Skip to content

Commit

Permalink
feat: check if cdk component is tainted (#1412)
Browse files Browse the repository at this point in the history
* feat(GROW-2367): check if cdk component is tainted
  • Loading branch information
PengyuanZhao authored Oct 16, 2023
1 parent 50ef881 commit 1cea71b
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 72 deletions.
37 changes: 26 additions & 11 deletions lwcomponent/api_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,34 @@ type ApiInfo interface {
Id() int32

LatestVersion() *semver.Version

AllVersions() []*semver.Version
}

type apiInfo struct {
id int32
name string
version semver.Version
desc string
sizeKB int64
id int32
name string
version semver.Version
allVersions []*semver.Version
desc string
sizeKB int64
}

func NewAPIInfo(id int32, name string, version *semver.Version, desc string, size int64) ApiInfo {
func NewAPIInfo(
id int32,
name string,
version *semver.Version,
allVersions []*semver.Version,
desc string,
size int64,
) ApiInfo {
return &apiInfo{
id: id,
name: name,
version: *version,
desc: desc,
sizeKB: size,
id: id,
name: name,
version: *version,
allVersions: allVersions,
desc: desc,
sizeKB: size,
}
}

Expand All @@ -35,3 +46,7 @@ func (a *apiInfo) Id() int32 {
func (a *apiInfo) LatestVersion() *semver.Version {
return &a.version
}

func (a *apiInfo) AllVersions() []*semver.Version {
return a.allVersions
}
6 changes: 4 additions & 2 deletions lwcomponent/api_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import (

func TestApiInfoId(t *testing.T) {
version, err := semver.NewVersion("1.1.1")
allVersions := []*semver.Version{version}
if err != nil {
panic(err)
}

var id int32 = 23

info := lwcomponent.NewAPIInfo(id, "test", version, "", 0)
info := lwcomponent.NewAPIInfo(id, "test", version, allVersions, "", 0)

result := info.Id()
assert.Equal(t, id, result)
Expand All @@ -26,11 +27,12 @@ func TestApiInfoLatestVersion(t *testing.T) {
var expectedVer string = "1.2.3"

version, err := semver.NewVersion(expectedVer)
allVersions := []*semver.Version{version}
if err != nil {
panic(err)
}

info := lwcomponent.NewAPIInfo(1, "test", version, "", 0)
info := lwcomponent.NewAPIInfo(1, "test", version, allVersions, "", 0)

result := info.LatestVersion()
assert.Equal(t, expectedVer, result.String())
Expand Down
47 changes: 28 additions & 19 deletions lwcomponent/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,24 +77,7 @@ func (c *Catalog) ListComponentVersions(component *CDKComponent) (versions []*se
return
}

response, err := c.client.V2.Components.ListComponentVersions(component.apiInfo.Id(), operatingSystem, architecture)
if err != nil {
return nil, err
}

rawVersions := response.Data[0].Versions

versions = make([]*semver.Version, len(rawVersions))
for idx, v := range rawVersions {
ver, err := semver.NewVersion(v)
if err != nil {
return nil, err
}

versions[idx] = ver
}

return versions, nil
return listComponentVersions(c.client, component.apiInfo.Id())
}

func (c *Catalog) PrintComponents() [][]string {
Expand Down Expand Up @@ -265,7 +248,12 @@ func NewCatalog(client *api.Client, stageConstructor StageConstructor) (*Catalog
return nil, errors.Wrap(err, fmt.Sprintf("component '%s' version '%s'", c.Name, c.Version))
}

api := NewAPIInfo(c.Id, c.Name, ver, c.Description, c.Size)
allVersions, err := listComponentVersions(client, c.Id)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("unable to fetch component '%s' versions", c.Name))
}

api := NewAPIInfo(c.Id, c.Name, ver, allVersions, c.Description, c.Size)

host, found := localComponents[c.Name]
if found {
Expand Down Expand Up @@ -309,6 +297,27 @@ func loadLocalComponents() (local map[string]HostInfo, err error) {
return
}

func listComponentVersions(client *api.Client, componentId int32) (versions []*semver.Version, err error) {
response, err := client.V2.Components.ListComponentVersions(componentId, operatingSystem, architecture)
if err != nil {
return nil, err
}

rawVersions := response.Data[0].Versions

versions = make([]*semver.Version, len(rawVersions))
for idx, v := range rawVersions {
ver, err := semver.NewVersion(v)
if err != nil {
return nil, err
}

versions[idx] = ver
}

return versions, nil
}

// func isDevelopmentComponent(path string, name string) bool {
// return file.FileExists(filepath.Join(path, name, DevelopmentFile))
// }
Expand Down
147 changes: 116 additions & 31 deletions lwcomponent/catalog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ func TestCatalogNewCatalog(t *testing.T) {
fmt.Fprint(w, generateComponentsResponse(prefix, apiComponentCount))
})

for i := 0; i < apiComponentCount; i++ {
name := fmt.Sprintf("%s-%d", prefix, i)
path := fmt.Sprintf("Components/%d", i)
versions := []string{"1.0.0", "1.1.1", "3.0.1", "5.4.3"}

fakeServer.MockAPI(path, func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Components API only accepts HTTP GET")
fmt.Fprint(w, generateComponentVersionsResponse(name, versions))
})
}

client, _ := api.NewClient("catalog_test",
api.WithToken("TOKEN"),
api.WithURL(fakeServer.URL()),
Expand All @@ -55,6 +66,17 @@ func TestCatalogNewCatalog(t *testing.T) {
fmt.Fprint(w, generateComponentsResponse(prefix, apiComponentCount))
})

for i := 0; i < apiComponentCount; i++ {
name := fmt.Sprintf("%s-%d", prefix, i)
path := fmt.Sprintf("Components/%d", i)
versions := []string{"1.0.0", "1.1.1", "3.0.1", "5.4.3"}

fakeServer.MockAPI(path, func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Components API only accepts HTTP GET")
fmt.Fprint(w, generateComponentVersionsResponse(name, versions))
})
}

client, _ := api.NewClient("catalog_test",
api.WithToken("TOKEN"),
api.WithURL(fakeServer.URL()),
Expand Down Expand Up @@ -109,13 +131,19 @@ func TestCatalogNewCatalog(t *testing.T) {
fmt.Fprint(w, generateComponentsResponse(prefix, 1))
})

name := fmt.Sprintf("%s-%d", prefix, 1)
versions := []string{"1.0.0", "1.1.1", "3.0.1", "5.4.3"}

fakeServer.MockAPI("Components/0", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Components API only accepts HTTP GET")
fmt.Fprint(w, generateComponentVersionsResponse(name, versions))
})

client, _ := api.NewClient("catalog_test",
api.WithToken("TOKEN"),
api.WithURL(fakeServer.URL()),
)

name := fmt.Sprintf("%s-%d", prefix, 1)

CreateLocalComponent(name, "invalid-version", false)

catalog, err := lwcomponent.NewCatalog(client, newTestStage)
Expand Down Expand Up @@ -148,6 +176,17 @@ func TestCatalogComponentCount(t *testing.T) {
fmt.Fprint(w, generateComponentsResponse(prefix, apiCount))
})

