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

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package k8s
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/rs/zerolog/log"
    11  	"go.mondoo.com/cnquery/motor/asset"
    12  	"go.mondoo.com/cnquery/motor/platform"
    13  	"go.mondoo.com/cnquery/motor/providers"
    14  	"go.mondoo.com/cnquery/motor/providers/k8s"
    15  	"google.golang.org/protobuf/proto"
    16  	"k8s.io/apimachinery/pkg/api/meta"
    17  	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    18  	"k8s.io/apimachinery/pkg/runtime"
    19  )
    20  
    21  func createPlatformData(objectKind, runtime string) (*platform.Platform, error) {
    22  	platformData := &platform.Platform{
    23  		Family:  []string{"k8s"},
    24  		Kind:    providers.Kind_KIND_K8S_OBJECT,
    25  		Runtime: runtime,
    26  	}
    27  	// We need this at two places (discovery and tranport)
    28  	// Here it is needed for the discovery and this is what ends up in  the database
    29  	switch objectKind {
    30  	case "Node":
    31  		platformData.Name = "k8s-node"
    32  		platformData.Title = "Kubernetes Node"
    33  	case "Pod":
    34  		platformData.Family = append(platformData.Family, "k8s-workload")
    35  		platformData.Name = "k8s-pod"
    36  		platformData.Title = "Kubernetes Pod"
    37  	case "CronJob":
    38  		platformData.Family = append(platformData.Family, "k8s-workload")
    39  		platformData.Name = "k8s-cronjob"
    40  		platformData.Title = "Kubernetes CronJob"
    41  	case "StatefulSet":
    42  		platformData.Family = append(platformData.Family, "k8s-workload")
    43  		platformData.Name = "k8s-statefulset"
    44  		platformData.Title = "Kubernetes StatefulSet"
    45  	case "Deployment":
    46  		platformData.Family = append(platformData.Family, "k8s-workload")
    47  		platformData.Name = "k8s-deployment"
    48  		platformData.Title = "Kubernetes Deployment"
    49  	case "Job":
    50  		platformData.Family = append(platformData.Family, "k8s-workload")
    51  		platformData.Name = "k8s-job"
    52  		platformData.Title = "Kubernetes Job"
    53  	case "ReplicaSet":
    54  		platformData.Family = append(platformData.Family, "k8s-workload")
    55  		platformData.Name = "k8s-replicaset"
    56  		platformData.Title = "Kubernetes ReplicaSet"
    57  	case "DaemonSet":
    58  		platformData.Family = append(platformData.Family, "k8s-workload")
    59  		platformData.Name = "k8s-daemonset"
    60  		platformData.Title = "Kubernetes DaemonSet"
    61  	case "AdmissionReview":
    62  		platformData.Family = append(platformData.Family, "k8s-admission")
    63  		platformData.Name = "k8s-admission"
    64  		platformData.Title = "Kubernetes Admission Review"
    65  	case "Ingress":
    66  		platformData.Family = append(platformData.Family, "k8s-ingress")
    67  		platformData.Name = "k8s-ingress"
    68  		platformData.Title = "Kubernetes Ingress"
    69  	case "Namespace":
    70  		platformData.Family = append(platformData.Family, "k8s-namespace")
    71  		platformData.Name = "k8s-namespace"
    72  		platformData.Title = "Kubernetes Namespace"
    73  	default:
    74  		return nil, fmt.Errorf("could not determine object kind %s", objectKind)
    75  	}
    76  	return platformData, nil
    77  }
    78  
    79  func createAssetFromObject(object runtime.Object, runtime string, connection *providers.Config, clusterIdentifier string) (*asset.Asset, error) {
    80  	objMeta, err := meta.Accessor(object)
    81  	if err != nil {
    82  		log.Error().Err(err).Msg("could not access object attributes")
    83  		return nil, err
    84  	}
    85  	objType, err := meta.TypeAccessor(object)
    86  	if err != nil {
    87  		log.Error().Err(err).Msg("could not access object attributes")
    88  		return nil, err
    89  	}
    90  
    91  	objectKind := objType.GetKind()
    92  	platformData, err := createPlatformData(objectKind, runtime)
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  	platformData.Version = objType.GetAPIVersion()
    97  	platformData.Build = objMeta.GetResourceVersion()
    98  	platformData.Labels = map[string]string{
    99  		"uid": string(objMeta.GetUID()),
   100  	}
   101  
   102  	assetLabels := objMeta.GetLabels()
   103  	if assetLabels == nil {
   104  		assetLabels = map[string]string{}
   105  	}
   106  	ns := objMeta.GetNamespace()
   107  	var name string
   108  	if ns != "" {
   109  		name = ns + "/" + objMeta.GetName()
   110  		platformData.Labels["namespace"] = ns
   111  	} else {
   112  		name = objMeta.GetName()
   113  	}
   114  
   115  	addMondooAssetLabels(assetLabels, objMeta, objType, clusterIdentifier)
   116  
   117  	newConnection := proto.Clone(connection).(*providers.Config)
   118  	newConnection.Options = map[string]string{}
   119  	for k, v := range connection.Options {
   120  		newConnection.Options[k] = v
   121  	}
   122  	newConnection.Options["object-kind"] = strings.ToLower(objectKind)
   123  
   124  	asset := &asset.Asset{
   125  		PlatformIds: []string{k8s.NewPlatformWorkloadId(clusterIdentifier, strings.ToLower(objectKind), objMeta.GetNamespace(), objMeta.GetName(), string(objMeta.GetUID()))},
   126  		Name:        name,
   127  		Platform:    platformData,
   128  		Connections: []*providers.Config{newConnection},
   129  		State:       asset.State_STATE_ONLINE,
   130  		Labels:      assetLabels,
   131  	}
   132  
   133  	return asset, nil
   134  }
   135  
   136  func addMondooAssetLabels(assetLabels map[string]string, objMeta v1.Object, objType meta.Type, clusterIdentifier string) {
   137  	ns := objMeta.GetNamespace()
   138  	if ns != "" {
   139  		assetLabels["k8s.mondoo.com/namespace"] = ns
   140  	}
   141  	assetLabels["k8s.mondoo.com/name"] = objMeta.GetName()
   142  	if string(objMeta.GetUID()) != "" {
   143  		// objects discovered from manifest do not necessarily have a UID
   144  		assetLabels["k8s.mondoo.com/uid"] = string(objMeta.GetUID())
   145  	}
   146  	assetLabels["k8s.mondoo.com/kind"] = objType.GetKind()
   147  	assetLabels["k8s.mondoo.com/apiVersion"] = objType.GetAPIVersion()
   148  	if objMeta.GetResourceVersion() != "" {
   149  		// objects discovered from manifest do not necessarily have a resource version
   150  		assetLabels["k8s.mondoo.com/resource-version"] = objMeta.GetResourceVersion()
   151  	}
   152  	assetLabels["k8s.mondoo.com/cluster-id"] = clusterIdentifier
   153  
   154  	owners := objMeta.GetOwnerReferences()
   155  	if len(owners) > 0 {
   156  		owner := owners[0]
   157  		assetLabels["k8s.mondoo.com/owner-kind"] = owner.Kind
   158  		assetLabels["k8s.mondoo.com/owner-name"] = owner.Name
   159  		assetLabels["k8s.mondoo.com/owner-uid"] = string(owner.UID)
   160  	}
   161  }