Skip to content

Commit 7035d53

Browse files
committed
fix: add owner reference for secret
1 parent 5031afe commit 7035d53

File tree

3 files changed

+242
-109
lines changed

3 files changed

+242
-109
lines changed

pkg/handlers/generic/mutation/encryption/inject.go

Lines changed: 85 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@ import (
1111

1212
corev1 "k8s.io/api/core/v1"
1313
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
14+
"k8s.io/apimachinery/pkg/api/errors"
1415
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1516
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
1617
apiserverv1 "k8s.io/apiserver/pkg/apis/config/v1"
18+
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
1719
cabpkv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
1820
controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1"
1921
runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
2022
ctrl "sigs.k8s.io/controller-runtime"
2123
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
24+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
2225
"sigs.k8s.io/yaml"
2326

2427
carenv1 "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/v1alpha1"
@@ -27,7 +30,7 @@ import (
2730
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/patches/selectors"
2831
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/variables"
2932
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/utils"
30-
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/k8s/client"
33+
k8sClientUtil "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/k8s/client"
3134
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig"
3235
)
3336

@@ -40,33 +43,19 @@ const (
4043
apiServerEncryptionConfigArg = "encryption-provider-config"
4144
)
4245

43-
type Config struct {
44-
Client ctrlclient.Client
45-
AESSecretKeyGenerator TokenGenerator
46-
}
47-
4846
type encryptionPatchHandler struct {
49-
config *Config
47+
client ctrlclient.Client
48+
keyGenerator TokenGenerator
5049
variableName string
5150
variableFieldPath []string
5251
}
5352

54-
func NewPatch(config *Config) *encryptionPatchHandler {
55-
return newEncryptionPatchHandler(
56-
config,
57-
clusterconfig.MetaVariableName,
58-
VariableName)
59-
}
60-
61-
func newEncryptionPatchHandler(
62-
config *Config,
63-
variableName string,
64-
variableFieldPath ...string,
65-
) *encryptionPatchHandler {
53+
func NewPatch(client ctrlclient.Client, keyGenerator TokenGenerator) *encryptionPatchHandler {
6654
return &encryptionPatchHandler{
67-
config: config,
68-
variableName: variableName,
69-
variableFieldPath: variableFieldPath,
55+
client: client,
56+
keyGenerator: keyGenerator,
57+
variableName: clusterconfig.MetaVariableName,
58+
variableFieldPath: []string{VariableName},
7059
}
7160
}
7261

@@ -76,7 +65,7 @@ func (h *encryptionPatchHandler) Mutate(
7665
vars map[string]apiextensionsv1.JSON,
7766
holderRef runtimehooksv1.HolderReference,
7867
clusterKey ctrlclient.ObjectKey,
79-
_ mutation.ClusterGetter,
68+
clusterGetter mutation.ClusterGetter,
8069
) error {
8170
log := ctrl.LoggerFrom(ctx, "holderRef", holderRef)
8271

@@ -102,25 +91,49 @@ func (h *encryptionPatchHandler) Mutate(
10291
encryptionVariable,
10392
)
10493

94+
cluster, err := clusterGetter(ctx)
95+
if err != nil {
96+
log.Error(err, "failed to get cluster from encryption mutation handler")
97+
return err
98+
}
99+
100+
found, err := h.DefaultEncryptionSecretExists(ctx, cluster)
101+
if err != nil {
102+
log.WithValues(
103+
"defaultEncryptionSecret", defaultEncryptionSecretName(cluster.Name),
104+
).Error(err, "failed to find default encryption configuration secret")
105+
return err
106+
}
107+
// we do not rotate or override the secret keys for encryption configuration
108+
if found {
109+
log.V(5).WithValues(
110+
"defaultEncryptionSecret", defaultEncryptionSecretName(cluster.Name),
111+
).Info(
112+
"skip generating encryption configuration. Default encryption configuration secret exists",
113+
defaultEncryptionSecretName(cluster.Name))
114+
return nil
115+
}
116+
105117
return patches.MutateIfApplicable(
106118
obj, vars, &holderRef, selectors.ControlPlane(), log,
107119
func(obj *controlplanev1.KubeadmControlPlaneTemplate) error {
108120
log.WithValues(
109121
"patchedObjectKind", obj.GetObjectKind().GroupVersionKind().String(),
110122
"patchedObjectName", ctrlclient.ObjectKeyFromObject(obj),
111-
).Info("setting encryption in control plane kubeadm config template")
123+
).Info("adding encryption configuration files and API server extra args in control plane kubeadm config spec")
112124
encConfig, err := h.generateEncryptionConfiguration(encryptionVariable.Providers)
113125
if err != nil {
114126
return err
115127
}
116-
secretName, err := h.CreateEncryptionConfigurationSecret(ctx, encConfig, clusterKey)
117-
if err != nil {
128+
129+
if err := h.CreateEncryptionConfigurationSecret(ctx, encConfig, cluster); err != nil {
118130
return err
119131
}
132+
120133
// Create kubadm config file for encryption config
121134
obj.Spec.Template.Spec.KubeadmConfigSpec.Files = append(
122135
obj.Spec.Template.Spec.KubeadmConfigSpec.Files,
123-
generateEncryptionCredentialsFile(secretName))
136+
generateEncryptionCredentialsFile(cluster))
124137

125138
// set APIServer args for encryption config
126139
if obj.Spec.Template.Spec.KubeadmConfigSpec.ClusterConfiguration == nil {
@@ -136,7 +149,8 @@ func (h *encryptionPatchHandler) Mutate(
136149
})
137150
}
138151

139-
func generateEncryptionCredentialsFile(secretName string) cabpkv1.File {
152+
func generateEncryptionCredentialsFile(cluster *clusterv1.Cluster) cabpkv1.File {
153+
secretName := defaultEncryptionSecretName(cluster.Name)
140154
return cabpkv1.File{
141155
Path: encryptionConfigurationOnRemote,
142156
ContentFrom: &cabpkv1.FileSource{
@@ -155,7 +169,7 @@ func (h *encryptionPatchHandler) generateEncryptionConfiguration(
155169
// We only support encryption for "secrets" and "configmaps" using "aescbc" provider.
156170
resourceConfig, err := encryptionConfigForSecretsAndConfigMaps(
157171
providers,
158-
h.config.AESSecretKeyGenerator,
172+
h.keyGenerator,
159173
)
160174
if err != nil {
161175
return nil, err
@@ -171,39 +185,71 @@ func (h *encryptionPatchHandler) generateEncryptionConfiguration(
171185
}, nil
172186
}
173187

188+
func (h *encryptionPatchHandler) DefaultEncryptionSecretExists(
189+
ctx context.Context,
190+
cluster *clusterv1.Cluster,
191+
) (bool, error) {
192+
secretName := defaultEncryptionSecretName(cluster.Name)
193+
existingSecret := &corev1.Secret{
194+
TypeMeta: metav1.TypeMeta{
195+
APIVersion: corev1.SchemeGroupVersion.String(),
196+
Kind: "Secret",
197+
},
198+
ObjectMeta: metav1.ObjectMeta{
199+
Name: secretName,
200+
Namespace: cluster.Namespace,
201+
},
202+
}
203+
err := h.client.Get(ctx, ctrlclient.ObjectKeyFromObject(existingSecret), existingSecret)
204+
if err != nil {
205+
if errors.IsNotFound(err) {
206+
return false, nil
207+
}
208+
return false, err
209+
}
210+
return true, nil
211+
}
212+
174213
func (h *encryptionPatchHandler) CreateEncryptionConfigurationSecret(
175214
ctx context.Context,
176215
encryptionConfig *apiserverv1.EncryptionConfiguration,
177-
clusterKey ctrlclient.ObjectKey,
178-
) (string, error) {
216+
cluster *clusterv1.Cluster,
217+
) error {
179218
dataYaml, err := yaml.Marshal(encryptionConfig)
180219
if err != nil {
181-
return "", fmt.Errorf("unable to marshal encryption configuration to YAML: %w", err)
220+
return fmt.Errorf("unable to marshal encryption configuration to YAML: %w", err)
182221
}
183222

184223
secretData := map[string]string{
185224
SecretKeyForEtcdEncryption: strings.TrimSpace(string(dataYaml)),
186225
}
187-
secretName := defaultEncryptionSecretName(clusterKey.Name)
226+
secretName := defaultEncryptionSecretName(cluster.Name)
188227
encryptionConfigSecret := &corev1.Secret{
189228
TypeMeta: metav1.TypeMeta{
190-
APIVersion: "v1",
229+
APIVersion: corev1.SchemeGroupVersion.String(),
191230
Kind: "Secret",
192231
},
193232
ObjectMeta: metav1.ObjectMeta{
194233
Name: secretName,
195-
Namespace: clusterKey.Namespace,
196-
Labels: utils.NewLabels(utils.WithMove(), utils.WithClusterName(clusterKey.Name)),
234+
Namespace: cluster.Namespace,
235+
Labels: utils.NewLabels(utils.WithMove(), utils.WithClusterName(cluster.Name)),
197236
},
198237
StringData: secretData,
199238
Type: corev1.SecretTypeOpaque,
200239
}
201240

241+
if err = controllerutil.SetOwnerReference(cluster, encryptionConfigSecret, h.client.Scheme()); err != nil {
242+
return fmt.Errorf(
243+
"failed to set owner reference on encryption configuration secret: %w",
244+
err,
245+
)
246+
}
247+
202248
// We only support creating encryption config in BeforeClusterCreate hook and ensure that the keys are immutable.
203-
if err := client.Create(ctx, h.config.Client, encryptionConfigSecret); err != nil {
204-
return "", fmt.Errorf("failed to create encryption configuration secret: %w", err)
249+
if err := k8sClientUtil.Create(ctx, h.client, encryptionConfigSecret); err != nil {
250+
return fmt.Errorf("failed to create encryption configuration secret: %w", err)
205251
}
206-
return secretName, nil
252+
return nil
207253
}
208254

209255
// We only support encryption for "secrets" and "configmaps".

0 commit comments

Comments
 (0)