github.com/grafana/tanka@v0.26.1-0.20240506093700-c22cfc35c21a/pkg/process/namespace.go (about)

     1  package process
     2  
     3  import (
     4  	"github.com/grafana/tanka/pkg/kubernetes/manifest"
     5  )
     6  
     7  const (
     8  	// AnnotationNamespaced can be set on any resource to override the decision
     9  	// whether 'metadata.namespace' is set by Tanka
    10  	AnnotationNamespaced = MetadataPrefix + "/namespaced"
    11  )
    12  
    13  // This is a list of "cluster-wide" resources harvested from `kubectl api-resources --namespaced=false`
    14  // This helps us to know which objects we should NOT apply namespaces to automatically.
    15  // We can add to this list periodically if new types are added.
    16  // This only applies to built-in kubernetes types. CRDs will need to be handled with annotations.
    17  var clusterWideKinds = map[string]bool{
    18  	"APIService":                     true,
    19  	"CertificateSigningRequest":      true,
    20  	"ClusterRole":                    true,
    21  	"ClusterRoleBinding":             true,
    22  	"ComponentStatus":                true,
    23  	"CSIDriver":                      true,
    24  	"CSINode":                        true,
    25  	"CustomResourceDefinition":       true,
    26  	"MutatingWebhookConfiguration":   true,
    27  	"Namespace":                      true,
    28  	"Node":                           true,
    29  	"NodeMetrics":                    true,
    30  	"PersistentVolume":               true,
    31  	"PodSecurityPolicy":              true,
    32  	"PriorityClass":                  true,
    33  	"RuntimeClass":                   true,
    34  	"SelfSubjectAccessReview":        true,
    35  	"SelfSubjectRulesReview":         true,
    36  	"StorageClass":                   true,
    37  	"SubjectAccessReview":            true,
    38  	"TokenReview":                    true,
    39  	"ValidatingWebhookConfiguration": true,
    40  	"VolumeAttachment":               true,
    41  }
    42  
    43  // Namespace injects the default namespace of the environment into each
    44  // resources, that does not already define one. AnnotationNamespaced can be used
    45  // to disable this per resource
    46  func Namespace(list manifest.List, def string) manifest.List {
    47  	if def == "" {
    48  		return list
    49  	}
    50  
    51  	for i, m := range list {
    52  		namespaced := true
    53  		if clusterWideKinds[m.Kind()] {
    54  			namespaced = false
    55  		}
    56  		// check for annotation override
    57  		if s, ok := m.Metadata().Annotations()[AnnotationNamespaced]; ok {
    58  			namespaced = s == "true"
    59  		}
    60  
    61  		if namespaced && !m.Metadata().HasNamespace() {
    62  			m.Metadata()["namespace"] = def
    63  		}
    64  
    65  		// remove annotations if empty (we always create those by accessing them)
    66  		if len(m.Metadata().Annotations()) == 0 {
    67  			delete(m.Metadata(), "annotations")
    68  		}
    69  
    70  		list[i] = m
    71  	}
    72  
    73  	return list
    74  }