Skip to content

Commit 9c6ff0d

Browse files
authored
refactor: Use controller manager to start runtime hooks server (#134)
1 parent 18746b6 commit 9c6ff0d

File tree

21 files changed

+125
-244
lines changed

21 files changed

+125
-244
lines changed

charts/capi-runtime-extensions/README.md

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,13 @@ A Helm chart for capi-runtime-extensions
2828
| certificates.issuer.kind | string | `"Issuer"` | |
2929
| certificates.issuer.name | string | `""` | |
3030
| certificates.issuer.selfSigned | bool | `true` | |
31-
| controllers.enableLeaderElection | bool | `false` | |
3231
| deployment.replicas | int | `1` | |
3332
| env | object | `{}` | |
34-
| handlers.AuditPolicyPatch.enabled | bool | `true` | |
35-
| handlers.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.configMap.content | string | `""` | |
36-
| handlers.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.configMap.name | string | `"calico-cni-installation-dockercluster"` | |
37-
| handlers.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.create | bool | `true` | |
38-
| handlers.CalicoCNI.defaultPodSubnet | string | `"192.168.0.0/16"` | |
39-
| handlers.CalicoCNI.defaultTigeraOperatorConfigMap.name | string | `"tigera-operator"` | |
40-
| handlers.CalicoCNI.enabled | bool | `true` | |
41-
| handlers.ExtraAPIServerCertSANsPatch.enabled | bool | `true` | |
42-
| handlers.ExtraAPIServerCertSANsVars.enabled | bool | `true` | |
43-
| handlers.HTTPProxyPatch.enabled | bool | `true` | |
44-
| handlers.HTTPProxyVars.enabled | bool | `true` | |
45-
| handlers.ServiceLoadBalancerGC.enabled | bool | `true` | |
33+
| hooks.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.configMap.content | string | `""` | |
34+
| hooks.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.configMap.name | string | `"calico-cni-installation-dockercluster"` | |
35+
| hooks.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.create | bool | `true` | |
36+
| hooks.CalicoCNI.defaultPodSubnet | string | `"192.168.0.0/16"` | |
37+
| hooks.CalicoCNI.defaultTigeraOperatorConfigMap.name | string | `"tigera-operator"` | |
4638
| image.pullPolicy | string | `"IfNotPresent"` | |
4739
| image.repository | string | `"ghcr.io/d2iq-labs/capi-runtime-extensions"` | |
4840
| image.tag | string | `""` | |

charts/capi-runtime-extensions/templates/cni/calico/manifests/docker/installation.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
# Copyright 2023 D2iQ, Inc. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

4-
{{- if and .Values.handlers.CalicoCNI.enabled .Values.handlers.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.create }}
4+
{{- if .Values.hooks.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.create }}
55
apiVersion: v1
66
kind: ConfigMap
77
metadata:
8-
name: '{{ .Values.handlers.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.configMap.name }}'
8+
name: '{{ .Values.hooks.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.configMap.name }}'
99
data:
1010
calico-installation: |
11-
{{- if .Values.handlers.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.configMap.content -}}
12-
{{ .Values.handlers.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.configMap.content | nindent 4}}
11+
{{- if .Values.hooks.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.configMap.content -}}
12+
{{ .Values.hooks.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.configMap.content | nindent 4}}
1313
{{- else -}}
1414
# This section includes base Calico installation configuration.
1515
# For more information, see: https://docs.projectcalico.org/reference/installation/api
@@ -25,7 +25,7 @@ data:
2525
# Note: The ipPools section cannot be modified post-install.
2626
ipPools:
2727
- blockSize: 26
28-
cidr: {{ .Values.handlers.CalicoCNI.defaultPodSubnet }}
28+
cidr: {{ .Values.hooks.CalicoCNI.defaultPodSubnet }}
2929
encapsulation: VXLANCrossSubnet
3030
natOutgoing: Enabled
3131
nodeSelector: all()

charts/capi-runtime-extensions/templates/cni/calico/manifests/tigera-operator-configmap.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ data:
88
kind: ConfigMap
99
metadata:
1010
creationTimestamp: null
11-
name: '{{ .Values.handlers.CalicoCNI.defaultTigeraOperatorConfigMap.name }}'
11+
name: '{{ .Values.hooks.CalicoCNI.defaultTigeraOperatorConfigMap.name }}'

charts/capi-runtime-extensions/templates/deployment.yaml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,8 @@ spec:
2828
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default $.Chart.AppVersion }}"
2929
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
3030
args:
31-
- --controllermanager.leader-elect={{ if gt (.Values.deployment.replicas | int) 1 }}true{{ else }}{{ .Values.controllers.enableLeaderElection }}{{ end }}
32-
- --runtimehooks.cert-dir=/runtimehooks-certs/
33-
{{- range $key, $value := .Values.handlers }}{{ if $value.enabled }}
34-
- --runtimehooks.enabled-handlers={{ $key }}
35-
{{ end }}{{- end }}
36-
- --runtimehooks.calicocni.defaultsNamespace=$(POD_NAMESPACE)
31+
- --webhook-cert-dir=/runtimehooks-certs/
32+
- --calicocni.defaultsNamespace=$(POD_NAMESPACE)
3733
{{- range $key, $value := .Values.extraArgs }}
3834
- --{{ $key }}={{ $value }}
3935
{{- end }}

