Skip to content

Commit 303cc53

Browse files
committed
feat: generate a self-signed cert for registry addon
1 parent 6b9c159 commit 303cc53

File tree

14 files changed

+1413
-85
lines changed

14 files changed

+1413
-85
lines changed
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
replicaCount: 2
1+
replicaCount: {{ .Replicas }}
22
persistence:
33
enabled: true
44
size: 50Gi
55
service:
66
type: ClusterIP
77
clusterIP: {{ .ServiceIP }}
8-
port: 80
8+
port: 443
99
statefulSet:
1010
enabled: true
1111
syncer:
1212
interval: 2m
13+
tlsSecretName: {{ .TLSSecretName }}

charts/cluster-api-runtime-extensions-nutanix/templates/certificates.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,20 @@ spec:
3232
kind: {{ .Values.certificates.issuer.kind }}
3333
name: {{ template "chart.issuerName" . }}
3434
secretName: {{ template "chart.name" . }}-admission-tls
35+
---
36+
# CA used to sign certificates for the clusters' registry addons
37+
apiVersion: cert-manager.io/v1
38+
kind: Certificate
39+
metadata:
40+
name: registry-addon-tls
41+
namespace: {{ .Release.Namespace }}
42+
labels:
43+
{{- include "chart.labels" . | nindent 4 }}
44+
spec:
45+
isCA: true
46+
commonName: registry-addon
47+
secretName: registry-addon-tls
48+
issuerRef:
49+
kind: {{ .Values.certificates.issuer.kind }}
50+
name: {{ template "chart.issuerName" . }}
51+
duration: 87600h # 10 years

pkg/handlers/generic/lifecycle/registry/cncfdistribution/handler.go

