-
Notifications
You must be signed in to change notification settings - Fork 17
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
fix: add using include/exclude kinds and namespaces #395
base: main
Are you sure you want to change the base?
Changes from all commits
ea611f5
638827c
3cee92f
f318548
065e723
eed731d
75fd906
812bbfc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -161,8 +161,90 @@ func (c client) GetIncludeKinds() []string { | |
return c.includeKinds | ||
} | ||
|
||
// initResourceList collects scannable resources. | ||
func (c *client) initResourceList() { | ||
// skip if resources are already created | ||
if len(c.resources) > 0 { | ||
return | ||
} | ||
|
||
// collect only included kinds | ||
if len(c.includeKinds) != 0 { | ||
// a customer can input resources in different cases: Pods, deployments etc. | ||
// `includeKinds` are already low cased, so we can just assign the values | ||
c.resources = c.includeKinds | ||
return | ||
} | ||
// if there are no included and excluded kinds - don't collect resources | ||
if len(c.excludeKinds) == 0 { | ||
return | ||
} | ||
// skip excluded resources | ||
for _, kind := range k8s.GetAllResources() { | ||
if slices.Contains(c.excludeKinds, kind) { | ||
continue | ||
} | ||
c.resources = append(c.resources, kind) | ||
} | ||
} | ||
|
||
// getNamespaces collects scannable namespaces | ||
func (c *client) getNamespaces() ([]string, error) { | ||
if len(c.includeNamespaces) > 0 { | ||
return c.includeNamespaces, nil | ||
} | ||
|
||
result := []string{} | ||
if len(c.excludeNamespaces) == 0 { | ||
return result, nil | ||
} | ||
namespaceGVR := schema.GroupVersionResource{ | ||
Group: "", | ||
Version: "v1", | ||
Resource: "namespaces", | ||
} | ||
dClient := c.getDynamicClient(namespaceGVR) | ||
namespaces, err := dClient.List(context.TODO(), v1.ListOptions{}) | ||
if err != nil { | ||
if errors.IsForbidden(err) { | ||
return result, fmt.Errorf("'exclude namespaces' option requires a cluster role with permissions to list namespaces") | ||
} | ||
Comment on lines
+209
to
+211
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can occur if a user passes in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
no, it can occur only if |
||
return result, fmt.Errorf("unable to list namespaces: %w", err) | ||
} | ||
for _, ns := range namespaces.Items { | ||
if slices.Contains(c.excludeNamespaces, ns.GetName()) { | ||
continue | ||
} | ||
result = append(result, ns.GetName()) | ||
} | ||
return result, nil | ||
} | ||
|
||
// ListArtifacts returns kubernetes scannable artifacs. | ||
func (c *client) ListArtifacts(ctx context.Context) ([]*artifacts.Artifact, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add some tests for this too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought about it.
|
||
c.initResourceList() | ||
namespaces, err := c.getNamespaces() | ||
if err != nil { | ||
return nil, err | ||
} | ||
if len(namespaces) == 0 { | ||
return c.ListSpecificArtifacts(ctx) | ||
} | ||
artifactList := make([]*artifacts.Artifact, 0) | ||
|
||
for _, namespace := range namespaces { | ||
c.namespace = namespace | ||
arts, err := c.ListSpecificArtifacts(ctx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
artifactList = append(artifactList, arts...) | ||
} | ||
return artifactList, nil | ||
} | ||
|
||
// ListSpecificArtifacts returns kubernetes scannable artifacs for a specific namespace or a cluster | ||
func (c *client) ListSpecificArtifacts(ctx context.Context) ([]*artifacts.Artifact, error) { | ||
artifactList := make([]*artifacts.Artifact, 0) | ||
|
||
namespaced := isNamespaced(c.namespace, c.allNamespaces) | ||
|
@@ -195,15 +277,6 @@ func (c *client) ListArtifacts(ctx context.Context) ([]*artifacts.Artifact, erro | |
if c.excludeOwned && c.hasOwner(resource) { | ||
continue | ||
} | ||
// filter resources by kind | ||
if FilterResources(c.includeKinds, c.excludeKinds, resource.GetKind()) { | ||
continue | ||
} | ||
|
||
// filter resources by namespace | ||
if FilterResources(c.includeNamespaces, c.excludeNamespaces, resource.GetNamespace()) { | ||
continue | ||
} | ||
|
||
lastAppliedResource := resource | ||
if jsonManifest, ok := resource.GetAnnotations()["kubectl.kubernetes.io/last-applied-configuration"]; ok { // required for outdated-api when k8s convert resources | ||
|
@@ -470,7 +543,7 @@ func rawResource(resource interface{}) (map[string]interface{}, error) { | |
func (c *client) getDynamicClient(gvr schema.GroupVersionResource) dynamic.ResourceInterface { | ||
dclient := c.cluster.GetDynamicClient() | ||
|
||
// don't use namespace if it is a cluster levle resource, | ||
// don't use namespace if it is a cluster level resource, | ||
// or namespace is empty | ||
if k8s.IsClusterResource(gvr) || len(c.namespace) == 0 { | ||
return dclient.Resource(gvr) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function seems untested, can we add some tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done 75fd906