github.com/cilium/cilium@v1.16.2/pkg/k8s/utils/workload.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  // Copyright Istio Authors
     5  // Copyright Authors of Hubble
     6  
     7  // GetWorkloadMetaFromPod and cronJobNameRegexp are copied from
     8  // https://github.com/istio/istio/blob/1aca7a67afd7b3e1d24fafb2fbfbeaf1e41534c0/pkg/kube/util.go
     9  //
    10  // Modifications:
    11  // GetDeployMetaFromPod has been renamed to GetWorkloadMetaFromPod and has
    12  // been updated to use the cilium slim API types.
    13  // We do not store the APIVersion of the owning workload in the TypeMeta
    14  // either, because it isn't needed for our purposes, and our slim types do not
    15  // have this field.
    16  // We fallback to the pod's ownerReference if we cannot find a more suitable
    17  // workload based on heuristics, whereas the original code defaulted to the
    18  // pod's name. This may be the case when using ReplicaSets without a Deployment.
    19  
    20  package utils
    21  
    22  import (
    23  	"regexp"
    24  	"strings"
    25  
    26  	slim_corev1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/api/core/v1"
    27  	slim_metav1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/apis/meta/v1"
    28  )
    29  
    30  var cronJobNameRegexp = regexp.MustCompile(`(.+)-\d{8,10}$`)
    31  
    32  // GetWorkloadMetaFromPod heuristically derives workload metadata from the pod spec.
    33  func GetWorkloadMetaFromPod(pod *slim_corev1.Pod) (slim_metav1.ObjectMeta, slim_metav1.TypeMeta, bool) {
    34  	if pod == nil {
    35  		return slim_metav1.ObjectMeta{}, slim_metav1.TypeMeta{}, false
    36  	}
    37  	// try to capture more useful namespace/name info for deployments, etc.
    38  	// TODO(dougreid): expand to enable lookup of OWNERs recursively a la kubernetesenv
    39  	workloadObjectMeta := pod.ObjectMeta
    40  	workloadObjectMeta.OwnerReferences = nil
    41  
    42  	var ok bool
    43  	var typeMetadata slim_metav1.TypeMeta
    44  	if len(pod.GenerateName) > 0 {
    45  		// if the pod name was generated (or is scheduled for generation), we can begin an investigation into the controlling reference for the pod.
    46  		var controllerRef slim_metav1.OwnerReference
    47  		controllerFound := false
    48  		for _, ref := range pod.OwnerReferences {
    49  			if ref.Controller != nil && *ref.Controller {
    50  				controllerRef = ref
    51  				controllerFound = true
    52  				break
    53  			}
    54  		}
    55  		if controllerFound {
    56  			ok = true
    57  			// default to the owner kind/name
    58  			typeMetadata.Kind = controllerRef.Kind
    59  			workloadObjectMeta.Name = controllerRef.Name
    60  
    61  			// heuristic for deployment detection
    62  			if typeMetadata.Kind == "ReplicaSet" && pod.Labels["pod-template-hash"] != "" && strings.HasSuffix(controllerRef.Name, pod.Labels["pod-template-hash"]) {
    63  				name := strings.TrimSuffix(controllerRef.Name, "-"+pod.Labels["pod-template-hash"])
    64  				workloadObjectMeta.Name = name
    65  				typeMetadata.Kind = "Deployment"
    66  			} else if typeMetadata.Kind == "ReplicaSet" && pod.Labels["pod-template-hash"] == "" {
    67  				workloadObjectMeta.Name = controllerRef.Name
    68  				typeMetadata.Kind = "ReplicaSet"
    69  			} else if typeMetadata.Kind == "ReplicationController" && pod.Labels["deploymentconfig"] != "" {
    70  				// If the pod is controlled by the replication controller, which is created by the DeploymentConfig resource in
    71  				// Openshift platform, set the deploy name to the deployment config's name, and the kind to 'DeploymentConfig'.
    72  				//
    73  				// nolint: lll
    74  				// For DeploymentConfig details, refer to
    75  				// https://docs.openshift.com/container-platform/4.1/applications/deployments/what-deployments-are.html#deployments-and-deploymentconfigs_what-deployments-are
    76  				//
    77  				// For the reference to the pod label 'deploymentconfig', refer to
    78  				// https://github.com/openshift/library-go/blob/7a65fdb398e28782ee1650959a5e0419121e97ae/pkg/apps/appsutil/const.go#L25
    79  				workloadObjectMeta.Name = pod.Labels["deploymentconfig"]
    80  				typeMetadata.Kind = "DeploymentConfig"
    81  				delete(workloadObjectMeta.Labels, "deploymentconfig")
    82  			} else if typeMetadata.Kind == "Job" {
    83  				// If job name suffixed with `-<digit-timestamp>`, where the length of digit timestamp is 8~10,
    84  				// trim the suffix and set kind to cron job.
    85  				if jn := cronJobNameRegexp.FindStringSubmatch(controllerRef.Name); len(jn) == 2 {
    86  					workloadObjectMeta.Name = jn[1]
    87  					typeMetadata.Kind = "CronJob"
    88  				}
    89  			}
    90  		}
    91  	}
    92  
    93  	return workloadObjectMeta, typeMetadata, ok
    94  }