for i := 0; i < apiCount; i++ {
name := fmt.Sprintf("%s-%d", prefix, i)
path := fmt.Sprintf("Components/%d", i)
versions := []string{"1.0.0", "1.1.1", "3.0.1", "5.4.3"}

fakeServer.MockAPI(path, func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Components API only accepts HTTP GET")
fmt.Fprint(w, generateComponentVersionsResponse(name, versions))
})
}

client, _ := api.NewClient("catalog_test",
api.WithToken("TOKEN"),
api.WithURL(fakeServer.URL()),
Expand Down Expand Up @@ -238,6 +277,17 @@ func TestCatalogGetComponent(t *testing.T) {
fmt.Fprint(w, generateComponentsResponse(prefix, count))
})

for i := 0; i < count; i++ {
name := fmt.Sprintf("%s-%d", prefix, i)
path := fmt.Sprintf("Components/%d", i)
versions := []string{"1.0.0", "1.1.1", "3.0.1", "5.4.3"}

fakeServer.MockAPI(path, func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Components API only accepts HTTP GET")
fmt.Fprint(w, generateComponentVersionsResponse(name, versions))
})
}

client, _ := api.NewClient("catalog_test",
api.WithToken("TOKEN"),
api.WithURL(fakeServer.URL()),
Expand Down Expand Up @@ -323,36 +373,33 @@ func TestCatalogGetComponent(t *testing.T) {
}

func TestCatalogListComponentVersions(t *testing.T) {
var (
prefix = "testCatalogListComponentVersions"
count = 4
)
prefix := "testCatalogListComponentVersions"

_, home := FakeHome()
defer ResetHome(home)

fakeServer := lacework.MockServer()
defer fakeServer.Close()

fakeServer.MockAPI("Components", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Components API only accepts HTTP GET")
fmt.Fprint(w, generateComponentsResponse(prefix, count))
})
t.Run("ok", func(t *testing.T) {
fakeServer := lacework.MockServer()
defer fakeServer.Close()

client, _ := api.NewClient("catalog_test",
api.WithToken("TOKEN"),
api.WithURL(fakeServer.URL()),
)
fakeServer.MockAPI("Components", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Components API only accepts HTTP GET")
fmt.Fprint(w, generateComponentsResponse(prefix, 1))
})

t.Run("ok", func(t *testing.T) {
name := fmt.Sprintf("%s-%d", prefix, 1)
name := fmt.Sprintf("%s-%d", prefix, 0)
versions := []string{"0.1.0", "1.1.1", "3.0.1", "5.4.3"}

fakeServer.MockAPI("Components/1", func(w http.ResponseWriter, r *http.Request) {
fakeServer.MockAPI("Components/0", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Components API only accepts HTTP GET")
fmt.Fprint(w, generateComponentVersionsResponse(name, versions))
})

client, _ := api.NewClient("catalog_test",
api.WithToken("TOKEN"),
api.WithURL(fakeServer.URL()),
)

catalog, err := lwcomponent.NewCatalog(client, newTestStage)
assert.NotNil(t, catalog)
assert.Nil(t, err)
Expand All @@ -370,24 +417,29 @@ func TestCatalogListComponentVersions(t *testing.T) {
})

t.Run("invalid semantic version", func(t *testing.T) {
name := fmt.Sprintf("%s-%d", prefix, 2)
fakeServer := lacework.MockServer()
defer fakeServer.Close()

fakeServer.MockAPI("Components", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Components API only accepts HTTP GET")
fmt.Fprint(w, generateComponentsResponse(prefix, 1))
})

name := fmt.Sprintf("%s-%d", prefix, 0)
versions := []string{"0.1.0", "1.invalid.1", "3.0.1", "5.4.3"}

fakeServer.MockAPI("Components/2", func(w http.ResponseWriter, r *http.Request) {
fakeServer.MockAPI("Components/0", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Components API only accepts HTTP GET")
fmt.Fprint(w, generateComponentVersionsResponse(name, versions))
})

catalog, err := lwcomponent.NewCatalog(client, newTestStage)
assert.NotNil(t, catalog)
assert.Nil(t, err)

component, err := catalog.GetComponent(name)
assert.NotNil(t, component)
assert.Nil(t, err)
client, _ := api.NewClient("catalog_test",
api.WithToken("TOKEN"),
api.WithURL(fakeServer.URL()),
)

vers, err := catalog.ListComponentVersions(component)
assert.Nil(t, vers)
catalog, err := lwcomponent.NewCatalog(client, newTestStage)
assert.Nil(t, catalog)
assert.NotNil(t, err)
})
}
Expand Down Expand Up @@ -421,6 +473,17 @@ func TestCatalogStage(t *testing.T) {
}
})

for i := 0; i < apiComponentCount; i++ {
name := fmt.Sprintf("%s-%d", prefix, i)
path := fmt.Sprintf("Components/%d", i)
versions := []string{"1.0.0", "1.1.1", "3.0.1", "5.4.3"}

fakeServer.MockAPI(path, func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Components API only accepts HTTP GET")
fmt.Fprint(w, generateComponentVersionsResponse(name, versions))
})
}