charts/capi-runtime-extensions/templates/role.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ rules:
1818
- patch
1919
- update
2020
- watch
21+
- apiGroups:
22+
- ""
23+
resources:
24+
- secrets
25+
verbs:
26+
- get
27+
- list
28+
- watch
2129
- apiGroups:
2230
- addons.cluster.x-k8s.io
2331
resources:

charts/capi-runtime-extensions/values.yaml

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
# Copyright 2023 D2iQ, Inc. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

4-
handlers:
4+
hooks:
55
CalicoCNI:
6-
enabled: true
76
defaultPodSubnet: 192.168.0.0/16
87
defaultTigeraOperatorConfigMap:
98
name: tigera-operator
@@ -13,25 +12,10 @@ handlers:
1312
configMap:
1413
name: calico-cni-installation-dockercluster
1514
content: ""
16-
ServiceLoadBalancerGC:
17-
enabled: true
18-
HTTPProxyVars:
19-
enabled: true
20-
HTTPProxyPatch:
21-
enabled: true
22-
AuditPolicyPatch:
23-
enabled: true
24-
ExtraAPIServerCertSANsVars:
25-
enabled: true
26-
ExtraAPIServerCertSANsPatch:
27-
enabled: true
2815

2916
deployment:
3017
replicas: 1
3118

32-
controllers:
33-
enableLeaderElection: false
34-
3519
image:
3620
repository: ghcr.io/d2iq-labs/capi-runtime-extensions
3721
tag: ""

cmd/capi-runtime-extensions/main.go

Lines changed: 66 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ package main
55

66
import (
77
"flag"
8+
"fmt"
89
"net/http"
910
"os"
1011
"time"
1112

1213
"github.com/spf13/pflag"
13-
"golang.org/x/sync/errgroup"
1414
"k8s.io/apimachinery/pkg/runtime"
1515
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
1616
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
@@ -22,10 +22,11 @@ import (
2222
capiv1 "sigs.k8s.io/cluster-api/api/v1beta1"
2323
crsv1 "sigs.k8s.io/cluster-api/exp/addons/api/v1beta1"
2424
ctrl "sigs.k8s.io/controller-runtime"
25-
ctrclient "sigs.k8s.io/controller-runtime/pkg/client"
25+
"sigs.k8s.io/controller-runtime/pkg/healthz"
26+
"sigs.k8s.io/controller-runtime/pkg/manager"
27+
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
2628

2729
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/server"
28-
"github.com/d2iq-labs/capi-runtime-extensions/internal/controllermanager"
2930
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/cni/calico"
3031
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/extraapiservercertsans"
3132
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/httpproxy"
@@ -53,42 +54,42 @@ func main() {
5354
// Creates a logger to be used during the main func.
5455
setupLog := ctrl.Log.WithName("main")
5556

56-
controllers := controllermanager.New()
57-
5857
scheme := runtime.NewScheme()
5958
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
6059
utilruntime.Must(crsv1.AddToScheme(scheme))
6160
utilruntime.Must(capiv1.AddToScheme(scheme))
6261

63-
// Gets a client to access the Kubernetes cluster where this RuntimeExtension will be deployed to
64-
restConfig, err := ctrl.GetConfig()
65-
if err != nil {
66-
setupLog.Error(err, "error getting config for the cluster")
67-
os.Exit(1)
62+
mgrOptions := &ctrl.Options{
63+
Scheme: scheme,
64+
Metrics: metricsserver.Options{
65+
BindAddress: ":8080",
66+
},
67+
HealthProbeBindAddress: ":8081",
68+
LeaderElection: false,
6869
}
6970

70-
client, err := ctrclient.New(restConfig, ctrclient.Options{Scheme: scheme})
71-
if err != nil {
72-
setupLog.Error(err, "error creating client to the cluster")
73-
os.Exit(1)
74-
}
71+
pflag.CommandLine.StringVar(
72+
&mgrOptions.Metrics.BindAddress,
73+
"metrics-bind-address",
74+
mgrOptions.Metrics.BindAddress,
75+
"The address the metric endpoint binds to.",
76+
)
77+
78+
pflag.CommandLine.StringVar(
79+
&mgrOptions.HealthProbeBindAddress,
80+
"health-probe-bind-address",
81+
mgrOptions.HealthProbeBindAddress,
82+
"The address the probe endpoint binds to.",
83+
)
7584

7685
calicoCNIConfig := &calico.CalicoCNIConfig{}
7786

78-
runtimeWebhookServer := server.NewServer(
79-
servicelbgc.New(client),
80-
calico.New(client, calicoCNIConfig),
81-
httpproxy.NewVariable(),
82-
httpproxy.NewPatch(client),
83-
extraapiservercertsans.NewVariable(),
84-
extraapiservercertsans.NewPatch(),
85-
)
87+
runtimeWebhookServerOpts := server.NewServerOptions()
8688

8789
// Initialize and parse command line flags.
8890
initFlags(pflag.CommandLine)
89-
runtimeWebhookServer.AddFlags("runtimehooks", pflag.CommandLine)
90-
controllers.AddFlags("controllermanager", pflag.CommandLine)
91-
calicoCNIConfig.AddFlags("runtimehooks.calicocni", pflag.CommandLine)
91+
runtimeWebhookServerOpts.AddFlags(pflag.CommandLine)
92+
calicoCNIConfig.AddFlags("calicocni", pflag.CommandLine)
9293
pflag.CommandLine.SetNormalizeFunc(cliflag.WordSepNormalizeFunc)
9394
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
9495
pflag.Parse()
@@ -120,26 +121,45 @@ func main() {
120121
}
121122

122123
signalCtx := ctrl.SetupSignalHandler()
123-
g, ctx := errgroup.WithContext(signalCtx)
124-
125-
g.Go(func() error {
126-
err := runtimeWebhookServer.Start(ctx)
127-
if err != nil {
128-
setupLog.Error(err, "unable to start runtime hooks wehook server")
129-
}
130-
return err
131-
})
132-
133-
g.Go(func() error {
134-
err := controllers.Start(ctx)
135-
if err != nil {
136-
setupLog.Error(err, "unable to start controller manager")
137-
}
138-
return err
139-
})
140-
141-
if err := g.Wait(); err != nil {
142-
setupLog.Error(err, "failed to run successfully")
124+
125+
mgr, err := newManager(mgrOptions)
126+
if err != nil {
127+
setupLog.Error(err, "failed to create a new controller manager")
143128
os.Exit(1)
144129
}
130+
131+
runtimeWebhookServer := server.NewServer(
132+
runtimeWebhookServerOpts,
133+
servicelbgc.New(mgr.GetClient()),
134+
calico.New(mgr.GetClient(), calicoCNIConfig),
135+
httpproxy.NewVariable(),
136+
httpproxy.NewPatch(mgr.GetClient()),
137+
extraapiservercertsans.NewVariable(),
138+
extraapiservercertsans.NewPatch(),
139+
)
140+
if err := mgr.Add(runtimeWebhookServer); err != nil {
141+
setupLog.Error(err, "unable to add runtime webhook server runnable to controller manager")
142+
os.Exit(1)
143+
}
144+
145+
if err := mgr.Start(signalCtx); err != nil {
146+
setupLog.Error(err, "unable to start controller manager")
147+
os.Exit(1)
148+
}
149+
}
150+
151+
func newManager(opts *manager.Options) (ctrl.Manager, error) {
152+
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), *opts)
153+
if err != nil {
154+
return nil, fmt.Errorf("unable to create manager: %w", err)
155+
}
156+
157+
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
158+
return nil, fmt.Errorf("unable to set up health check: %w", err)
159+
}
160+
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
161+
return nil, fmt.Errorf("unable to set up ready check: %w", err)
162+
}
163+
164+
return mgr, nil
145165
}

