Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support exclude and include kinds and namespaces for bom #325

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading