Skip to content

Commit 0f65310

Browse files
committed
feat(controlplane): implement STACKIT pod identity webhook deployment
1 parent 1c3d5d7 commit 0f65310

2 files changed

Lines changed: 80 additions & 26 deletions

File tree

pkg/controller/controlplane/valuesprovider.go

Lines changed: 77 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"fmt"
1111
"maps"
1212
"path/filepath"
13-
"sort"
1413
"strings"
1514

1615
"github.com/Masterminds/semver/v3"
@@ -28,6 +27,7 @@ import (
2827
kutil "github.com/gardener/gardener/pkg/utils/kubernetes"
2928
secretutils "github.com/gardener/gardener/pkg/utils/secrets"
3029
secretsmanager "github.com/gardener/gardener/pkg/utils/secrets/manager"
30+
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
3131
appsv1 "k8s.io/api/apps/v1"
3232
corev1 "k8s.io/api/core/v1"
3333
networkingv1 "k8s.io/api/networking/v1"
@@ -37,13 +37,10 @@ import (
3737
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
3838
"k8s.io/apimachinery/pkg/api/errors"
3939
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
40-
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
4140
"k8s.io/apimachinery/pkg/runtime"
42-
"k8s.io/apimachinery/pkg/runtime/schema"
4341
"k8s.io/apimachinery/pkg/runtime/serializer"
4442
"k8s.io/apimachinery/pkg/types"
4543
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
46-
"k8s.io/apimachinery/pkg/util/sets"
4744
vpaautoscalingv1 "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1"
4845
"k8s.io/utils/ptr"
4946
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
@@ -59,8 +56,9 @@ import (
5956
)
6057

6158
const (
62-
caNameControlPlane = "ca-" + openstack.Name + "-controlplane"
63-
cloudControllerManagerServerName = openstack.CloudControllerManagerName + "-server"
59+
caNameControlPlane = "ca-" + openstack.Name + "-controlplane"
60+
cloudControllerManagerServerName = openstack.CloudControllerManagerName + "-server"
61+
stackitPodIdentityWebhookServerName = stackit.STACKITPodIdentityWebhookName + "-server"
6462

6563
CSIStackitPrefix = "stackit-blockstorage"
6664

@@ -103,6 +101,16 @@ func secretConfigsFunc(namespace string) []extensionssecretmanager.SecretConfigW
103101
},
104102
Options: []secretsmanager.GenerateOption{secretsmanager.SignedByCA(caNameControlPlane)},
105103
},
104+
{
105+
Config: &secretutils.CertificateSecretConfig{
106+
Name: stackitPodIdentityWebhookServerName,
107+
CommonName: stackit.STACKITPodIdentityWebhookName,
108+
DNSNames: kutil.DNSNamesForService(stackit.STACKITPodIdentityWebhookName, namespace),
109+
CertType: secretutils.ServerCert,
110+
SkipPublishingCACertificate: true,
111+
},
112+
Options: []secretsmanager.GenerateOption{secretsmanager.SignedByCA(caNameControlPlane)},
113+
},
106114
}
107115
}
108116

@@ -117,12 +125,6 @@ func shootAccessSecretsFunc(namespace string) []*gutil.AccessSecret {
117125
}
118126
}
119127

120-
func makeUnstructured(gvk schema.GroupVersionKind) *unstructured.Unstructured {
121-
obj := &unstructured.Unstructured{}
122-
obj.SetGroupVersionKind(gvk)
123-
return obj
124-
}
125-
126128
var (
127129
configChart = &chart.Chart{
128130
Name: openstack.CloudProviderConfigName,
@@ -207,6 +209,14 @@ var (
207209
{Type: &vpaautoscalingv1.VerticalPodAutoscaler{}, Name: openstack.STACKITALBControllerManagerName},
208210
},
209211
},
212+
{
213+
Name: stackit.STACKITPodIdentityWebhookName,
214+
Images: []string{imagevector.ImageNameStackitPodIdentityWebhook},
215+
Objects: []*chart.Object{
216+
{Type: &appsv1.Deployment{}, Name: stackit.STACKITPodIdentityWebhookName},
217+
{Type: &corev1.Service{}, Name: stackit.STACKITPodIdentityWebhookName},
218+
},
219+
},
210220
},
211221
}
212222

@@ -306,6 +316,12 @@ var (
306316
{Type: &rbacv1.RoleBinding{}, Name: openstack.UsernamePrefix + openstack.CSIResizerName},
307317
},
308318
},
319+
{
320+
Name: stackit.STACKITPodIdentityWebhookName,
321+
Objects: []*chart.Object{
322+
{Type: &admissionregistrationv1.MutatingWebhookConfiguration{}, Name: stackit.STACKITPodIdentityWebhookName},
323+
},
324+
},
309325
},
310326
}
311327

@@ -478,7 +494,7 @@ func (vp *valuesProvider) GetControlPlaneShootChartValues(
478494
ctx context.Context,
479495
cp *extensionsv1alpha1.ControlPlane,
480496
cluster *extensionscontroller.Cluster,
481-
_ secretsmanager.Reader,
497+
secretsReader secretsmanager.Reader,
482498
_ map[string]string,
483499
) (map[string]any, error) {
484500
// Decode providerConfig
@@ -493,7 +509,7 @@ func (vp *valuesProvider) GetControlPlaneShootChartValues(
493509
if err != nil {
494510
return nil, err
495511
}
496-
return vp.getControlPlaneShootChartValues(ctx, cpConfig, cp, cloudProfileConfig, cluster)
512+
return vp.getControlPlaneShootChartValues(ctx, cpConfig, cp, cloudProfileConfig, cluster, secretsReader)
497513
}
498514

499515
// GetStorageClassesChartValues returns the values for the shoot storageclasses chart applied by the generic actuator.
@@ -708,6 +724,11 @@ func (vp *valuesProvider) getControlPlaneChartValues(ctx context.Context, cpConf
708724
}
709725
}
710726

727+
podIdentityWebhook, err := getSTACKITPodIdentityWebhookChartValues(cluster, secretsReader, scaledDown)
728+
if err != nil {
729+
return nil, err
730+
}
731+
711732
storageCSIDriver := getCSIDriver(cpConfig)
712733
switch storageCSIDriver {
713734
case stackitv1alpha1.OPENSTACK:
@@ -732,6 +753,7 @@ func (vp *valuesProvider) getControlPlaneChartValues(ctx context.Context, cpConf
732753
},
733754
openstack.CloudControllerManagerName: ccm,
734755
openstack.STACKITCloudControllerManagerName: stackitccm,
756+
stackit.STACKITPodIdentityWebhookName: podIdentityWebhook,
735757
})
736758

