go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/_motor/discovery/k8s/list_namespaces.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package k8s
     5  
     6  import (
     7  	"github.com/pkg/errors"
     8  	"github.com/rs/zerolog/log"
     9  	"go.mondoo.com/cnquery/motor/asset"
    10  	"go.mondoo.com/cnquery/motor/providers"
    11  	"go.mondoo.com/cnquery/motor/providers/k8s"
    12  	v1 "k8s.io/api/core/v1"
    13  	k8sErrors "k8s.io/apimachinery/pkg/api/errors"
    14  	"k8s.io/apimachinery/pkg/api/meta"
    15  )
    16  
    17  // ListNamespaces lists all namespaces in the cluster.
    18  func ListNamespaces(
    19  	p k8s.KubernetesProvider,
    20  	connection *providers.Config,
    21  	clusterIdentifier string,
    22  	nsFilter NamespaceFilterOpts,
    23  	resFilter map[string][]K8sResourceIdentifier,
    24  	od *k8s.PlatformIdOwnershipDirectory,
    25  ) ([]*asset.Asset, error) {
    26  	nss := []*v1.Namespace{}
    27  
    28  	if len(resFilter) > 0 {
    29  		if len(resFilter["namespace"]) == 0 {
    30  			return []*asset.Asset{}, nil
    31  		}
    32  
    33  		for _, res := range resFilter["namespace"] {
    34  			ns, err := p.Namespace(res.Name)
    35  			if err != nil {
    36  				return nil, err
    37  			}
    38  			nss = append(nss, ns)
    39  		}
    40  	} else {
    41  		namespaces, err := p.Namespaces()
    42  		if err != nil {
    43  			// If we don't have rights to list the cluster namespaces, attempt getting them 1 by 1
    44  			if k8sErrors.IsForbidden(err) && len(nsFilter.include) > 0 {
    45  				for _, ns := range nsFilter.include {
    46  					n, err := p.Namespace(ns)
    47  					if err != nil {
    48  						return nil, err
    49  					}
    50  					nss = append(nss, n)
    51  				}
    52  			} else {
    53  				return nil, errors.Wrap(err, "could not list kubernetes namespaces")
    54  			}
    55  		}
    56  
    57  		for i := range namespaces {
    58  			ns := namespaces[i]
    59  			skip, err := skipNamespace(ns, nsFilter)
    60  			if err != nil {
    61  				log.Error().Err(err).Str("namespace", ns.Name).Msg("error checking whether Namespace should be included or excluded")
    62  				return nil, err
    63  			}
    64  			if skip {
    65  				log.Debug().Str("namespace", ns.Name).Msg("ignoring namespace")
    66  				continue
    67  			}
    68  			nss = append(nss, &ns)
    69  		}
    70  	}
    71  
    72  	assets := []*asset.Asset{}
    73  	for i := range nss {
    74  		// The namespace can be a root asset, in this case the ownership directory will not be present
    75  		if od != nil {
    76  			od.Add(nss[i])
    77  		}
    78  
    79  		asset, err := createAssetFromObject(nss[i], p.Runtime(), connection, clusterIdentifier)
    80  		if err != nil {
    81  			return nil, errors.Wrap(err, "failed to create asset from namespace")
    82  		}
    83  
    84  		obj, _ := meta.Accessor(nss[i])
    85  		log.Debug().Str("name", obj.GetName()).Str("connection", asset.Connections[0].Host).Msg("resolved namespace")
    86  
    87  		assets = append(assets, asset)
    88  	}
    89  	return assets, nil
    90  }