Skip to content

Commit e6eedb0

Browse files
committed
WIP: Default cloud.conf if no configmap is found
Signed-off-by: Nolan Brubaker <[email protected]>
1 parent 86f8c6d commit e6eedb0

File tree

4 files changed

+35
-52
lines changed

4 files changed

+35
-52
lines changed

pkg/cloud/aws/aws_config_transformer.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,15 @@ func CloudConfigTransformer(source string, infra *configv1.Infrastructure, netwo
2727
}
2828

2929
func readAWSConfig(source string) (*awsconfig.CloudConfig, error) {
30+
cfg := &awsconfig.CloudConfig{}
31+
32+
// There are cases in which a cloud config was not installed with a cluster, and this is valid.
33+
// We'll want to return the cloud config to be modified for OpenShift defaults in that case.
3034
if len(source) == 0 {
31-
return nil, fmt.Errorf("empty INI file")
35+
return cfg, nil
3236
}
3337

3438
// Use the same method the AWS CCM uses to load configuration.
35-
cfg := &awsconfig.CloudConfig{}
3639
if err := gcfg.FatalOnly(gcfg.ReadStringInto(cfg, source)); err != nil {
3740
return nil, fmt.Errorf("failed to parse INI file: %w", err)
3841
}

pkg/cloud/cloud.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ import (
2525
// consumer of the transformer.
2626
type cloudConfigTransformer func(source string, infra *configv1.Infrastructure, network *configv1.Network) (string, error)
2727

28+
// defaultCloudConfig returns a default cloud configuration in the event that a cluster does not have a source config map.
29+
// Clusters created prior to 4.14 do not always have a source config map.
30+
type defaultCloudConfig func(platform configv1.PlatformType) (string, error)
31+
2832
// GetCloudConfigTransformer returns the function that should be used to transform
2933
// the cloud configuration config map, and a boolean to indicate if the config should
3034
// be synced from the CCO namespace before applying the transformation.

pkg/controllers/cloud_config_sync_controller.go

Lines changed: 16 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -55,21 +55,6 @@ func (r *CloudConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
5555
return ctrl.Result{}, err
5656
}
5757

58-
syncNeeded, err := r.isCloudConfigSyncNeeded(infra.Status.PlatformStatus, infra.Spec.CloudConfig)
59-
if err != nil {
60-
if err := r.setDegradedCondition(ctx); err != nil {
61-
return ctrl.Result{}, fmt.Errorf("failed to set conditions for cloud config controller: %v", err)
62-
}
63-
return ctrl.Result{}, err
64-
}
65-
if !syncNeeded {
66-
if err := r.setAvailableCondition(ctx); err != nil {
67-
return ctrl.Result{}, fmt.Errorf("failed to set conditions for cloud config controller: %v", err)
68-
}
69-
klog.Infof("cloud-config sync is not needed, returning early")
70-
return ctrl.Result{}, nil
71-
}
72-
7358
cloudConfigTransformerFn, needsManagedConfigLookup, err := cloud.GetCloudConfigTransformer(infra.Status.PlatformStatus)
7459
if err != nil {
7560
klog.Errorf("unable to get cloud config transformer function; unsupported platform")
@@ -113,15 +98,20 @@ func (r *CloudConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
11398
Name: infra.Spec.CloudConfig.Name,
11499
Namespace: OpenshiftConfigNamespace,
115100
}
116-
if err := r.Get(ctx, openshiftUnmanagedCMKey, sourceCM); err != nil {
101+
if err := r.Get(ctx, openshiftUnmanagedCMKey, sourceCM); err == nil {
102+
return ctrl.Result{}, err
103+
} else if errors.IsNotFound(err) {
104+
klog.Warningf("unmanaged cloud-config is not found, falling back to default cloud config.")
105+
} else {
117106
klog.Errorf("unable to get cloud-config for sync")
118107
if err := r.setDegradedCondition(ctx); err != nil {
119108
return ctrl.Result{}, fmt.Errorf("failed to set conditions for cloud config controller: %v", err)
120109
}
121-
return ctrl.Result{}, err
122110
}
123111
}
124112

113+
klog.Infof("PAST NOT FOUND")
114+
125115
sourceCM, err = r.prepareSourceConfigMap(sourceCM, infra)
126116
if err != nil {
127117
if err := r.setDegradedCondition(ctx); err != nil {
@@ -130,6 +120,8 @@ func (r *CloudConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
130120
return ctrl.Result{}, err
131121
}
132122

123+
klog.Infof("PAST PREPARE")
124+
133125
if cloudConfigTransformerFn != nil {
134126
// We ignore stuff in sourceCM.BinaryData. This isn't allowed to
135127
// contain any key that overlaps with those found in sourceCM.Data and
@@ -144,6 +136,8 @@ func (r *CloudConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
144136
sourceCM.Data[defaultConfigKey] = output
145137
}
146138

139+
klog.Infof("PAST TRANSFORM")
140+
147141
targetCM := &corev1.ConfigMap{}
148142
targetConfigMapKey := client.ObjectKey{
149143
Namespace: r.ManagedNamespace,
@@ -183,27 +177,6 @@ func (r *CloudConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
183177
return ctrl.Result{}, nil
184178
}
185179

186-
func (r *CloudConfigReconciler) isCloudConfigSyncNeeded(platformStatus *configv1.PlatformStatus, infraCloudConfigRef configv1.ConfigMapFileReference) (bool, error) {
187-
if platformStatus == nil {
188-
return false, fmt.Errorf("platformStatus is required")
189-
}
190-
switch platformStatus.Type {
191-
case configv1.AzurePlatformType,
192-
configv1.GCPPlatformType,
193-
configv1.VSpherePlatformType,
194-
configv1.IBMCloudPlatformType,
195-
configv1.PowerVSPlatformType,
196-
configv1.OpenStackPlatformType,
197-
configv1.NutanixPlatformType:
198-
return true, nil
199-
case configv1.AWSPlatformType:
200-
// Some of AWS regions might require to sync a cloud-config, in such case reference in infra resource will be presented
201-
return infraCloudConfigRef.Name != "", nil
202-
default:
203-
return false, nil
204-
}
205-
}
206-
207180
func (r *CloudConfigReconciler) prepareSourceConfigMap(source *corev1.ConfigMap, infra *configv1.Infrastructure) (*corev1.ConfigMap, error) {
208181
// Keys might be different between openshift-config/cloud-config and openshift-config-managed/kube-cloud-config
209182
// Always use "cloud.conf" which is default one across openshift
@@ -218,10 +191,11 @@ func (r *CloudConfigReconciler) prepareSourceConfigMap(source *corev1.ConfigMap,
218191
delete(cloudConfCm.Data, infraConfigKey)
219192
return cloudConfCm, nil
220193
}
221-
return nil, fmt.Errorf(
222-
"key %s specified in infra resource does not found in source configmap %s",
223-
infraConfigKey, client.ObjectKeyFromObject(source),
224-
)
194+
195+
// If there was no relevant data in the configmap, make a default entry for it.
196+
cloudConfCm.Data[defaultConfigKey] = ""
197+
198+
return cloudConfCm, nil
225199
}
226200

227201
func (r *CloudConfigReconciler) isCloudConfigEqual(source *corev1.ConfigMap, target *corev1.ConfigMap) bool {

pkg/controllers/cloud_config_sync_controller_test.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,14 @@ var _ = Describe("prepareSourceConfigMap reconciler method", func() {
151151
Expect(reconciler.isCloudConfigEqual(preparedConfig, managedCloudConfig)).Should(BeTrue())
152152
})
153153

154-
It("config preparation should fail if key from infra resource does not found", func() {
155-
brokenInfraConfig := infraCloudConfig.DeepCopy()
156-
brokenInfraConfig.Data = map[string]string{"hehehehehe": "bar"}
157-
_, err := reconciler.prepareSourceConfigMap(brokenInfraConfig, infra)
158-
Expect(err).Should(Not(Succeed()))
159-
Expect(err.Error()).Should(BeEquivalentTo("key foo specified in infra resource does not found in source configmap openshift-config/test-config"))
154+
It("config preparation should create required key if key isn't found in infrastructure", func() {
155+
infraConfig := infraCloudConfig.DeepCopy()
156+
infraConfig.Data = map[string]string{"hehehehehe": "bar"}
157+
preparedConfig, err := reconciler.prepareSourceConfigMap(infraConfig, infra)
158+
Expect(err).Should(Succeed())
159+
_, ok := preparedConfig.Data[defaultConfigKey]
160+
Expect(ok).Should(BeTrue())
161+
Expect(len(preparedConfig.Data[defaultConfigKey])).Should(BeEquivalentTo(0))
160162
})
161163

162164
It("config preparation should not touch extra fields in infra ConfigMap", func() {
@@ -467,7 +469,7 @@ var _ = Describe("Cloud config sync reconciler", func() {
467469
Expect(cl.Create(ctx, makeInfraCloudConfig(configv1.AWSPlatformType))).To(Succeed())
468470
})
469471

470-
It("should skip config sync for AWS platform if there is no reference in infra resource", func() {
472+
It("should sync for a default config AWS platform if there is no reference in infra resource", func() {
471473
infraResource := makeInfrastructureResource(configv1.AWSPlatformType)
472474
infraResource.Spec.CloudConfig.Name = ""
473475
Expect(cl.Create(ctx, infraResource)).To(Succeed())
@@ -481,7 +483,7 @@ var _ = Describe("Cloud config sync reconciler", func() {
481483
allCMs := &corev1.ConfigMapList{}
482484
Expect(cl.List(ctx, allCMs, &client.ListOptions{Namespace: targetNamespaceName})).To(Succeed())
483485

484-
Expect(len(allCMs.Items)).To(BeZero())
486+
Expect(len(allCMs.Items)).To(BeEquivalentTo(1))
485487
})
486488

487489
It("should perform config sync for AWS platform if there is a reference in infra resource", func() {

0 commit comments

Comments
 (0)