common/pkg/server/server.go

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ package server
55

66
import (
77
"context"
8-
"slices"
98
"strings"
109

1110
"github.com/spf13/pflag"
@@ -20,51 +19,43 @@ import (
2019
)
2120

2221
type Server struct {
23-
allExtensionHandlers []handlers.Named
24-
25-
webhookPort int
26-
webhookCertDir string
27-
2822
catalog *runtimecatalog.Catalog
23+
hooks []handlers.Named
2924

30-
enabledHandlers []string
25+
opts *ServerOptions
3126
}
3227

33-
func NewServer(extensionHandlers ...handlers.Named) *Server {
28+
func NewServer(opts *ServerOptions, hooks ...handlers.Named) *Server {
3429
// catalog contains all information about RuntimeHooks.
3530
catalog := runtimecatalog.New()
3631

3732
_ = runtimehooksv1.AddToCatalog(catalog)
3833

3934
return &Server{
40-
allExtensionHandlers: extensionHandlers,
41-
catalog: catalog,
42-
webhookPort: 9443,
43-
webhookCertDir: "/runtimehooks-certs/",
35+
catalog: catalog,
36+
opts: opts,
37+
hooks: hooks,
4438
}
4539
}
4640

47-
func (s *Server) AddFlags(prefix string, fs *pflag.FlagSet) {
48-
fs.IntVar(&s.webhookPort, prefix+".port", s.webhookPort, "Webhook Server port")
41+
type ServerOptions struct {
42+
webhookPort int
43+
webhookCertDir string
44+
}
45+
46+
func NewServerOptions() *ServerOptions {
47+
return &ServerOptions{}
48+
}
49+
50+
func (s *ServerOptions) AddFlags(fs *pflag.FlagSet) {
51+
fs.IntVar(&s.webhookPort, "webhook-port", s.webhookPort, "Webhook Server port")
4952

5053
fs.StringVar(
5154
&s.webhookCertDir,
52-
prefix+".cert-dir",
55+
"webhook-cert-dir",
5356
s.webhookCertDir,
5457
"Runtime hooks server cert dir.",
5558
)
56-
57-
handlerNames := make([]string, 0, len(s.allExtensionHandlers))
58-
for _, h := range s.allExtensionHandlers {
59-
handlerNames = append(handlerNames, h.Name())
60-
}
61-
62-
fs.StringSliceVar(
63-
&s.enabledHandlers,
64-
prefix+".enabled-handlers",
65-
handlerNames,
66-
"list of all enabled handlers",
67-
)
6859
}
6960

7061
func (s *Server) Start(ctx context.Context) error {
@@ -74,20 +65,16 @@ func (s *Server) Start(ctx context.Context) error {
7465
// Create a http server for serving runtime extensions
7566
webhookServer, err := server.New(server.Options{
7667
Catalog: s.catalog,
77-
Port: s.webhookPort,
78-
CertDir: s.webhookCertDir,
68+
Port: s.opts.webhookPort,
69+
CertDir: s.opts.webhookCertDir,
7970
})
8071
if err != nil {
8172
setupLog.Error(err, "error creating webhook server")
8273
return err
8374
}
8475

85-
for idx := range s.allExtensionHandlers {
86-
h := s.allExtensionHandlers[idx]
87-
88-
if !slices.Contains(s.enabledHandlers, h.Name()) {
89-
continue
90-
}
76+
for idx := range s.hooks {
77+
h := s.hooks[idx]
9178

9279
if t, ok := h.(lifecycle.BeforeClusterCreate); ok {
9380
if err := webhookServer.AddExtensionHandler(server.ExtensionHandler{

0 commit comments

Comments
 (0)