Skip to content

Commit 73085fe

Browse files
committed
Added additional code to main to setup webhook certificates and start the webhook
1 parent b106499 commit 73085fe

8 files changed

+643
-12
lines changed

cmd/main.go

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ limitations under the License.
1717
package main
1818

1919
import (
20+
"context"
2021
"crypto/tls"
2122
"encoding/json"
2223
"flag"
2324
"fmt"
2425
webhook2 "github.com/att-cloudnative-labs/kconfig-controller/internal/webhook"
2526
"os"
27+
"path/filepath"
28+
"sigs.k8s.io/controller-runtime/pkg/certwatcher"
2629
"sigs.k8s.io/controller-runtime/pkg/client"
2730

2831
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
@@ -67,6 +70,8 @@ func main() {
6770
var configMapPrefix string
6871
var secretPrefix string
6972
var defaultContainerSelector string
73+
var webhookPort int
74+
var webhookCertPath, webhookCertName, webhookCertKey string
7075

7176
flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
7277
"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
@@ -81,6 +86,10 @@ func main() {
8186
flag.StringVar(&configMapPrefix, "configmap-prefix", "kc-", "prefix added to name of configmaps created from kconfigs")
8287
flag.StringVar(&secretPrefix, "secret-prefix", "kc-", "prefix added to the name of secrets created from kconfigs")
8388
flag.StringVar(&defaultContainerSelector, "default-container-selector", "{}", "default container selector if kconfig doesn't supply")
89+
flag.StringVar(&webhookCertPath, "webhook-cert-path", "", "The directory that contains the webhook certificate.")
90+
flag.StringVar(&webhookCertName, "webhook-cert-name", "tls.crt", "The name of the webhook certificate file.")
91+
flag.StringVar(&webhookCertKey, "webhook-cert-key", "tls.key", "The name of the webhook key file.")
92+
flag.IntVar(&webhookPort, "webhook-port", 9443, "The port on which the webhook server listens.")
8493
opts := zap.Options{
8594
Development: true,
8695
}
@@ -103,6 +112,30 @@ func main() {
103112
if !enableHTTP2 {
104113
tlsOpts = append(tlsOpts, disableHTTP2)
105114
}
115+
// Create watchers for metrics and webhooks certificates
116+
var webhookCertWatcher *certwatcher.CertWatcher
117+
118+
// Initial webhook TLS options
119+
webhookTLSOpts := tlsOpts
120+
121+
if len(webhookCertPath) > 0 {
122+
setupLog.Info("Initializing webhook certificate watcher using provided certificates",
123+
"webhook-cert-path", webhookCertPath, "webhook-cert-name", webhookCertName, "webhook-cert-key", webhookCertKey)
124+
125+
var err error
126+
webhookCertWatcher, err = certwatcher.New(
127+
filepath.Join(webhookCertPath, webhookCertName),
128+
filepath.Join(webhookCertPath, webhookCertKey),
129+
)
130+
if err != nil {
131+
setupLog.Error(err, "Failed to initialize webhook certificate watcher")
132+
os.Exit(1)
133+
}
134+
135+
webhookTLSOpts = append(webhookTLSOpts, func(config *tls.Config) {
136+
config.GetCertificate = webhookCertWatcher.GetCertificate
137+
})
138+
}
106139

107140
var containerSelector v1.LabelSelector
108141
err := json.Unmarshal([]byte(defaultContainerSelector), &containerSelector)
@@ -113,7 +146,7 @@ func main() {
113146
setupLog.Info("setting up pod config injector webhook")
114147

115148
webhookServer := webhook.NewServer(webhook.Options{
116-
TLSOpts: tlsOpts,
149+
TLSOpts: webhookTLSOpts, Port: webhookPort,
117150
})
118151
cfg := ctrl.GetConfigOrDie()
119152
client, err := client.New(cfg, client.Options{})
@@ -129,6 +162,11 @@ func main() {
129162
DefaultContainerSelector: &containerSelector,
130163
},
131164
})
165+
166+
if err := webhookServer.Start(context.Background()); err != nil {
167+
setupLog.Error(err, "error starting webhook server")
168+
os.Exit(1)
169+
}
132170
// Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
133171
// More info:
134172
// - https://pkg.go.dev/sigs.k8s.io/[email protected]/pkg/metrics/server
@@ -210,4 +248,5 @@ func main() {
210248
setupLog.Error(err, "problem running manager")
211249
os.Exit(1)
212250
}
251+
213252
}
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
---
2+
apiVersion: apiextensions.k8s.io/v1
3+
kind: CustomResourceDefinition
4+
metadata:
5+
annotations:
6+
controller-gen.kubebuilder.io/version: v0.16.4
7+
name: kconfigbindings.kconfigcontroller.atteg.com
8+
spec:
9+
group: kconfigcontroller.atteg.com
10+
names:
11+
kind: KconfigBinding
12+
listKind: KconfigBindingList
13+
plural: kconfigbindings
14+
singular: kconfigbinding
15+
scope: Namespaced
16+
versions:
17+
- name: v1beta1
18+
schema:
19+
openAPIV3Schema:
20+
description: KconfigBinding is the Schema for the kconfigbindings API.
21+
properties:
22+
apiVersion:
23+
description: |-
24+
APIVersion defines the versioned schema of this representation of an object.
25+
Servers should convert recognized schemas to the latest internal value, and
26+
may reject unrecognized values.
27+
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
28+
type: string
29+
kind:
30+
description: |-
31+
Kind is a string value representing the REST resource this object represents.
32+
Servers may infer this from the endpoint the client submits requests to.
33+
Cannot be updated.
34+
In CamelCase.
35+
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
36+
type: string
37+
metadata:
38+
type: object
39+
spec:
40+
description: KconfigBindingSpec defines the desired state of KconfigBinding.
41+
properties:
42+
containerSelector:
43+
description: |-
44+
A label selector is a label query over a set of resources. The result of matchLabels and
45+
matchExpressions are ANDed. An empty label selector matches all objects. A null
46+
label selector matches no objects.
47+
properties:
48+
matchExpressions:
49+
description: matchExpressions is a list of label selector requirements.
50+
The requirements are ANDed.
51+
items:
52+
description: |-
53+
A label selector requirement is a selector that contains values, a key, and an operator that
54+
relates the key and values.
55+
properties:
56+
key:
57+
description: key is the label key that the selector applies
58+
to.
59+
type: string
60+
operator:
61+
description: |-
62+
operator represents a key's relationship to a set of values.
63+
Valid operators are In, NotIn, Exists and DoesNotExist.
64+
type: string
65+
values:
66+
description: |-
67+
values is an array of string values. If the operator is In or NotIn,
68+
the values array must be non-empty. If the operator is Exists or DoesNotExist,
69+
the values array must be empty. This array is replaced during a strategic
70+
merge patch.
71+
items:
72+
type: string
73+
type: array
74+
x-kubernetes-list-type: atomic
75+
required:
76+
- key
77+
- operator
78+
type: object
79+
type: array
80+
x-kubernetes-list-type: atomic
81+
matchLabels:
82+
additionalProperties:
83+
type: string
84+
description: |-
85+
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
86+
map is equivalent to an element of matchExpressions, whose key field is "key", the
87+
operator is "In", and the values array contains only "value". The requirements are ANDed.
88+
type: object
89+
type: object
90+
x-kubernetes-map-type: atomic
91+
envs:
92+
items:
93+
description: EnvVar represents an environment variable present in
94+
a Container.
95+
properties:
96+
name:
97+
description: Name of the environment variable. Must be a C_IDENTIFIER.
98+
type: string
99+
value:
100+
description: |-
101+
Variable references $(VAR_NAME) are expanded
102+
using the previously defined environment variables in the container and
103+
any service environment variables. If a variable cannot be resolved,
104+
the reference in the input string will be unchanged. Double $$ are reduced
105+
to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.
106+
"$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
107+
Escaped references will never be expanded, regardless of whether the variable
108+
exists or not.
109+
Defaults to "".
110+
type: string
111+
valueFrom:
112+
description: Source for the environment variable's value. Cannot
113+
be used if value is not empty.
114+
properties:
115+
configMapKeyRef:
116+
description: Selects a key of a ConfigMap.
117+
properties:
118+
key:
119+
description: The key to select.
120+
type: string
121+
name:
122+
default: ""
123+
description: |-
124+
Name of the referent.
125+
This field is effectively required, but due to backwards compatibility is
126+
allowed to be empty. Instances of this type with an empty value here are
127+
almost certainly wrong.
128+
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
129+
type: string
130+
optional:
131+
description: Specify whether the ConfigMap or its key
132+
must be defined
133+
type: boolean
134+
required:
135+
- key
136+
type: object
137+
x-kubernetes-map-type: atomic
138+
fieldRef:
139+
description: |-
140+
Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,
141+
spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
142+
properties:
143+
apiVersion:
144+
description: Version of the schema the FieldPath is
145+
written in terms of, defaults to "v1".
146+
type: string
147+
fieldPath:
148+
description: Path of the field to select in the specified
149+
API version.
150+
type: string
151+
required:
152+
- fieldPath
153+
type: object
154+
x-kubernetes-map-type: atomic
155+
resourceFieldRef:
156+
description: |-
157+
Selects a resource of the container: only resources limits and requests
158+
(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
159+
properties:
160+
containerName:
161+
description: 'Container name: required for volumes,
162+
optional for env vars'
163+
type: string
164+
divisor:
165+
anyOf:
166+
- type: integer
167+
- type: string
168+
description: Specifies the output format of the exposed
169+
resources, defaults to "1"
170+
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
171+
x-kubernetes-int-or-string: true
172+
resource:
173+
description: 'Required: resource to select'
174+
type: string
175+
required:
176+
- resource
177+
type: object
178+
x-kubernetes-map-type: atomic
179+
secretKeyRef:
180+
description: Selects a key of a secret in the pod's namespace
181+
properties:
182+
key:
183+
description: The key of the secret to select from. Must
184+
be a valid secret key.
185+
type: string
186+
name:
187+
default: ""
188+
description: |-
189+
Name of the referent.
190+
This field is effectively required, but due to backwards compatibility is
191+
allowed to be empty. Instances of this type with an empty value here are
192+
almost certainly wrong.
193+
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
194+
type: string
195+
optional:
196+
description: Specify whether the Secret or its key must
197+
be defined
198+
type: boolean
199+
required:
200+
- key
201+
type: object
202+
x-kubernetes-map-type: atomic
203+
type: object
204+
required:
205+
- name
206+
type: object
207+
type: array
208+
level:
209+
type: integer
210+
selector:
211+
description: |-
212+
A label selector is a label query over a set of resources. The result of matchLabels and
213+
matchExpressions are ANDed. An empty label selector matches all objects. A null
214+
label selector matches no objects.
215+
properties:
216+
matchExpressions:
217+
description: matchExpressions is a list of label selector requirements.
218+
The requirements are ANDed.
219+
items:
220+
description: |-
221+
A label selector requirement is a selector that contains values, a key, and an operator that
222+
relates the key and values.
223+
properties:
224+
key:
225+
description: key is the label key that the selector applies
226+
to.
227+
type: string
228+
operator:
229+
description: |-
230+
operator represents a key's relationship to a set of values.
231+
Valid operators are In, NotIn, Exists and DoesNotExist.
232+
type: string
233+
values:
234+
description: |-
235+
values is an array of string values. If the operator is In or NotIn,
236+
the values array must be non-empty. If the operator is Exists or DoesNotExist,
237+
the values array must be empty. This array is replaced during a strategic
238+
merge patch.
239+
items:
240+
type: string
241+
type: array
242+
x-kubernetes-list-type: atomic
243+
required:
244+
- key
245+
- operator
246+
type: object
247+
type: array
248+
x-kubernetes-list-type: atomic
249+
matchLabels:
250+
additionalProperties:
251+
type: string
252+
description: |-
253+
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
254+
map is equivalent to an element of matchExpressions, whose key field is "key", the
255+
operator is "In", and the values array contains only "value". The requirements are ANDed.
256+
type: object
257+
type: object
258+
x-kubernetes-map-type: atomic
259+
required:
260+
- containerSelector
261+
- envs
262+
- level
263+
type: object
264+
status:
265+
description: KconfigBindingStatus defines the observed state of KconfigBinding.
266+
properties:
267+
observedGeneration:
268+
format: int64
269+
type: integer
270+
required:
271+
- observedGeneration
272+
type: object
273+
type: object
274+
served: true
275+
storage: true
276+
subresources:
277+
status: {}

0 commit comments

Comments
 (0)