Skip to content

Commit 3afed4a

Browse files
caoxingmingcaoxingming
andauthored
Fix: reconcile after configuration's hcl changed (#360)
Co-authored-by: caoxingming <caoxingming@jd.com>
1 parent d2e6f21 commit 3afed4a

File tree

2 files changed

+138
-22
lines changed

2 files changed

+138
-22
lines changed

controllers/configuration_controller.go

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ func (r *ConfigurationReconciler) Reconcile(ctx context.Context, req ctrl.Reques
213213

214214
var tfExecutionJob = &batchv1.Job{}
215215
if err := meta.getApplyJob(ctx, r.Client, tfExecutionJob); err == nil {
216-
if !meta.EnvChanged && tfExecutionJob.Status.Succeeded == int32(1) {
216+
if !meta.EnvChanged && !meta.ConfigurationChanged && tfExecutionJob.Status.Succeeded == int32(1) {
217217
err = meta.updateApplyStatus(ctx, r.Client, types.Available, types.MessageCloudResourceDeployed)
218218
return ctrl.Result{}, err
219219
}
@@ -635,24 +635,20 @@ func (r *ConfigurationReconciler) preCheck(ctx context.Context, configuration *v
635635
}
636636
meta.CompleteConfiguration, meta.Backend = completeConfiguration, backendConf
637637

638+
// Check whether configuration(hcl/json) is changed
639+
if err := meta.CheckWhetherConfigurationChanges(ctx, k8sClient, configurationType); err != nil {
640+
return err
641+
}
642+
638643
if configuration.ObjectMeta.DeletionTimestamp.IsZero() {
639644
if err := meta.storeTFConfiguration(ctx, k8sClient); err != nil {
640645
return err
641646
}
642647
}
643648

644-
// Check whether configuration(hcl/json) is changed
645-
if err := meta.CheckWhetherConfigurationChanges(ctx, k8sClient, configurationType); err != nil {
646-
return err
647-
}
648-
649649
if meta.ConfigurationChanged {
650650
klog.InfoS("Configuration hanged, reloading...")
651-
if err := meta.updateApplyStatus(ctx, k8sClient, types.ConfigurationReloading, types.ConfigurationReloadingAsHCLChanged); err != nil {
652-
return err
653-
}
654-
// store configuration to ConfigMap
655-
return meta.storeTFConfiguration(ctx, k8sClient)
651+
return meta.updateApplyStatus(ctx, k8sClient, types.ConfigurationReloading, types.ConfigurationReloadingAsHCLChanged)
656652
}
657653

658654
// Check whether env changes
@@ -1462,17 +1458,17 @@ func (meta *TFConfigurationMeta) storeTFConfiguration(ctx context.Context, k8sCl
14621458

14631459
// CheckWhetherConfigurationChanges will check whether configuration is changed
14641460
func (meta *TFConfigurationMeta) CheckWhetherConfigurationChanges(ctx context.Context, k8sClient client.Client, configurationType types.ConfigurationType) error {
1465-
var cm v1.ConfigMap
1466-
if err := k8sClient.Get(ctx, client.ObjectKey{Name: meta.ConfigurationCMName, Namespace: meta.ControllerNamespace}, &cm); err != nil {
1467-
return err
1468-
}
1469-
1470-
var configurationChanged bool
14711461
switch configurationType {
14721462
case types.ConfigurationHCL:
1473-
configurationChanged = cm.Data[types.TerraformHCLConfigurationName] != meta.CompleteConfiguration
1474-
meta.ConfigurationChanged = configurationChanged
1475-
if configurationChanged {
1463+
var cm v1.ConfigMap
1464+
if err := k8sClient.Get(ctx, client.ObjectKey{Name: meta.ConfigurationCMName, Namespace: meta.ControllerNamespace}, &cm); err != nil {
1465+
if kerrors.IsNotFound(err) {
1466+
return nil
1467+
}
1468+
return err
1469+
}
1470+
meta.ConfigurationChanged = cm.Data[types.TerraformHCLConfigurationName] != meta.CompleteConfiguration
1471+
if meta.ConfigurationChanged {
14761472
klog.InfoS("Configuration HCL changed", "ConfigMap", cm.Data[types.TerraformHCLConfigurationName],
14771473
"RenderedCompletedConfiguration", meta.CompleteConfiguration)
14781474
}

controllers/configuration_controller_test.go

Lines changed: 122 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,78 @@ func TestConfigurationReconcile(t *testing.T) {
659659
WithObjects(namespace, secret, provider, configuration6).
660660
Build()
661661

662+
// for case "Configuration changed, and reconcile"
663+
appliedConfigurationCM := &corev1.ConfigMap{
664+
ObjectMeta: v1.ObjectMeta{
665+
Name: "tf-a",
666+
Namespace: req.Namespace,
667+
},
668+
Data: map[string]string{types.TerraformHCLConfigurationName: `Here is the original hcl
669+
670+
terraform {
671+
backend "kubernetes" {
672+
secret_suffix = "a"
673+
in_cluster_config = true
674+
namespace = "b"
675+
}
676+
}
677+
`,
678+
},
679+
}
680+
varMap := map[string]string{"name": "abc"}
681+
appliedEnvVariable := &corev1.Secret{
682+
ObjectMeta: metav1.ObjectMeta{
683+
Name: fmt.Sprintf(TFVariableSecret, req.Name),
684+
Namespace: req.Namespace,
685+
},
686+
Data: map[string][]byte{
687+
"TF_VAR_name": []byte(varMap["name"]),
688+
"ALICLOUD_ACCESS_KEY": []byte(ak.AccessKeyID),
689+
"ALICLOUD_SECRET_KEY": []byte(ak.AccessKeySecret),
690+
"ALICLOUD_REGION": []byte(provider.Spec.Region),
691+
"ALICLOUD_SECURITY_TOKEN": []byte(""),
692+
},
693+
Type: corev1.SecretTypeOpaque,
694+
}
695+
appliedJobName := req.Name + "-" + string(TerraformApply)
696+
appliedJob := &batchv1.Job{
697+
ObjectMeta: metav1.ObjectMeta{
698+
Name: appliedJobName,
699+
Namespace: req.Namespace,
700+
UID: "111",
701+
},
702+
Status: batchv1.JobStatus{
703+
Succeeded: int32(1),
704+
},
705+
}
706+
varData, _ := json.Marshal(varMap)
707+
configuration7 := &v1beta2.Configuration{
708+
ObjectMeta: metav1.ObjectMeta{
709+
Name: "a",
710+
Namespace: "b",
711+
},
712+
Spec: v1beta2.ConfigurationSpec{
713+
HCL: "Here is the changed hcl",
714+
Variable: &runtime.RawExtension{Raw: varData},
715+
ProviderReference: &crossplane.Reference{
716+
Name: "default",
717+
Namespace: "default",
718+
},
719+
WriteConnectionSecretToReference: &crossplane.SecretReference{
720+
Name: "db-conn",
721+
Namespace: "default",
722+
},
723+
},
724+
Status: v1beta2.ConfigurationStatus{
725+
Apply: v1beta2.ConfigurationApplyStatus{
726+
State: types.Available,
727+
},
728+
},
729+
}
730+
r7 := &ConfigurationReconciler{}
731+
r7.Client = fake.NewClientBuilder().WithScheme(s).WithObjects(secret, provider, backendSecret,
732+
appliedJob, appliedEnvVariable, appliedConfigurationCM, configuration7).Build()
733+
662734
type args struct {
663735
req reconcile.Request
664736
r *ConfigurationReconciler
@@ -726,6 +798,23 @@ func TestConfigurationReconcile(t *testing.T) {
726798
}
727799
},
728800
},
801+
{
802+
name: "Configuration changed, and reconcile",
803+
args: args{
804+
req: req,
805+
r: r7,
806+
},
807+
check: func(t *testing.T, cc client.Client) {
808+
job := &batchv1.Job{}
809+
if err = cc.Get(context.TODO(), k8stypes.NamespacedName{Name: appliedJobName, Namespace: req.Namespace}, job); err != nil {
810+
t.Error("Failed to retrieve the new job")
811+
}
812+
assert.Equal(t, job.Name, appliedJob.Name, "Not expected job name")
813+
assert.Equal(t, job.Namespace, appliedJob.Namespace, "Not expected job namespace")
814+
assert.NotEqual(t, job.UID, appliedJob.UID, "No new job created")
815+
assert.NotEqual(t, job.Status.Succeeded, appliedJob.Status.Succeeded, "Not expected job status")
816+
},
817+
},
729818
}
730819

731820
for _, tc := range testcases {
@@ -2510,10 +2599,36 @@ func TestCheckWhetherConfigurationChanges(t *testing.T) {
25102599
Namespace: "b",
25112600
ControllerNamespace: "b",
25122601
},
2513-
configurationType: "xxx",
2602+
configurationType: "HCL",
25142603
},
25152604
want: want{
2516-
errMsg: "not found",
2605+
errMsg: "",
2606+
},
2607+
},
2608+
"configuration type is remote": {
2609+
args: args{
2610+
meta: &TFConfigurationMeta{
2611+
ConfigurationCMName: "aaa",
2612+
Namespace: "b",
2613+
ControllerNamespace: "b",
2614+
},
2615+
configurationType: "Remote",
2616+
},
2617+
want: want{
2618+
errMsg: "",
2619+
},
2620+
},
2621+
"create configuration for the first time": {
2622+
args: args{
2623+
meta: &TFConfigurationMeta{
2624+
ConfigurationCMName: "aa",
2625+
Namespace: "b",
2626+
ControllerNamespace: "b",
2627+
},
2628+
configurationType: "HCL",
2629+
},
2630+
want: want{
2631+
errMsg: "",
25172632
},
25182633
},
25192634
}
@@ -2525,6 +2640,11 @@ func TestCheckWhetherConfigurationChanges(t *testing.T) {
25252640
t.Errorf("CheckWhetherConfigurationChanges() error = %v, wantErr %v", err, tc.want.errMsg)
25262641
}
25272642
}
2643+
2644+
if tc.want.errMsg == "" {
2645+
assert.Nil(t, err)
2646+
assert.False(t, tc.args.meta.ConfigurationChanged)
2647+
}
25282648
})
25292649
}
25302650
}

0 commit comments

Comments
 (0)