Skip to content

Commit

Permalink
feat: support exclude and include kinds and namespaces for bom (#325)
Browse files Browse the repository at this point in the history
Signed-off-by: chenk <hen.keinan@gmail.com>
  • Loading branch information
chen-keinan authored Apr 8, 2024
1 parent 7206c5c commit 81b7dc3
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 39 deletions.
9 changes: 0 additions & 9 deletions examples/trivy.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,6 @@ func main() {
}
printArtifacts(artifacts)

fmt.Println("Scanning namespace 'default', resource 'deployment/orion'")

//trivy k8s --namespace default deployment/orion
artifact, err := trivyk8s.Namespace("default").GetArtifact(ctx, "deploy", "orion")
if err != nil {
log.Fatal(err)
}
printArtifact(artifact)

fmt.Println("Scanning 'deployments'")

//trivy k8s deployment
Expand Down
65 changes: 36 additions & 29 deletions pkg/trivyk8s/trivyk8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ type TrivyK8S interface {
type ArtifactsK8S interface {
// ListArtifacts returns kubernetes scanable artifacts
ListArtifacts(context.Context) ([]*artifacts.Artifact, error)
// GetArtifact return kubernete scanable artifact
GetArtifact(context.Context, string, string) (*artifacts.Artifact, error)
// ListArtifactAndNodeInfo return kubernete scanable artifact and node info
ListArtifactAndNodeInfo(context.Context, ...NodeCollectorOption) ([]*artifacts.Artifact, error)
// ListClusterBomInfo returns kubernetes Bom (node,core components) information.
Expand Down Expand Up @@ -137,6 +135,26 @@ func isNamespaced(namespace string, allNamespace bool) bool {
return false
}

// return list of namespaces to exclude
func (c *client) GetExcludeNamespaces() []string {
return c.excludeNamespaces
}

// return list of namespaces to include
func (c *client) GetIncludeNamespaces() []string {
return c.includeNamespaces
}

// return list of kinds to exclude
func (c *client) GetExcludeKinds() []string {
return c.excludeKinds
}

// return list of kinds to include
func (c client) GetIncludeKinds() []string {
return c.includeKinds
}

// ListArtifacts returns kubernetes scannable artifacs.
func (c *client) ListArtifacts(ctx context.Context) ([]*artifacts.Artifact, error) {
artifactList := make([]*artifacts.Artifact, 0)
Expand Down Expand Up @@ -173,12 +191,12 @@ func (c *client) ListArtifacts(ctx context.Context) ([]*artifacts.Artifact, erro
continue
}
// filter resources by kind
if filterResources(c.includeKinds, c.excludeKinds, resource.GetKind()) {
if FilterResources(c.includeKinds, c.excludeKinds, resource.GetKind()) {
continue
}

// filter resources by namespace
if filterResources(c.includeNamespaces, c.excludeNamespaces, resource.GetNamespace()) {
if FilterResources(c.includeNamespaces, c.excludeNamespaces, resource.GetNamespace()) {
continue
}

Expand Down Expand Up @@ -211,7 +229,7 @@ func (c *client) ListArtifacts(ctx context.Context) ([]*artifacts.Artifact, erro
return artifactList, nil
}

func filterResources(include []string, exclude []string, key string) bool {
func FilterResources(include []string, exclude []string, key string) bool {

if (len(include) > 0 && len(exclude) > 0) || // if both include and exclude cannot be set together
(len(include) == 0 && len(exclude) == 0) {
Expand Down Expand Up @@ -341,8 +359,21 @@ func (c *client) ListClusterBomInfo(ctx context.Context) ([]*artifacts.Artifact,
if err != nil {
return []*artifacts.Artifact{}, err
}
b.Components = c.filterNamespaces(b.Components)
if slices.Contains(c.GetExcludeKinds(), "node") {
b.NodesInfo = []bom.NodeInfo{}
}
return BomToArtifacts(b)
}

func (c *client) filterNamespaces(comp []bom.Component) []bom.Component {
bm := make([]bom.Component, 0)
for _, co := range comp {
if FilterResources(c.GetIncludeNamespaces(), c.GetExcludeNamespaces(), co.Namespace) {
bm = append(bm, co)
}
}
return bm
}

func BomToArtifacts(b *bom.Result) ([]*artifacts.Artifact, error) {
Expand Down Expand Up @@ -382,30 +413,6 @@ func rawResource(resource interface{}) (map[string]interface{}, error) {
return rawResource, nil
}

// GetArtifact return kubernetes scannable artifac.
func (c *client) GetArtifact(ctx context.Context, kind, name string) (*artifacts.Artifact, error) {
gvr, err := c.cluster.GetGVR(kind)
if err != nil {
return nil, err
}

dclient := c.getDynamicClient(gvr)
resource, err := dclient.Get(ctx, name, v1.GetOptions{})
if err != nil {
return nil, fmt.Errorf("failed getting resource for gvr: %v - %w", gvr, err)
}
auths, err := c.cluster.AuthByResource(*resource)
if err != nil {
return nil, fmt.Errorf("failed getting auth for gvr: %v - %w", gvr, err)
}
artifact, err := artifacts.FromResource(*resource, auths)
if err != nil {
return nil, err
}

return artifact, nil
}

func (c *client) getDynamicClient(gvr schema.GroupVersionResource) dynamic.ResourceInterface {
dclient := c.cluster.GetDynamicClient()

Expand Down
2 changes: 1 addition & 1 deletion pkg/trivyk8s/trivyk8s_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func TestFilterResource(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := filterResources(tt.includeKinds, tt.excludeKinds, tt.resourceKind)
got := FilterResources(tt.includeKinds, tt.excludeKinds, tt.resourceKind)
assert.Equal(t, got, tt.want)
})
}
Expand Down

0 comments on commit 81b7dc3

Please sign in to comment.