client, _ := api.NewClient("catalog_test",
api.WithToken("TOKEN"),
api.WithURL(fakeServer.URL()),
Expand Down Expand Up @@ -569,6 +632,17 @@ func TestCatalogInstall(t *testing.T) {
fmt.Fprint(w, generateComponentsResponse(prefix, apiComponentCount))
})

for i := 0; i < apiComponentCount; i++ {
name := fmt.Sprintf("%s-%d", prefix, i)
path := fmt.Sprintf("Components/%d", i)
versions := []string{"1.0.0", "1.1.1", "3.0.1", "5.4.3"}

fakeServer.MockAPI(path, func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Components API only accepts HTTP GET")
fmt.Fprint(w, generateComponentVersionsResponse(name, versions))
})
}

client, _ := api.NewClient("catalog_test",
api.WithToken("TOKEN"),
api.WithURL(fakeServer.URL()))
Expand Down Expand Up @@ -628,6 +702,17 @@ func TestCatalogDelete(t *testing.T) {
fmt.Fprint(w, generateComponentsResponse(prefix, apiComponentCount))
})

for i := 0; i < apiComponentCount; i++ {
name := fmt.Sprintf("%s-%d", prefix, i)
path := fmt.Sprintf("Components/%d", i)
versions := []string{"1.0.0", "1.1.1", "3.0.1", "5.4.3"}

fakeServer.MockAPI(path, func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Components API only accepts HTTP GET")
fmt.Fprint(w, generateComponentVersionsResponse(name, versions))
})
}

client, _ := api.NewClient("catalog_test",
api.WithToken("TOKEN"),
api.WithURL(fakeServer.URL()))
Expand Down
Loading

0 comments on commit 1cea71b

Please sign in to comment.