diff --git a/deploy/crds/tf.galleybytes.com_terraforms_crd.yaml b/deploy/crds/tf.galleybytes.com_terraforms_crd.yaml
index 48056fa..8ee65d7 100644
--- a/deploy/crds/tf.galleybytes.com_terraforms_crd.yaml
+++ b/deploy/crds/tf.galleybytes.com_terraforms_crd.yaml
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.9.2
- creationTimestamp: null
+ controller-gen.kubebuilder.io/version: v0.12.0
name: terraforms.tf.galleybytes.com
spec:
group: tf.galleybytes.com
@@ -223,6 +222,13 @@ spec:
Defaults to Always if :latest tag is specified, or IfNotPresent
otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images'
type: string
+ must:
+ description: "Must is short for \"must succeed to generate sidecar
+ spec\". Generation of spec does not guarantee correctness.
+ Must will only be applied to sidecars. \n If must is false
+ and the sidecar spec fails to generate, the sidecar addition
+ will be omitted."
+ type: boolean
task:
description: Task is the second part of a two-part selector
of when the plugin gets run in the workflow. This should correspond
@@ -234,7 +240,9 @@ spec:
of \n - At
to run at the same time as the defined
task \n - After
to run after the defined task
has completed. \n - Sidecar
to run as a sidecar
- for the given task."
+ for the given task. Since sidecars run in the same pod as
+ a \"main workflow\" task, failed sidecars will cause a failure
+ in the workflow."
type: string
required:
- image
diff --git a/pkg/apis/tf/v1beta1/terraform_types.go b/pkg/apis/tf/v1beta1/terraform_types.go
index eeb8993..2426daf 100644
--- a/pkg/apis/tf/v1beta1/terraform_types.go
+++ b/pkg/apis/tf/v1beta1/terraform_types.go
@@ -358,12 +358,19 @@ type Plugin struct {
//
// - After
to run after the defined task has completed.
//
- // - Sidecar
to run as a sidecar for the given task.
+ // - Sidecar
to run as a sidecar for the given task. Since sidecars run
+ // in the same pod as a "main workflow" task, failed sidecars will cause a failure in the workflow.
When string `json:"when"`
// Task is the second part of a two-part selector of when the plugin gets run in the workflow. This
// should correspond to one of the tfo task names.
Task TaskName `json:"task"`
+
+ // Must is short for "must succeed to generate sidecar spec". Generation of spec does not guarantee
+ // correctness. Must will only be applied to sidecars.
+ //
+ // If must is false and the sidecar spec fails to generate, the sidecar addition will be omitted.
+ Must bool `json:"must,omitempty"`
}
// TaskOption are different configuration options to be injected into task pods. Can apply to
@@ -423,7 +430,7 @@ type TaskOption struct {
// +optional
Volumes []corev1.Volume `json:"volumes,omitempty"`
- //Extra volumeMounts for task pod
+ // Extra volumeMounts for task pod
// +optional
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
}
@@ -778,11 +785,12 @@ func (s TerraformSpec) MarshalJSON() ([]byte, error) {
type Alias TerraformSpec
return json.Marshal(&struct {
*Alias
- KeepLatestPodsOnly bool `json:"keepLatestPodsOnly"`
- KeepCompletedPods bool `json:"keepCompletedPods"`
- WriteOutputsToStatus bool `json:"writeOutputsToStatus"`
- IgnoreDelete bool `json:"ignoreDelete"`
- RequireApproval bool `json:"requireApproval"`
+ KeepLatestPodsOnly bool `json:"keepLatestPodsOnly"`
+ KeepCompletedPods bool `json:"keepCompletedPods"`
+ WriteOutputsToStatus bool `json:"writeOutputsToStatus"`
+ IgnoreDelete bool `json:"ignoreDelete"`
+ RequireApproval bool `json:"requireApproval"`
+ TaskOptions []TaskOption `json:"taskOptions"`
}{
Alias: (*Alias)(&s),
KeepLatestPodsOnly: s.KeepLatestPodsOnly,
@@ -790,6 +798,7 @@ func (s TerraformSpec) MarshalJSON() ([]byte, error) {
WriteOutputsToStatus: s.WriteOutputsToStatus,
IgnoreDelete: s.IgnoreDelete,
RequireApproval: s.RequireApproval,
+ TaskOptions: s.TaskOptions,
})
}
@@ -837,6 +846,17 @@ func (s ResourceDownload) MarshalJSON() ([]byte, error) {
})
}
+func (s Plugin) MarshalJSON() ([]byte, error) {
+ type Alias Plugin
+ return json.Marshal(&struct {
+ *Alias
+ Must bool `json:"must"`
+ }{
+ Alias: (*Alias)(&s),
+ Must: s.Must,
+ })
+}
+
func init() {
SchemeBuilder.Register(&Terraform{}, &TerraformList{})
diff --git a/pkg/apis/tf/v1beta1/zz_generated.openapi.go b/pkg/apis/tf/v1beta1/zz_generated.openapi.go
index d27e300..08f83cb 100644
--- a/pkg/apis/tf/v1beta1/zz_generated.openapi.go
+++ b/pkg/apis/tf/v1beta1/zz_generated.openapi.go
@@ -362,7 +362,7 @@ func schema_pkg_apis_tf_v1beta1_Plugin(ref common.ReferenceCallback) common.Open
},
"when": {
SchemaProps: spec.SchemaProps{
- Description: "When is a keyword of a two-part selector of when the plugin gets run in the workflow. The value must be one of\n\n- At
to run at the same time as the defined task\n\n- After
to run after the defined task has completed.\n\n- Sidecar
to run as a sidecar for the given task.",
+ Description: "When is a keyword of a two-part selector of when the plugin gets run in the workflow. The value must be one of\n\n- At
to run at the same time as the defined task\n\n- After
to run after the defined task has completed.\n\n- Sidecar
to run as a sidecar for the given task. Since sidecars run in the same pod as a \"main workflow\" task, failed sidecars will cause a failure in the workflow.",
Default: "",
Type: []string{"string"},
Format: "",
@@ -376,6 +376,13 @@ func schema_pkg_apis_tf_v1beta1_Plugin(ref common.ReferenceCallback) common.Open
Format: "",
},
},
+ "must": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Must is short for \"must succeed to generate sidecar spec\". Generation of spec does not guarantee correctness. Must will only be applied to sidecars.\n\nIf must is false and the sidecar spec fails to generate, the sidecar addition will be omitted.",
+ Type: []string{"boolean"},
+ Format: "",
+ },
+ },
},
Required: []string{"image", "when", "task"},
},
diff --git a/pkg/controllers/terraform_controller.go b/pkg/controllers/terraform_controller.go
index e33549e..6ddf2fe 100644
--- a/pkg/controllers/terraform_controller.go
+++ b/pkg/controllers/terraform_controller.go
@@ -798,7 +798,16 @@ func (r *ReconcileTerraform) Reconcile(ctx context.Context, request reconcile.Re
}
case "Sidecar":
if whenTask.ID() == podType.ID() {
- runOpts.sidecarPlugins = append(runOpts.sidecarPlugins, *r.getPluginSidecarPod(ctx, reqLogger, tf, pluginTaskName, pluginConfig, globalEnvFrom))
+ pluginSidecarPod, err := r.getPluginSidecarPod(ctx, reqLogger, tf, pluginTaskName, pluginConfig, globalEnvFrom)
+ if err != nil {
+ if pluginConfig.Must {
+ reqLogger.V(1).Info(err.Error())
+ return reconcile.Result{Requeue: true}, nil
+ }
+ reqLogger.V(1).Info("Error adding sidecar plugin: %s", err.Error())
+ continue
+ }
+ runOpts.sidecarPlugins = append(runOpts.sidecarPlugins, *pluginSidecarPod)
}
}
}
@@ -1416,7 +1425,7 @@ func (r ReconcileTerraform) getPluginRunOpts(tf *tfv1beta1.Terraform, pluginTask
return pluginRunOpts
}
-func (r ReconcileTerraform) getPluginSidecarPod(ctx context.Context, logger logr.Logger, tf *tfv1beta1.Terraform, pluginTaskName tfv1beta1.TaskName, pluginConfig tfv1beta1.Plugin, globalEnvFrom []corev1.EnvFromSource) *corev1.Pod {
+func (r ReconcileTerraform) getPluginSidecarPod(ctx context.Context, logger logr.Logger, tf *tfv1beta1.Terraform, pluginTaskName tfv1beta1.TaskName, pluginConfig tfv1beta1.Plugin, globalEnvFrom []corev1.EnvFromSource) (*corev1.Pod, error) {
return r.getPluginRunOpts(tf, pluginTaskName, pluginConfig, globalEnvFrom).generatePod()
}