1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package webhook
16
17 import (
18 "sort"
19
20 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s"
21
22 admissionregistration "k8s.io/api/admissionregistration/v1"
23 corev1 "k8s.io/api/core/v1"
24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25 "k8s.io/apimachinery/pkg/util/intstr"
26 )
27
28 var (
29 admissionReviewVersions = []string{"v1"}
30 )
31
32 func GenerateWebhookManifests(validatingWebhookConfigurationName, mutatingWebhookConfigurationName,
33 serviceName string, whCfgs []WebhookConfig) (*admissionregistration.ValidatingWebhookConfiguration, *admissionregistration.MutatingWebhookConfiguration) {
34 validating := validatingWebhookConfig(validatingWebhookConfigurationName, serviceName, whCfgs)
35 mutating := mutatingWebhookConfig(mutatingWebhookConfigurationName, serviceName, whCfgs)
36 return validating, mutating
37 }
38
39 func generateService(name string, selector map[string]string) *corev1.Service {
40 return &corev1.Service{
41 ObjectMeta: metav1.ObjectMeta{
42 Name: name,
43 Namespace: k8s.SystemNamespace,
44 },
45 Spec: corev1.ServiceSpec{
46 Selector: selector,
47 Ports: []corev1.ServicePort{
48 {
49 Port: ServicePort,
50 TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: ServicePort},
51 },
52 },
53 },
54 }
55 }
56
57 func mutatingWebhooksForWebhookConfigs(whCfgs []WebhookConfig, svcName string, whType webhookType) []admissionregistration.MutatingWebhook {
58 whs := make([]admissionregistration.MutatingWebhook, 0)
59 for _, whCfg := range whCfgs {
60 if whCfg.Type != whType {
61 continue
62 }
63 wh := &admissionregistration.MutatingWebhook{
64 Name: whCfg.Name,
65 Rules: whCfg.Rules,
66 ObjectSelector: whCfg.ObjectSelector,
67 FailurePolicy: &whCfg.FailurePolicy,
68 SideEffects: &whCfg.SideEffects,
69 AdmissionReviewVersions: admissionReviewVersions,
70 TimeoutSeconds: &k8s.WebhookTimeoutSeconds,
71 }
72 cc := getClientConfig(svcName, whCfg.Path)
73 wh.ClientConfig = *cc
74 whs = append(whs, *wh)
75 }
76 sort.Slice(whs, func(i, j int) bool {
77 return whs[i].Name < whs[j].Name
78 })
79 return whs
80 }
81
82 func validatingWebhooksForWebhookConfigs(whCfgs []WebhookConfig, svcName string, whType webhookType) []admissionregistration.ValidatingWebhook {
83 whs := make([]admissionregistration.ValidatingWebhook, 0)
84 for _, whCfg := range whCfgs {
85 if whCfg.Type != whType {
86 continue
87 }
88 wh := &admissionregistration.ValidatingWebhook{
89 Name: whCfg.Name,
90 Rules: whCfg.Rules,
91 ObjectSelector: whCfg.ObjectSelector,
92 FailurePolicy: &whCfg.FailurePolicy,
93 SideEffects: &whCfg.SideEffects,
94 AdmissionReviewVersions: admissionReviewVersions,
95 TimeoutSeconds: &k8s.WebhookTimeoutSeconds,
96 }
97 cc := getClientConfig(svcName, whCfg.Path)
98 wh.ClientConfig = *cc
99 whs = append(whs, *wh)
100 }
101 sort.Slice(whs, func(i, j int) bool {
102 return whs[i].Name < whs[j].Name
103 })
104 return whs
105 }
106
107 func mutatingWebhookConfig(name, svcName string, whCfgs []WebhookConfig) *admissionregistration.MutatingWebhookConfiguration {
108 whs := mutatingWebhooksForWebhookConfigs(whCfgs, svcName, Mutating)
109 if len(whs) > 0 {
110 return &admissionregistration.MutatingWebhookConfiguration{
111 TypeMeta: metav1.TypeMeta{
112 APIVersion: admissionregistration.SchemeGroupVersion.String(),
113 Kind: "MutatingWebhookConfiguration",
114 },
115 ObjectMeta: metav1.ObjectMeta{
116 Name: name,
117 Labels: map[string]string{
118 k8s.KCCSystemLabel: "true",
119 },
120 },
121 Webhooks: whs,
122 }
123 }
124 return nil
125 }
126
127 func validatingWebhookConfig(name, svcName string, whCfgs []WebhookConfig) *admissionregistration.ValidatingWebhookConfiguration {
128 whs := validatingWebhooksForWebhookConfigs(whCfgs, svcName, Validating)
129 if len(whs) > 0 {
130 return &admissionregistration.ValidatingWebhookConfiguration{
131 TypeMeta: metav1.TypeMeta{
132 APIVersion: admissionregistration.SchemeGroupVersion.String(),
133 Kind: "ValidatingWebhookConfiguration",
134 },
135 ObjectMeta: metav1.ObjectMeta{
136 Name: name,
137 Labels: map[string]string{
138 k8s.KCCSystemLabel: "true",
139 },
140 },
141 Webhooks: whs,
142 }
143 }
144 return nil
145 }
146
147 func getClientConfig(serviceName, path string) *admissionregistration.WebhookClientConfig {
148 return &admissionregistration.WebhookClientConfig{
149 CABundle: []byte{},
150 Service: &admissionregistration.ServiceReference{
151 Name: serviceName,
152 Namespace: k8s.SystemNamespace,
153 Path: &path,
154 },
155 }
156 }
157
View as plain text