Skip to content
This repository was archived by the owner on Apr 11, 2024. It is now read-only.

Commit bab3b56

Browse files
committed
fix: Nutanix CSI credentials Secret creation
The existing code created a ClusterResourceSet with the user provided Secret. However, that won't work unless that Secret has an embedded Secret in it.
1 parent b9c569c commit bab3b56

File tree

9 files changed

+342
-212
lines changed

9 files changed

+342
-212
lines changed

charts/cluster-api-runtime-extensions-nutanix/templates/csi/nutanix/manifests/helm-addon-installation.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ metadata:
88
name: '{{ .Values.hooks.csi.nutanix.helmAddonStrategy.defaultValueTemplateConfigMap.name }}'
99
data:
1010
values.yaml: |-
11+
# The Secret containing the credentials will be created by the handler.
1112
createSecret: false
13+
secretName: nutanix-csi-credentials
1214
{{- end -}}

pkg/handlers/generic/lifecycle/csi/aws-ebs/handler.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ import (
2121
"github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/options"
2222
)
2323

24+
var (
25+
defaultStorageClassParams = map[string]string{
26+
"csi.storage.k8s.io/fstype": "ext4",
27+
"type": "gp3",
28+
}
29+
)
30+
2431
type AWSEBSConfig struct {
2532
*options.GlobalOptions
2633
defaultAWSEBSConfigMapName string
@@ -81,14 +88,14 @@ func (a *AWSEBS) createStorageClasses(ctx context.Context,
8188
defaultStorageConfig *v1alpha1.DefaultStorage,
8289
) error {
8390
allStorageClasses := make([]runtime.Object, 0, len(configs))
84-
for _, c := range configs {
85-
setAsDefault := c.Name == defaultStorageConfig.StorageClassConfigName &&
91+
for _, config := range configs {
92+
setAsDefault := config.Name == defaultStorageConfig.StorageClassConfigName &&
8693
v1alpha1.CSIProviderAWSEBS == defaultStorageConfig.ProviderName
8794
allStorageClasses = append(allStorageClasses, lifecycleutils.CreateStorageClass(
88-
c,
89-
a.config.GlobalOptions.DefaultsNamespace(),
95+
config,
9096
v1alpha1.AWSEBSProvisioner,
9197
setAsDefault,
98+
defaultStorageClassParams,
9299
))
93100
}
94101
cm, err := lifecycleutils.CreateConfigMapForCRS(

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func (c *CSIHandler) AfterControlPlaneInitialized(
118118
)
119119
continue
120120
}
121-
log.Info(fmt.Sprintf("Creating csi provider %s", provider.Name))
121+
log.Info(fmt.Sprintf("Creating CSI provider %s", provider.Name))
122122
err = handler.Apply(
123123
ctx,
124124
provider,
@@ -129,11 +129,17 @@ func (c *CSIHandler) AfterControlPlaneInitialized(
129129
log.Error(
130130
err,
131131
fmt.Sprintf(
132-
"failed to create %s csi driver object.",
132+
"failed to delpoy %s CSI driver",
133133
provider.Name,
134134
),
135135
)
136136
resp.SetStatus(runtimehooksv1.ResponseStatusFailure)
137+
resp.SetMessage(
138+
fmt.Sprintf(
139+
"failed to deploy CSI driver: %v",
140+
err,
141+
),
142+
)
137143
}
138144
}
139145
}

pkg/handlers/generic/lifecycle/csi/nutanix-csi/handler.go

Lines changed: 52 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"fmt"
99

1010
"github.com/spf13/pflag"
11-
corev1 "k8s.io/api/core/v1"
1211
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1312
"k8s.io/apimachinery/pkg/runtime"
1413
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
@@ -24,14 +23,32 @@ import (
2423
)
2524

2625
const (
27-
defaultHelmRepositoryURL = "https://nutanix.github.io/helm/"
28-
defaultStorageHelmChartVersion = "v2.6.6"
29-
defaultStorageHelmChartName = "nutanix-csi-storage"
30-
defaultStorageHelmReleaseNameTemplate = "nutanix-csi-storage-%s"
31-
32-
defaultSnapshotHelmChartVersion = "v6.3.2"
33-
defaultSnapshotHelmChartName = "nutanix-csi-snapshot"
34-
defaultSnapshotHelmReleaseNameTemplate = "nutanix-csi-snapshot-%s"
26+
defaultHelmRepositoryURL = "https://nutanix.github.io/helm/"
27+
defaultStorageHelmChartVersion = "v2.6.6"
28+
defaultStorageHelmChartName = "nutanix-csi-storage"
29+
defaultStorageHelmReleaseName = "nutanix-csi-storage"
30+
defaultStorageHelmReleaseNamespace = "ntnx-system"
31+
32+
defaultSnapshotHelmChartVersion = "v6.3.2"
33+
defaultSnapshotHelmChartName = "nutanix-csi-snapshot"
34+
defaultSnapshotHelmReleaseName = "nutanix-csi-snapshot"
35+
defaultSnapshotHelmReleaseNamespace = "ntnx-system"
36+
37+
//nolint:gosec // Does not contain hard coded credentials.
38+
defaultCredentialsSecretName = "nutanix-csi-credentials"
39+
)
40+
41+
var (
42+
defaultStorageClassParameters = map[string]string{
43+
"storageType": "NutanixVolumes",
44+
"csi.storage.k8s.io/fstype": "xfs",
45+
"csi.storage.k8s.io/provisioner-secret-name": defaultCredentialsSecretName,
46+
"csi.storage.k8s.io/provisioner-secret-namespace": defaultStorageHelmReleaseNamespace,
47+
"csi.storage.k8s.io/node-publish-secret-name": defaultCredentialsSecretName,
48+
"csi.storage.k8s.io/node-publish-secret-namespace": defaultStorageHelmReleaseNamespace,
49+
"csi.storage.k8s.io/controller-expand-secret-name": defaultCredentialsSecretName,
50+
"csi.storage.k8s.io/controller-expand-secret-namespace": defaultStorageHelmReleaseNamespace,
51+
}
3552
)
3653

3754
type NutanixCSIConfig struct {
@@ -80,42 +97,35 @@ func (n *NutanixCSI) Apply(
8097
default:
8198
return fmt.Errorf("stategy %s not implemented", strategy)
8299
}
100+
83101
if provider.Credentials != nil {
84-
sec := &corev1.Secret{
85-
TypeMeta: metav1.TypeMeta{
86-
APIVersion: corev1.SchemeGroupVersion.String(),
87-
Kind: "Secret",
88-
},
89-
ObjectMeta: metav1.ObjectMeta{
90-
Namespace: provider.Credentials.Name,
91-
Name: provider.Credentials.Namespace,
92-
},
93-
}
94-
err := n.client.Get(
95-
ctx,
96-
ctrlclient.ObjectKeyFromObject(sec),
97-
sec,
98-
)
99-
if err != nil {
100-
return err
102+
key := ctrlclient.ObjectKey{
103+
Name: defaultCredentialsSecretName,
104+
Namespace: defaultStorageHelmReleaseNamespace,
101105
}
102-
err = lifecycleutils.EnsureCRSForClusterFromObjects(
106+
err := lifecycleutils.CopySecretToRemoteCluster(
103107
ctx,
104-
fmt.Sprintf("nutanix-csi-credentials-crs-%s", req.Cluster.Name),
105108
n.client,
109+
provider.Credentials.Name,
110+
key,
106111
&req.Cluster,
107-
sec,
108112
)
109113
if err != nil {
110-
return err
114+
return fmt.Errorf("error creating credentials Secret for the Nutanix CSI driver: %w", err)
111115
}
112116
}
113-
return n.createStorageClasses(
117+
118+
err := n.createStorageClasses(
114119
ctx,
115120
provider.StorageClassConfig,
116121
&req.Cluster,
117122
defaultStorageConfig,
118123
)
124+
if err != nil {
125+
return fmt.Errorf("error creating StorageClasses for the Nutanix CSI driver: %w", err)
126+
}
127+
128+
return nil
119129
}
120130

121131
func (n *NutanixCSI) handleHelmAddonApply(
@@ -149,8 +159,8 @@ func (n *NutanixCSI) handleHelmAddonApply(
149159
ClusterSelector: metav1.LabelSelector{
150160
MatchLabels: map[string]string{clusterv1.ClusterNameLabel: req.Cluster.Name},
151161
},
152-
ReleaseNamespace: req.Cluster.Namespace,
153-
ReleaseName: fmt.Sprintf(defaultStorageHelmReleaseNameTemplate, req.Cluster.Name),
162+
ReleaseNamespace: defaultStorageHelmReleaseNamespace,
163+
ReleaseName: defaultStorageHelmReleaseName,
154164
Version: defaultStorageHelmChartVersion,
155165
ValuesTemplate: values,
156166
},
@@ -174,16 +184,16 @@ func (n *NutanixCSI) handleHelmAddonApply(
174184
},
175185
ObjectMeta: metav1.ObjectMeta{
176186
Namespace: req.Cluster.Namespace,
177-
Name: "nutanix-csi-snapshot" + req.Cluster.Name,
187+
Name: "nutanix-csi-snapshot-" + req.Cluster.Name,
178188
},
179189
Spec: caaphv1.HelmChartProxySpec{
180190
RepoURL: defaultHelmRepositoryURL,
181191
ChartName: defaultSnapshotHelmChartName,
182192
ClusterSelector: metav1.LabelSelector{
183193
MatchLabels: map[string]string{clusterv1.ClusterNameLabel: req.Cluster.Name},
184194
},
185-
ReleaseNamespace: req.Cluster.Namespace,
186-
ReleaseName: fmt.Sprintf(defaultSnapshotHelmReleaseNameTemplate, req.Cluster.Name),
195+
ReleaseNamespace: defaultSnapshotHelmReleaseNamespace,
196+
ReleaseName: defaultSnapshotHelmReleaseName,
187197
Version: defaultSnapshotHelmChartVersion,
188198
},
189199
}
@@ -205,20 +215,21 @@ func (n *NutanixCSI) handleHelmAddonApply(
205215
return nil
206216
}
207217

208-
func (n *NutanixCSI) createStorageClasses(ctx context.Context,
218+
func (n *NutanixCSI) createStorageClasses(
219+
ctx context.Context,
209220
configs []v1alpha1.StorageClassConfig,
210221
cluster *clusterv1.Cluster,
211222
defaultStorageConfig *v1alpha1.DefaultStorage,
212223
) error {
213224
allStorageClasses := make([]runtime.Object, 0, len(configs))
214-
for _, c := range configs {
215-
setAsDefault := c.Name == defaultStorageConfig.StorageClassConfigName &&
225+
for _, config := range configs {
226+
setAsDefault := config.Name == defaultStorageConfig.StorageClassConfigName &&
216227
v1alpha1.CSIProviderNutanix == defaultStorageConfig.ProviderName
217228
allStorageClasses = append(allStorageClasses, lifecycleutils.CreateStorageClass(
218-
c,
219-
n.config.GlobalOptions.DefaultsNamespace(),
229+
config,
220230
v1alpha1.NutanixProvisioner,
221231
setAsDefault,
232+
defaultStorageClassParameters,
222233
))
223234
}
224235
cm, err := lifecycleutils.CreateConfigMapForCRS(
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2023 D2iQ, Inc. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package utils
5+
6+
import (
7+
storagev1 "k8s.io/api/storage/v1"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
"k8s.io/utils/ptr"
10+
11+
"github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1"
12+
)
13+
14+
const (
15+
kindStorageClass = "StorageClass"
16+
)
17+
18+
func CreateStorageClass(
19+
storageConfig v1alpha1.StorageClassConfig,
20+
provisionerName v1alpha1.StorageProvisioner,
21+
isDefault bool,
22+
defaultParameters map[string]string,
23+
) *storagev1.StorageClass {
24+
parameters := make(map[string]string)
25+
// set the defaults first so that user provided parameters can override them
26+
for k, v := range defaultParameters {
27+
parameters[k] = v
28+
}
29+
// set user provided parameters, overriding any defaults with the same key
30+
for k, v := range storageConfig.Parameters {
31+
parameters[k] = v
32+
}
33+
34+
sc := storagev1.StorageClass{
35+
TypeMeta: metav1.TypeMeta{
36+
Kind: kindStorageClass,
37+
APIVersion: storagev1.SchemeGroupVersion.String(),
38+
},
39+
ObjectMeta: metav1.ObjectMeta{
40+
Name: storageConfig.Name,
41+
},
42+
Provisioner: string(provisionerName),
43+
Parameters: parameters,
44+
VolumeBindingMode: ptr.To(storageConfig.VolumeBindingMode),
45+
ReclaimPolicy: ptr.To(storageConfig.ReclaimPolicy),
46+
AllowVolumeExpansion: ptr.To(storageConfig.AllowExpansion),
47+
}
48+
if isDefault {
49+
sc.ObjectMeta.Annotations = defaultStorageClassMap
50+
}
51+
return &sc
52+
}

0 commit comments

Comments
 (0)