737759
if vp.deployALBIngressController {
@@ -1028,7 +1050,7 @@ func DeploySTACKITALB(cpConfig *stackitv1alpha1.ControlPlaneConfig) bool {
10281050
}
10291051

10301052
// getControlPlaneShootChartValues collects and returns the control plane shoot chart values.
1031-
func (vp *valuesProvider) getControlPlaneShootChartValues(ctx context.Context, cpConfig *stackitv1alpha1.ControlPlaneConfig, cp *extensionsv1alpha1.ControlPlane, cloudProfileConfig *stackitv1alpha1.CloudProfileConfig, cluster *extensionscontroller.Cluster) (map[string]any, error) {
1053+
func (vp *valuesProvider) getControlPlaneShootChartValues(ctx context.Context, cpConfig *stackitv1alpha1.ControlPlaneConfig, cp *extensionsv1alpha1.ControlPlane, cloudProfileConfig *stackitv1alpha1.CloudProfileConfig, cluster *extensionscontroller.Cluster, secretsReader secretsmanager.Reader) (map[string]any, error) {
10321054
var csiNodeDriverValues map[string]any
10331055

10341056
values := make(map[string]any)
@@ -1056,8 +1078,14 @@ func (vp *valuesProvider) getControlPlaneShootChartValues(ctx context.Context, c
10561078
return nil, err
10571079
}
10581080

1081+
podIdentityWebhook, err := vp.getSTACKITPodIdentityWebhookShootChartValues(secretsReader)
1082+
if err != nil {
1083+
return nil, err
1084+
}
1085+
10591086
maps.Copy(values, map[string]any{
1060-
openstack.CloudControllerManagerName: map[string]any{"enabled": true},
1087+
openstack.CloudControllerManagerName: map[string]any{"enabled": true},
1088+
stackit.STACKITPodIdentityWebhookName: podIdentityWebhook,
10611089
})
10621090

10631091
return values, nil
@@ -1225,16 +1253,6 @@ func (vp *valuesProvider) getControlPlaneShootChartCSISTACKITValues(ctx context.
12251253
return values
12261254
}
12271255

1228-
func (vp *valuesProvider) getAllWorkerPoolsZones(cluster *extensionscontroller.Cluster) []string {
1229-
zones := sets.NewString()
1230-
for _, worker := range cluster.Shoot.Spec.Provider.Workers {
1231-
zones.Insert(worker.Zones...)
1232-
}
1233-
list := zones.UnsortedList()
1234-
sort.Strings(list)
1235-
return list
1236-
}
1237-
12381256
func cleanupSeedLegacyCSISnapshotValidation(ctx context.Context, client k8sclient.Client, namespace string) error {
12391257
stackitSnapShotName := fmt.Sprintf("%s-%s", CSIStackitPrefix, openstack.CSISnapshotValidationName)
12401258

@@ -1276,3 +1294,36 @@ func cleanupCloudProviderConfigSecret(ctx context.Context, client k8sclient.Clie
12761294

12771295
return nil
12781296
}
1297+
1298+
func getSTACKITPodIdentityWebhookChartValues(
1299+
cluster *extensionscontroller.Cluster,
1300+
secretsReader secretsmanager.Reader,
1301+
scaledDown bool,
1302+
) (map[string]any, error) {
1303+
tlsSecret, found := secretsReader.Get(stackitPodIdentityWebhookServerName)
1304+
if !found {
1305+
return nil, fmt.Errorf("secret %q not found", stackitPodIdentityWebhookServerName)
1306+
}
1307+
1308+
return map[string]any{
1309+
"replicaCount": extensionscontroller.GetControlPlaneReplicas(cluster, scaledDown, 2),
1310+
"webhook": map[string]any{
1311+
"tlsSecretName": tlsSecret.Name,
1312+
},
1313+
}, nil
1314+
}
1315+
1316+
func (vp *valuesProvider) getSTACKITPodIdentityWebhookShootChartValues(
1317+
secretsReader secretsmanager.Reader,
1318+
) (map[string]any, error) {
1319+
caSecret, found := secretsReader.Get(caNameControlPlane)
1320+
if !found {
1321+
return nil, fmt.Errorf("secret %q not found", caNameControlPlane)
1322+
}
1323+
1324+
return map[string]any{
1325+
"webhook": map[string]any{
1326+
"caBundle": gardenerutils.EncodeBase64(caSecret.Data[secretutils.DataKeyCertificateBundle]),
1327+
},
1328+
}, nil
1329+
}

pkg/stackit/types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ const (
1616
EtherTypeIPv6 = "IPv6"
1717
DirectionEgress = "egress"
1818
DirectionIngress = "ingress"
19+
20+
// STACKITPodIdentityWebhookName is a constant for the name of the Pod Identity Webhook. (stackit)
21+
STACKITPodIdentityWebhookName = "stackit-pod-identity-webhook"
1922
)
2023

2124
var (

0 commit comments

Comments
 (0)