Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions api/v1beta1/configuration_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ type BaseConfigurationSpec struct {

// ConfigurationStatus defines the observed state of Configuration
type ConfigurationStatus struct {
// observedGeneration is the most recent generation observed for this Configuration. It corresponds to the
// Configuration's generation, which is updated on mutation by the API Server.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`

Apply ConfigurationApplyStatus `json:"apply,omitempty"`
Destroy ConfigurationDestroyStatus `json:"destroy,omitempty"`
}
Expand Down
2 changes: 1 addition & 1 deletion chart/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ name: terraform-controller
version: 0.2.8
description: A Kubernetes Terraform controller
home: https://github.com/oam-dev/terraform-controller
appVersion: "0.3.0"
appVersion: "0.3.1"
6 changes: 6 additions & 0 deletions chart/crds/terraform.core.oam.dev_configurations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ spec:
description: A ConfigurationState represents the status of a resource
type: string
type: object
observedGeneration:
description: observedGeneration is the most recent generation observed
for this Configuration. It corresponds to the Configuration's generation,
which is updated on mutation by the API Server.
format: int64
type: integer
type: object
type: object
served: true
Expand Down
52 changes: 28 additions & 24 deletions controllers/configuration_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func (r *ConfigurationReconciler) Reconcile(ctx context.Context, req ctrl.Reques

var tfExecutionJob = &batchv1.Job{}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这一块不能删除,它解决的是这个场景:
Configuration 部署过程中,job 已经完成了,状态还是 ProvisioningAndChecking,这时候删除 Configuration,状态就无法到达 Avaialable,导致状态 block,无法部署成功也无法删除。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里需要判断一下是否是当前 spec 对应的 job ,如果新的 spec 进来会后会拿到上一次的 job

if err := r.Client.Get(ctx, client.ObjectKey{Name: meta.ApplyJobName, Namespace: meta.Namespace}, tfExecutionJob); err == nil {
if tfExecutionJob.Status.Succeeded == int32(1) {
if !meta.EnvChanged && tfExecutionJob.Status.Succeeded == int32(1) {
if err := meta.updateApplyStatus(ctx, r.Client, types.Available, types.MessageCloudResourceDeployed); err != nil {
return ctrl.Result{}, err
}
Expand Down Expand Up @@ -200,6 +200,7 @@ type TFConfigurationMeta struct {
RemoteGit string
RemoteGitPath string
ConfigurationChanged bool
EnvChanged bool
ConfigurationCMName string
BackendSecretName string
ApplyJobName string
Expand Down Expand Up @@ -277,7 +278,7 @@ func (r *ConfigurationReconciler) terraformApply(ctx context.Context, namespace
return errors.Wrap(err, types.ErrUpdateTerraformApplyJob)
}

if tfExecutionJob.Status.Succeeded == int32(1) {
if !meta.EnvChanged && tfExecutionJob.Status.Succeeded == int32(1) {
if err := meta.updateApplyStatus(ctx, k8sClient, types.Available, types.MessageCloudResourceDeployed); err != nil {
return err
}
Expand Down Expand Up @@ -461,6 +462,28 @@ func (r *ConfigurationReconciler) preCheck(ctx context.Context, configuration *v
return err
}

// Check whether env changes
if err := meta.prepareTFVariables(configuration); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, I did move it to here in another pending PR.

return err
}

var variableInSecret v1.Secret
if err := k8sClient.Get(ctx, client.ObjectKey{Name: meta.VariableSecretName, Namespace: meta.Namespace}, &variableInSecret); err == nil {
for k, v := range variableInSecret.Data {
if val, ok := meta.VariableSecretData[k]; !ok || !bytes.Equal(v, val) {
meta.EnvChanged = true
klog.Info("Job's env changed")
if err := meta.updateApplyStatus(ctx, k8sClient, types.ConfigurationReloading, types.ConfigurationReloadingAsVariableChanged); err != nil {
return err
}

break
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

}
}
} else if !kerrors.IsNotFound(err) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will happen if it's not IsNotFound error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

system err or runtime err

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果 not found 在这里返回,会无法继续进行;后面会在配置变更后删除 secrets object

return err
}

// Apply ClusterRole
return createTerraformExecutorClusterRole(ctx, k8sClient, fmt.Sprintf("%s-%s", meta.Namespace, ClusterRoleName))
}
Expand All @@ -472,6 +495,7 @@ func (meta *TFConfigurationMeta) updateApplyStatus(ctx context.Context, k8sClien
State: state,
Message: message,
}
configuration.Status.ObservedGeneration = configuration.Generation
if state == types.Available {
outputs, err := meta.getTFOutputs(ctx, k8sClient, configuration)
if err != nil {
Expand Down Expand Up @@ -539,31 +563,11 @@ func (meta *TFConfigurationMeta) assembleAndTriggerJob(ctx context.Context, k8sC

// updateTerraformJob will set deletion finalizer to the Terraform job if its envs are changed, which will result in
// deleting the job. Finally, a new Terraform job will be generated
func (meta *TFConfigurationMeta) updateTerraformJobIfNeeded(ctx context.Context, k8sClient client.Client, configuration v1beta1.Configuration,
func (meta *TFConfigurationMeta) updateTerraformJobIfNeeded(ctx context.Context, k8sClient client.Client, _ v1beta1.Configuration,
job batchv1.Job) error {
if err := meta.prepareTFVariables(&configuration); err != nil {
return err
}

// check whether env changes
var variableInSecret v1.Secret
if err := k8sClient.Get(ctx, client.ObjectKey{Name: meta.VariableSecretName, Namespace: meta.Namespace}, &variableInSecret); err != nil {
return err
}

var envChanged bool
for k, v := range variableInSecret.Data {
if val, ok := meta.VariableSecretData[k]; !ok || !bytes.Equal(v, val) {
envChanged = true
klog.Info("Job's env changed")
if err := meta.updateApplyStatus(ctx, k8sClient, types.ConfigurationReloading, types.ConfigurationReloadingAsVariableChanged); err != nil {
return err
}
}
}

// if either one changes, delete the job
if envChanged || meta.ConfigurationChanged {
if meta.EnvChanged || meta.ConfigurationChanged {
klog.InfoS("about to delete job", "Name", job.Name, "Namespace", job.Namespace)
var j batchv1.Job
if err := k8sClient.Get(ctx, client.ObjectKey{Name: job.Name, Namespace: job.Namespace}, &j); err == nil {
Expand Down