Skip to content

Commit 9021422

Browse files
authored
Merge pull request #392 from werf/feat/kubedog/add-ability-to-scan-namespaces
feat: support multiple in-cluster scan namespaces via virtual contexts
2 parents ed58edf + 5507f79 commit 9021422

1 file changed

Lines changed: 39 additions & 1 deletion

File tree

pkg/kube/kube.go

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ type GetAllContextsClientsOptions struct {
138138
APIServerURL string
139139
Insecure bool
140140
CADataBase64 string
141+
142+
// ScanNamespaces is used in in-cluster mode only.
143+
// When set, creates one virtual context per namespace so that
144+
// scan-context-namespace-only scans all listed namespaces instead of
145+
// just the pod's own namespace.
146+
ScanNamespaces []string
141147
}
142148

143149
type ContextClient struct {
@@ -160,6 +166,9 @@ func GetAllContextsClients(opts GetAllContextsClientsOptions) ([]*ContextClient,
160166
}
161167

162168
if hasInClusterConfig() {
169+
if len(opts.ScanNamespaces) > 0 {
170+
return getInClusterContextClientsForNamespaces(opts.ScanNamespaces)
171+
}
163172
contextClient, err := getInClusterContextClient()
164173
if err != nil {
165174
return nil, err
@@ -398,7 +407,10 @@ func getInClusterConfig() (*KubeConfig, error) {
398407
if data, err := os.ReadFile(kubeNamespaceFilePath); err != nil {
399408
return nil, fmt.Errorf("in-cluster configuration problem: cannot determine default kubernetes namespace: error reading %s: %w", kubeNamespaceFilePath, err)
400409
} else {
401-
res.DefaultNamespace = string(data)
410+
res.DefaultNamespace = strings.TrimSpace(string(data))
411+
if res.DefaultNamespace == "" {
412+
return nil, fmt.Errorf("in-cluster configuration problem: cannot determine default kubernetes namespace: empty namespace in %s", kubeNamespaceFilePath)
413+
}
402414
}
403415

404416
return res, nil
@@ -422,6 +434,32 @@ func getInClusterContextClient() (*ContextClient, error) {
422434
}, nil
423435
}
424436

437+
// getInClusterContextClientsForNamespaces creates one virtual ContextClient per
438+
// namespace using the same in-cluster ServiceAccount credentials.
439+
// This allows scan-context-namespace-only to cover multiple namespaces without
440+
// requiring a kubeconfig or cluster-wide permissions.
441+
func getInClusterContextClientsForNamespaces(namespaces []string) ([]*ContextClient, error) {
442+
kubeConfig, err := getInClusterConfig()
443+
if err != nil {
444+
return nil, err
445+
}
446+
447+
clientset, err := kubernetes.NewForConfig(kubeConfig.Config)
448+
if err != nil {
449+
return nil, err
450+
}
451+
452+
var clients []*ContextClient
453+
for _, ns := range namespaces {
454+
clients = append(clients, &ContextClient{
455+
ContextName: fmt.Sprintf("inClusterContext/%s", ns),
456+
ContextNamespace: ns,
457+
Client: clientset,
458+
})
459+
}
460+
return clients, nil
461+
}
462+
425463
func GroupVersionResourceByKind(client kubernetes.Interface, kind string) (schema.GroupVersionResource, error) {
426464
lists, err := client.Discovery().ServerPreferredResources()
427465
if err != nil {

0 commit comments

Comments
 (0)