-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcreate.go
124 lines (104 loc) · 3.27 KB
/
create.go
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package pods
import (
"context"
"strings"
"github.com/buzzsurfr/exorcism"
"k8s.io/api/admission/v1beta1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
log "k8s.io/klog/v2"
)
func validateCreate() exorcism.AdmitFunc {
return func(r *v1beta1.AdmissionRequest) (*exorcism.Result, error) {
pod, err := parsePod(r.Object.Raw)
if err != nil {
return &exorcism.Result{Msg: err.Error()}, nil
}
for _, c := range pod.Spec.Containers {
if strings.HasSuffix(c.Image, ":latest") {
return &exorcism.Result{Msg: "You cannot use the tag 'latest' in a container."}, nil
}
}
return &exorcism.Result{Allowed: true}, nil
}
}
func mutateCreate() exorcism.AdmitFunc {
return func(r *v1beta1.AdmissionRequest) (*exorcism.Result, error) {
// Get the list of DaemonSets
// creates the in-cluster config
config, err := rest.InClusterConfig()
if err != nil {
panic(err.Error())
}
// creates the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
// Setup return values and get info from request
var operations []exorcism.PatchOperation
pod, err := parsePod(r.Object.Raw)
if err != nil {
return &exorcism.Result{Msg: err.Error()}, nil
}
var containers []v1.Container
containers = append(containers, pod.Spec.Containers...)
daemonsets, err := clientset.AppsV1().DaemonSets("").List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
log.Infof("%d DaemonSets found", len(daemonsets.Items))
for _, daemonset := range daemonsets.Items {
// log.Infof("DaemonSet %s/%s found", daemonset.Namespace, daemonset.Name)
// Ignore DaemonSets for known kubernetes components that do not interface as a sidecar
var ignoredLabelKeys []string = []string{"k8s-app"}
ignoreDaemonSet := false
for k := range daemonset.ObjectMeta.Labels {
if contains(ignoredLabelKeys, k) {
ignoreDaemonSet = true
}
}
if ignoreDaemonSet {
log.Infof("Ignored %s/%s because it's part of the standard kubernetes deployment.", daemonset.Namespace, daemonset.Name)
continue
}
// Mutate containers from daemonset and add to pod spec
sideCars := daemonset.Spec.Template.Spec.DeepCopy().Containers
for _, c := range sideCars {
// Remove host port from ports
var ports []v1.ContainerPort
for _, port := range c.Ports {
ports = append(ports, v1.ContainerPort{
Name: port.Name,
HostPort: 0,
ContainerPort: port.ContainerPort,
Protocol: port.Protocol,
HostIP: "",
})
}
c.Ports = ports
containers = append(containers, c)
}
// containers = append(containers, sideCars...)
operations = append(operations, exorcism.ReplacePatchOperation("/spec/containers", containers))
}
// Add a simple annotation using `AddPatchOperation`
metadata := map[string]string{"origin": "fromMutation"}
operations = append(operations, exorcism.AddPatchOperation("/metadata/annotations", metadata))
log.Flush()
return &exorcism.Result{
Allowed: true,
PatchOps: operations,
}, nil
}
}
func contains(set []string, element string) bool {
for _, v := range set {
if v == element {
return true
}
}
return false
}