forked from argoproj/argo-cd
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkube.go
More file actions
85 lines (81 loc) · 3.07 KB
/
kube.go
File metadata and controls
85 lines (81 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package kube
import (
"github.com/argoproj/gitops-engine/pkg/utils/kube"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"github.com/argoproj/argo-cd/common"
)
// SetAppInstanceLabel the recommended app.kubernetes.io/instance label against an unstructured object
// Uses the legacy labeling if environment variable is set
func SetAppInstanceLabel(target *unstructured.Unstructured, key, val string) error {
labels := target.GetLabels()
if labels == nil {
labels = make(map[string]string)
}
labels[key] = val
target.SetLabels(labels)
if key != common.LabelKeyLegacyApplicationName {
// we no longer label the pod template sub resources in v0.11
return nil
}
gvk := schema.FromAPIVersionAndKind(target.GetAPIVersion(), target.GetKind())
// special case for deployment and job types: make sure that derived replicaset, and pod has
// the application label
switch gvk.Group {
case "apps", "extensions":
switch gvk.Kind {
case kube.DeploymentKind, kube.ReplicaSetKind, kube.StatefulSetKind, kube.DaemonSetKind:
templateLabels, ok, err := unstructured.NestedMap(target.UnstructuredContent(), "spec", "template", "metadata", "labels")
if err != nil {
return err
}
if !ok || templateLabels == nil {
templateLabels = make(map[string]interface{})
}
templateLabels[key] = val
err = unstructured.SetNestedMap(target.UnstructuredContent(), templateLabels, "spec", "template", "metadata", "labels")
if err != nil {
return err
}
// The following is a workaround for issue #335. In API version extensions/v1beta1 or
// apps/v1beta1, if a spec omits spec.selector then k8s will default the
// spec.selector.matchLabels to match spec.template.metadata.labels. This means Argo CD
// labels can potentially make their way into spec.selector.matchLabels, which is a bad
// thing. The following logic prevents this behavior.
switch target.GetAPIVersion() {
case "apps/v1beta1", "extensions/v1beta1":
selector, _, err := unstructured.NestedMap(target.UnstructuredContent(), "spec", "selector")
if err != nil {
return err
}
if len(selector) == 0 {
// If we get here, user did not set spec.selector in their manifest. We do not want
// our Argo CD labels to get defaulted by kubernetes, so we explicitly set the labels
// for them (minus the Argo CD labels).
delete(templateLabels, key)
err = unstructured.SetNestedMap(target.UnstructuredContent(), templateLabels, "spec", "selector", "matchLabels")
if err != nil {
return err
}
}
}
}
case "batch":
switch gvk.Kind {
case kube.JobKind:
templateLabels, ok, err := unstructured.NestedMap(target.UnstructuredContent(), "spec", "template", "metadata", "labels")
if err != nil {
return err
}
if !ok || templateLabels == nil {
templateLabels = make(map[string]interface{})
}
templateLabels[key] = val
err = unstructured.SetNestedMap(target.UnstructuredContent(), templateLabels, "spec", "template", "metadata", "labels")
if err != nil {
return err
}
}
}
return nil
}