Lines changed: 100 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ import (
2424
const (
2525
DefaultHelmReleaseName = "cncf-distribution-registry"
2626
DefaultHelmReleaseNamespace = "registry-system"
27+
28+
stsName = "cncf-distribution-registry-docker-registry"
29+
stsHeadlessServiceName = "cncf-distribution-registry-docker-registry-headless"
30+
stsReplicas = 2
31+
tlsSecretName = "registry-tls"
2732
)
2833

2934
type Config struct {
@@ -59,14 +64,71 @@ func New(
5964
}
6065
}
6166

67+
func (n *CNCFDistribution) Setup(
68+
ctx context.Context,
69+
_ v1alpha1.RegistryAddon,
70+
cluster *clusterv1.Cluster,
71+
log logr.Logger,
72+
) error {
73+
log.Info("Setting up CA for CNCF Distribution registry")
74+
err := utils.EnsureCASecretForCluster(
75+
ctx,
76+
n.client,
77+
cluster,
78+
)
79+
if err != nil {
80+
return fmt.Errorf("failed to ensure CA secret for CNCF Distribution registry addon: %w", err)
81+
}
82+
return nil
83+
}
84+
6285
func (n *CNCFDistribution) Apply(
6386
ctx context.Context,
6487
_ v1alpha1.RegistryAddon,
6588
cluster *clusterv1.Cluster,
6689
log logr.Logger,
6790
) error {
68-
log.Info("Applying CNCF Distribution registry installation")
91+
log.Info("Copying TLS Certificate for CNCF Distribution registry to remote cluster")
92+
// Ensure the CA secret exists and is up to date in the cluster's namespace before trying to use it.
93+
err := utils.EnsureCASecretForCluster(
94+
ctx,
95+
n.client,
96+
cluster,
97+
)
98+
if err != nil {
99+
return fmt.Errorf("failed to ensure CA secret for CNCF Distribution registry addon: %w", err)
100+
}
69101

102+
// Copy the TLS secret to the remote cluster.
103+
serviceIP, err := utils.ServiceIPForCluster(cluster)
104+
if err != nil {
105+
return fmt.Errorf("error getting service IP for the CNCF distribution registry: %w", err)
106+
}
107+
opts := &utils.EnsureCertificateOpts{
108+
RemoteSecretKey: ctrlclient.ObjectKey{
109+
Name: tlsSecretName,
110+
Namespace: DefaultHelmReleaseNamespace,
111+
},
112+
Spec: utils.CertificateSpec{
113+
CommonName: stsName,
114+
DNSNames: certificateDNSNames(),
115+
IPAddresses: certificateIPAddresses(serviceIP),
116+
},
117+
}
118+
err = utils.EnsureTLSCertificateSecretOnRemoteCluster(
119+
ctx,
120+
n.client,
121+
cluster,
122+
opts,
123+
)
124+
if err != nil {
125+
return fmt.Errorf(
126+
"failed to copy certificate secret for CNCF Distribution registry addon to remote cluster: %w",
127+
err,
128+
)
129+
}
130+
131+
log.Info("Applying CNCF Distribution registry installation")
70132
helmChartInfo, err := n.helmChartInfoGetter.For(ctx, log, config.CNCFDistributionRegistry)
71133
if err != nil {
72134
return fmt.Errorf("failed to get CNCF Distribution registry helm chart: %w", err)
@@ -101,11 +163,15 @@ func templateValues(cluster *clusterv1.Cluster, text string) (string, error) {
101163
}
102164

103165
type input struct {
104-
ServiceIP string
166+
ServiceIP string
167+
Replicas int32
168+
TLSSecretName string
105169
}
106170

107171
templateInput := input{
108-
ServiceIP: serviceIP,
172+
Replicas: stsReplicas,
173+
ServiceIP: serviceIP,
174+
TLSSecretName: tlsSecretName,
109175
}
110176

111177
var b bytes.Buffer
@@ -119,3 +185,34 @@ func templateValues(cluster *clusterv1.Cluster, text string) (string, error) {
119185

120186
return b.String(), nil
121187
}
188+
189+
func certificateDNSNames() []string {
190+
names := []string{
191+
stsName,
192+
fmt.Sprintf("%s.%s", stsName, DefaultHelmReleaseNamespace),
193+
fmt.Sprintf("%s.%s.svc", stsName, DefaultHelmReleaseNamespace),
194+
fmt.Sprintf("%s.%s.svc.cluster.local", stsName, DefaultHelmReleaseNamespace),
195+
}
196+
for i := 0; i < stsReplicas; i++ {
197+
names = append(names,
198+
[]string{
199+
fmt.Sprintf("%s-%d", stsName, i),
200+
fmt.Sprintf("%s-%d.%s.%s", stsName, i, stsHeadlessServiceName, DefaultHelmReleaseNamespace),
201+
fmt.Sprintf("%s-%d.%s.%s.svc", stsName, i, stsHeadlessServiceName, DefaultHelmReleaseNamespace),
202+
fmt.Sprintf(
203+
"%s-%d.%s.%s.svc.cluster.local",
204+
stsName, i, stsHeadlessServiceName, DefaultHelmReleaseNamespace,
205+
),
206+
}...,
207+
)
208+
}
209+
210+
return names
211+
}
212+
213+
func certificateIPAddresses(serviceIP string) []string {
214+
return []string{
215+
serviceIP,
216+
"127.0.0.1",
217+
}
218+
}

pkg/handlers/generic/lifecycle/registry/handler.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ import (
2020
)
2121

2222
type RegistryProvider interface {
23+
Setup(
24+
ctx context.Context,
25+
registryVar v1alpha1.RegistryAddon,
26+
cluster *clusterv1.Cluster,
27+
log logr.Logger,
28+
) error
2329
Apply(
2430
ctx context.Context,
2531
registryVar v1alpha1.RegistryAddon,
@@ -37,6 +43,7 @@ type RegistryHandler struct {
3743

3844
var (
3945
_ commonhandlers.Named = &RegistryHandler{}
46+
_ lifecycle.BeforeClusterCreate = &RegistryHandler{}
4047
_ lifecycle.AfterControlPlaneInitialized = &RegistryHandler{}
4148
_ lifecycle.BeforeClusterUpgrade = &RegistryHandler{}
4249
)
@@ -57,6 +64,17 @@ func (r *RegistryHandler) Name() string {
5764
return "RegistryHandler"
5865
}
5966

67+
func (r *RegistryHandler) BeforeClusterCreate(
68+
ctx context.Context,
69+
req *runtimehooksv1.BeforeClusterCreateRequest,
70+
resp *runtimehooksv1.BeforeClusterCreateResponse,
71+
) {
72+
commonResponse := &runtimehooksv1.CommonResponse{}
73+
r.setup(ctx, &req.Cluster, commonResponse)
74+
resp.Status = commonResponse.GetStatus()
75+
resp.Message = commonResponse.GetMessage()
76+
}
77+
6078
func (r *RegistryHandler) AfterControlPlaneInitialized(
6179
ctx context.Context,
6280
req *runtimehooksv1.AfterControlPlaneInitializedRequest,
@@ -74,11 +92,97 @@ func (r *RegistryHandler) BeforeClusterUpgrade(
7492
resp *runtimehooksv1.BeforeClusterUpgradeResponse,
7593
) {
7694
commonResponse := &runtimehooksv1.CommonResponse{}
95+
r.setup(ctx, &req.Cluster, commonResponse)
7796
r.apply(ctx, &req.Cluster, commonResponse)
7897
resp.Status = commonResponse.GetStatus()
7998
resp.Message = commonResponse.GetMessage()
8099
}
81100

101+
func (r *RegistryHandler) setup(
102+
ctx context.Context,
103+
cluster *clusterv1.Cluster,
104+
resp *runtimehooksv1.CommonResponse,
105+
) {
106+
clusterKey := ctrlclient.ObjectKeyFromObject(cluster)
107+
108+
log := ctrl.LoggerFrom(ctx).WithValues(
109+
"cluster",
110+
clusterKey,
111+
)
112+
113+
varMap := variables.ClusterVariablesToVariablesMap(cluster.Spec.Topology.Variables)
114+
registryVar, err := variables.Get[v1alpha1.RegistryAddon](
115+
varMap,
116+
r.variableName,
117+
r.variablePath...)
118+
if err != nil {
119+
if variables.IsNotFoundError(err) {
120+
log.V(5).
121+
Info(
122+
"Skipping RegistryAddon, field is not specified",
123+
"error",
124+
err,
125+
)
126+
return
127+
}
128+
log.Error(
129+
err,
130+
"failed to read RegistryAddon provider from cluster definition",
131+
)
132+
resp.SetStatus(runtimehooksv1.ResponseStatusFailure)
133+
resp.SetMessage(
134+
fmt.Sprintf("failed to read RegistryAddon provider from cluster definition: %v",
135+
err,
136+
),
137+
)
138+
return
139+
}
140+
141+
handler, ok := r.ProviderHandler[registryVar.Provider]
142+
if !ok {
143+
err = fmt.Errorf("unknown RegistryAddon Provider")
144+
log.Error(err, "provider", registryVar.Provider)
145+
resp.SetStatus(runtimehooksv1.ResponseStatusFailure)
146+
resp.SetMessage(
147+
fmt.Sprintf("%s %s", err, registryVar.Provider),
148+
)
149+
return
150+
}
151+
152+
log.Info(fmt.Sprintf("Setting up RegistryAddon provider prerequisites %s", registryVar.Provider))
153+
err = handler.Setup(
154+
ctx,
155+
registryVar,
156+
cluster,
157+
log,
158+
)
159+
if err != nil {
160+
log.Error(
161+
err,
162+
fmt.Sprintf(
163+
"failed to set up RegistryAddon provider prerequisites %s",
164+
registryVar.Provider,
165+
),
166+
)
167+
resp.SetStatus(runtimehooksv1.ResponseStatusFailure)
168+
resp.SetMessage(
169+
fmt.Sprintf(
170+
"failed to set up RegistryAddon provider prerequisites: %v",
171+
err,
172+
),
173+
)
174+
return
175+
}
176+
177+
resp.SetStatus(runtimehooksv1.ResponseStatusSuccess)
178+
resp.SetMessage(
179+
fmt.Sprintf(
180+
"Set up RegistryAddon provider prerequisites %s",
181+
registryVar.Provider,
182+
),
183+
)
184+
}
185+
82186
func (r *RegistryHandler) apply(
83187
ctx context.Context,
84188
cluster *clusterv1.Cluster,

0 commit comments

Comments
 (0)