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

Commit ffeea76

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 ffeea76

File tree

11 files changed

+349
-213
lines changed

11 files changed

+349
-213
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/ccm/aws/handler.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,13 @@ func (a *AWSCCM) Apply(
9696
)
9797
}
9898

99-
err = lifecycleutils.EnsureCRSForClusterFromObjects(ctx, ccmConfigMap.Name, a.client, cluster, ccmConfigMap)
99+
err = lifecycleutils.EnsureCRSForClusterFromObjects(
100+
ctx,
101+
ccmConfigMap.Name,
102+
a.client,
103+
cluster,
104+
ccmConfigMap,
105+
)
100106
if err != nil {
101107
return fmt.Errorf("failed to generate CCM CRS for cluster: %w", err)
102108
}

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

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

24+
var defaultStorageClassParams = map[string]string{
25+
"csi.storage.k8s.io/fstype": "ext4",
26+
"type": "gp3",
27+
}
28+
2429
type AWSEBSConfig struct {
2530
*options.GlobalOptions
2631
defaultAWSEBSConfigMapName string
@@ -81,14 +86,14 @@ func (a *AWSEBS) createStorageClasses(ctx context.Context,
8186
defaultStorageConfig *v1alpha1.DefaultStorage,
8287
) error {
8388
allStorageClasses := make([]runtime.Object, 0, len(configs))
84-
for _, c := range configs {
85-
setAsDefault := c.Name == defaultStorageConfig.StorageClassConfigName &&
89+
for _, config := range configs {
90+
setAsDefault := config.Name == defaultStorageConfig.StorageClassConfigName &&
8691
v1alpha1.CSIProviderAWSEBS == defaultStorageConfig.ProviderName
8792
allStorageClasses = append(allStorageClasses, lifecycleutils.CreateStorageClass(
88-
c,
89-
a.config.GlobalOptions.DefaultsNamespace(),
93+
config,
9094
v1alpha1.AWSEBSProvisioner,
9195
setAsDefault,
96+
defaultStorageClassParams,
9297
))
9398
}
9499
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: 53 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,16 +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"
3539
)
3640

41+
var defaultStorageClassParameters = map[string]string{
42+
"storageType": "NutanixVolumes",
43+
"csi.storage.k8s.io/fstype": "xfs",
44+
"csi.storage.k8s.io/provisioner-secret-name": defaultCredentialsSecretName,
45+
"csi.storage.k8s.io/provisioner-secret-namespace": defaultStorageHelmReleaseNamespace,
46+
"csi.storage.k8s.io/node-publish-secret-name": defaultCredentialsSecretName,
47+
"csi.storage.k8s.io/node-publish-secret-namespace": defaultStorageHelmReleaseNamespace,
48+
"csi.storage.k8s.io/controller-expand-secret-name": defaultCredentialsSecretName,
49+
"csi.storage.k8s.io/controller-expand-secret-namespace": defaultStorageHelmReleaseNamespace,
50+
}
51+
3752
type NutanixCSIConfig struct {
3853
*options.GlobalOptions
3954
defaultValuesTemplateConfigMapName string
@@ -80,42 +95,38 @@ func (n *NutanixCSI) Apply(
8095
default:
8196
return fmt.Errorf("stategy %s not implemented", strategy)
8297
}
98+
8399
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-
},
100+
key := ctrlclient.ObjectKey{
101+
Name: defaultCredentialsSecretName,
102+
Namespace: defaultStorageHelmReleaseNamespace,
93103
}
94-
err := n.client.Get(
104+
err := lifecycleutils.CopySecretToRemoteCluster(
95105
ctx,
96-
ctrlclient.ObjectKeyFromObject(sec),
97-
sec,
98-
)
99-
if err != nil {
100-
return err
101-
}
102-
err = lifecycleutils.EnsureCRSForClusterFromObjects(
103-
ctx,
104-
fmt.Sprintf("nutanix-csi-credentials-crs-%s", req.Cluster.Name),
105106
n.client,
107+
provider.Credentials.Name,
108+
key,
106109
&req.Cluster,
107-
sec,
108110
)
109111
if err != nil {
110-
return err
112+
return fmt.Errorf(
113+
"error creating credentials Secret for the Nutanix CSI driver: %w",
114+
err,
115+
)
111116
}
112117
}
113-
return n.createStorageClasses(
118+
119+
err := n.createStorageClasses(
114120
ctx,
115121
provider.StorageClassConfig,
116122
&req.Cluster,
117123
defaultStorageConfig,
118124
)
125+
if err != nil {
126+
return fmt.Errorf("error creating StorageClasses for the Nutanix CSI driver: %w", err)
127+
}
128+
129+
return nil
119130
}
120131

121132
func (n *NutanixCSI) handleHelmAddonApply(
@@ -149,8 +160,8 @@ func (n *NutanixCSI) handleHelmAddonApply(
149160
ClusterSelector: metav1.LabelSelector{
150161
MatchLabels: map[string]string{clusterv1.ClusterNameLabel: req.Cluster.Name},
151162
},
152-
ReleaseNamespace: req.Cluster.Namespace,
153-
ReleaseName: fmt.Sprintf(defaultStorageHelmReleaseNameTemplate, req.Cluster.Name),
163+
ReleaseNamespace: defaultStorageHelmReleaseNamespace,
164+
ReleaseName: defaultStorageHelmReleaseName,
154165
Version: defaultStorageHelmChartVersion,
155166
ValuesTemplate: values,
156167
},
@@ -174,16 +185,16 @@ func (n *NutanixCSI) handleHelmAddonApply(
174185
},
175186
ObjectMeta: metav1.ObjectMeta{
176187
Namespace: req.Cluster.Namespace,
177-
Name: "nutanix-csi-snapshot" + req.Cluster.Name,
188+
Name: "nutanix-csi-snapshot-" + req.Cluster.Name,
178189
},
179190
Spec: caaphv1.HelmChartProxySpec{
180191
RepoURL: defaultHelmRepositoryURL,
181192
ChartName: defaultSnapshotHelmChartName,
182193
ClusterSelector: metav1.LabelSelector{
183194
MatchLabels: map[string]string{clusterv1.ClusterNameLabel: req.Cluster.Name},
184195
},
185-
ReleaseNamespace: req.Cluster.Namespace,
186-
ReleaseName: fmt.Sprintf(defaultSnapshotHelmReleaseNameTemplate, req.Cluster.Name),
196+
ReleaseNamespace: defaultSnapshotHelmReleaseNamespace,
197+
ReleaseName: defaultSnapshotHelmReleaseName,
187198
Version: defaultSnapshotHelmChartVersion,
188199
},
189200
}
@@ -205,20 +216,21 @@ func (n *NutanixCSI) handleHelmAddonApply(
205216
return nil
206217
}
207218

208-
func (n *NutanixCSI) createStorageClasses(ctx context.Context,
219+
func (n *NutanixCSI) createStorageClasses(
220+
ctx context.Context,
209221
configs []v1alpha1.StorageClassConfig,
210222
cluster *clusterv1.Cluster,
211223
defaultStorageConfig *v1alpha1.DefaultStorage,
212224
) error {
213225
allStorageClasses := make([]runtime.Object, 0, len(configs))
214-
for _, c := range configs {
215-
setAsDefault := c.Name == defaultStorageConfig.StorageClassConfigName &&
226+
for _, config := range configs {
227+
setAsDefault := config.Name == defaultStorageConfig.StorageClassConfigName &&
216228
v1alpha1.CSIProviderNutanix == defaultStorageConfig.ProviderName
217229
allStorageClasses = append(allStorageClasses, lifecycleutils.CreateStorageClass(
218-
c,
219-
n.config.GlobalOptions.DefaultsNamespace(),
230+
config,
220231
v1alpha1.NutanixProvisioner,
221232
setAsDefault,
233+
defaultStorageClassParameters,
222234
))
223235
}
224236
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)