Skip to content

Commit 966471a

Browse files
authored
Refactor constructing containers and support checkout certain git refs (#382)
1 parent 3536da5 commit 966471a

24 files changed

+542
-307
lines changed

controllers/process/const.go renamed to api/types/const.go

+27-17
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
1-
package process
1+
package types
22

33
const (
4-
// WorkingVolumeMountPath is the mount path for working volume
5-
WorkingVolumeMountPath = "/data"
6-
// InputTFConfigurationVolumeName is the volume name for input Terraform Configuration
7-
InputTFConfigurationVolumeName = "tf-input-configuration"
8-
// BackendVolumeName is the volume name for Terraform backend
9-
BackendVolumeName = "tf-backend"
10-
// InputTFConfigurationVolumeMountPath is the volume mount path for input Terraform Configuration
11-
InputTFConfigurationVolumeMountPath = "/opt/tf-configuration"
12-
// BackendVolumeMountPath is the volume mount path for Terraform backend
13-
BackendVolumeMountPath = "/opt/tf-backend"
4+
DefaultNamespace = "default"
145

156
GitCredsKnownHosts = "known_hosts"
16-
// Terraform credentials
7+
// TerraformCredentials -
178
TerraformCredentials = "credentials.tfrc.json"
18-
// Terraform Registry Configuration
9+
// TerraformRegistryConfig -
1910
TerraformRegistryConfig = ".terraformrc"
2011
)
2112

13+
const (
14+
// TerraformContainerName is the name of the container that executes terraform in the pod
15+
TerraformContainerName = "terraform-executor"
16+
TerraformInitContainerName = "terraform-init"
17+
)
18+
2219
const (
2320
// TFInputConfigMapName is the CM name for Terraform Input Configuration
2421
TFInputConfigMapName = "tf-%s"
@@ -43,23 +40,36 @@ const (
4340
ServiceAccountName = "tf-executor-service-account"
4441
)
4542

43+
// Volume names and mount paths
4644
const (
47-
defaultNamespace = "default"
48-
// TerraformContainerName is the name of the container that executes terraform in the pod
49-
TerraformContainerName = "terraform-executor"
50-
TerraformInitContainerName = "terraform-init"
45+
// WorkingVolumeMountPath is the mount path for working volume
46+
WorkingVolumeMountPath = "/data"
47+
48+
// InputTFConfigurationVolumeName is the volume name for input Terraform Configuration
49+
InputTFConfigurationVolumeName = "tf-input-configuration"
50+
// InputTFConfigurationVolumeMountPath is the volume mount path for input Terraform Configuration
51+
InputTFConfigurationVolumeMountPath = "/opt/tf-configuration"
52+
53+
// BackendVolumeName is the volume name for Terraform backend
54+
BackendVolumeName = "tf-backend"
55+
// BackendVolumeMountPath is the volume mount path for Terraform backend
56+
BackendVolumeMountPath = "/opt/tf-backend"
57+
5158
// GitAuthConfigVolumeName is the volume name for git auth configurtaion
5259
GitAuthConfigVolumeName = "git-auth-configuration"
5360
// GitAuthConfigVolumeMountPath is the volume mount path for git auth configurtaion
5461
GitAuthConfigVolumeMountPath = "/root/.ssh"
62+
5563
// TerraformCredentialsConfigVolumeName is the volume name for terraform auth configurtaion
5664
TerraformCredentialsConfigVolumeName = "terraform-credentials-configuration"
5765
// TerraformCredentialsConfigVolumeMountPath is the volume mount path for terraform auth configurtaion
5866
TerraformCredentialsConfigVolumeMountPath = "/root/.terraform.d"
67+
5968
// TerraformRCConfigVolumeName is the volume name of the terraform registry configuration
6069
TerraformRCConfigVolumeName = "terraform-rc-configuration"
6170
// TerraformRCConfigVolumeMountPath is the volume mount path for registry configuration
6271
TerraformRCConfigVolumeMountPath = "/root"
72+
6373
// TerraformCredentialsHelperConfigVolumeName is the volume name for terraform auth configurtaion
6474
TerraformCredentialsHelperConfigVolumeName = "terraform-credentials-helper-configuration"
6575
// TerraformCredentialsHelperConfigVolumeMountPath is the volume mount path for terraform auth configurtaion

api/types/state.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ const (
4444
type Stage string
4545

4646
const (
47-
TerraformInit Stage = "TerraformInit"
48-
TerraformApply Stage = "TerraformApply"
47+
InitStage Stage = "InitStage"
48+
ApplyStage Stage = "Apply"
4949
)
5050

5151
const (

api/types/terraform.go

+19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package types
22

3+
import "k8s.io/apimachinery/pkg/api/resource"
4+
35
const (
46
// TerraformHCLConfigurationName is the file name for Terraform hcl Configuration
57
TerraformHCLConfigurationName = "main.tf"
@@ -15,9 +17,26 @@ const (
1517
ConfigurationRemote ConfigurationType = "Remote"
1618
)
1719

20+
type Git struct {
21+
URL string
22+
Path string
23+
Ref GitRef
24+
}
25+
1826
// GitRef specifies the git reference
1927
type GitRef struct {
2028
Branch string `json:"branch,omitempty"`
2129
Tag string `json:"tag,omitempty"`
2230
Commit string `json:"commit,omitempty"`
2331
}
32+
33+
type ResourceQuota struct {
34+
ResourcesLimitsCPU string
35+
ResourcesLimitsCPUQuantity resource.Quantity
36+
ResourcesLimitsMemory string
37+
ResourcesLimitsMemoryQuantity resource.Quantity
38+
ResourcesRequestsCPU string
39+
ResourcesRequestsCPUQuantity resource.Quantity
40+
ResourcesRequestsMemory string
41+
ResourcesRequestsMemoryQuantity resource.Quantity
42+
}

api/v1beta1/zz_generated.deepcopy.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1beta2/configuration_types.go

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ type ConfigurationSpec struct {
3333
// Remote is a git repo which contains hcl files. Currently, only public git repos are supported.
3434
Remote string `json:"remote,omitempty"`
3535

36+
// GitRef is the git branch or tag or commit hash to checkout. Only used when Remote is specified.
37+
GitRef apitypes.GitRef `json:"gitRef,omitempty"`
38+
3639
// +kubebuilder:pruning:PreserveUnknownFields
3740
Variable *runtime.RawExtension `json:"variable,omitempty"`
3841

api/v1beta2/zz_generated.deepcopy.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

chart/crds/terraform.core.oam.dev_configurations.yaml

+11
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,17 @@ spec:
331331
name must be unique.
332332
type: string
333333
type: object
334+
gitRef:
335+
description: GitRef is the git branch or tag or commit hash to checkout.
336+
Only used when Remote is specified.
337+
properties:
338+
branch:
339+
type: string
340+
commit:
341+
type: string
342+
tag:
343+
type: string
344+
type: object
334345
hcl:
335346
description: HCL is the Terraform HCL type configuration
336347
type: string

controllers/configuration_controller.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func (r *ConfigurationReconciler) Reconcile(ctx context.Context, req ctrl.Reques
9999
klog.InfoS("performing Configuration Destroy", "Namespace", req.Namespace, "Name", req.Name, "JobName", meta.DestroyJobName)
100100
// if allow to delete halfway, we will not check the status of the apply job.
101101

102-
_, err := terraform.GetTerraformStatus(ctx, meta.ControllerNamespace, meta.DestroyJobName, process.TerraformContainerName, process.TerraformInitContainerName)
102+
_, err := terraform.GetTerraformStatus(ctx, meta.ControllerNamespace, meta.DestroyJobName, types.TerraformContainerName, types.TerraformInitContainerName)
103103
if err != nil {
104104
klog.ErrorS(err, "Terraform destroy failed")
105105
if updateErr := meta.UpdateDestroyStatus(ctx, r.Client, types.ConfigurationDestroyFailed, err.Error()); updateErr != nil {
@@ -151,7 +151,7 @@ func (r *ConfigurationReconciler) Reconcile(ctx context.Context, req ctrl.Reques
151151
}
152152
return ctrl.Result{RequeueAfter: 3 * time.Second}, errors.Wrap(err, "failed to create/update cloud resource")
153153
}
154-
state, err := terraform.GetTerraformStatus(ctx, meta.ControllerNamespace, meta.ApplyJobName, process.TerraformContainerName, process.TerraformInitContainerName)
154+
state, err := terraform.GetTerraformStatus(ctx, meta.ControllerNamespace, meta.ApplyJobName, types.TerraformContainerName, types.TerraformInitContainerName)
155155
if err != nil {
156156
klog.ErrorS(err, "Terraform apply failed")
157157
if updateErr := meta.UpdateApplyStatus(ctx, r.Client, state, err.Error()); updateErr != nil {
@@ -173,7 +173,7 @@ func (r *ConfigurationReconciler) terraformApply(ctx context.Context, configurat
173173

174174
if err := meta.GetApplyJob(ctx, k8sClient, &tfExecutionJob); err != nil {
175175
if kerrors.IsNotFound(err) {
176-
return meta.AssembleAndTriggerJob(ctx, k8sClient, process.TerraformApply)
176+
return meta.AssembleAndTriggerJob(ctx, k8sClient, types.TerraformApply)
177177
}
178178
}
179179
klog.InfoS("terraform apply job", "Namespace", tfExecutionJob.Namespace, "Name", tfExecutionJob.Name)
@@ -229,7 +229,7 @@ func (r *ConfigurationReconciler) terraformDestroy(ctx context.Context, configur
229229
if err := k8sClient.Get(ctx, client.ObjectKey{Name: meta.DestroyJobName, Namespace: meta.ControllerNamespace}, &destroyJob); err != nil {
230230
if kerrors.IsNotFound(err) {
231231
if err := r.Client.Get(ctx, client.ObjectKey{Name: configuration.Name, Namespace: configuration.Namespace}, &v1beta2.Configuration{}); err == nil {
232-
if err = meta.AssembleAndTriggerJob(ctx, k8sClient, process.TerraformDestroy); err != nil {
232+
if err = meta.AssembleAndTriggerJob(ctx, k8sClient, types.TerraformDestroy); err != nil {
233233
return err
234234
}
235235
}
@@ -480,7 +480,7 @@ func (r *ConfigurationReconciler) preCheck(ctx context.Context, configuration *v
480480
return err
481481
}
482482

483-
return util.CreateTerraformExecutorClusterRole(ctx, k8sClient, fmt.Sprintf("%s-%s", meta.ControllerNamespace, process.ClusterRoleName))
483+
return util.CreateTerraformExecutorClusterRole(ctx, k8sClient, fmt.Sprintf("%s-%s", meta.ControllerNamespace, types.ClusterRoleName))
484484
}
485485

486486
// SetupWithManager setups with a manager

controllers/configuration_controller_test.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ func TestConfigurationReconcile(t *testing.T) {
130130

131131
applyingJob2 := &batchv1.Job{
132132
ObjectMeta: metav1.ObjectMeta{
133-
Name: req.Name + "-" + string(process.TerraformApply),
133+
Name: req.Name + "-" + string(types.TerraformApply),
134134
Namespace: req.Namespace,
135135
},
136136
Status: batchv1.JobStatus{
@@ -153,7 +153,7 @@ func TestConfigurationReconcile(t *testing.T) {
153153

154154
variableSecret := &corev1.Secret{
155155
ObjectMeta: metav1.ObjectMeta{
156-
Name: fmt.Sprintf(process.TFVariableSecret, req.Name),
156+
Name: fmt.Sprintf(types.TFVariableSecret, req.Name),
157157
Namespace: req.Namespace,
158158
},
159159
Data: map[string][]byte{
@@ -306,7 +306,7 @@ terraform {
306306
varMap := map[string]string{"name": "abc"}
307307
appliedEnvVariable := &corev1.Secret{
308308
ObjectMeta: metav1.ObjectMeta{
309-
Name: fmt.Sprintf(process.TFVariableSecret, req.Name),
309+
Name: fmt.Sprintf(types.TFVariableSecret, req.Name),
310310
Namespace: req.Namespace,
311311
},
312312
Data: map[string][]byte{
@@ -318,7 +318,7 @@ terraform {
318318
},
319319
Type: corev1.SecretTypeOpaque,
320320
}
321-
appliedJobName := req.Name + "-" + string(process.TerraformApply)
321+
appliedJobName := req.Name + "-" + string(types.TerraformApply)
322322
appliedJob := &batchv1.Job{
323323
ObjectMeta: metav1.ObjectMeta{
324324
Name: appliedJobName,
@@ -1165,7 +1165,7 @@ func TestTerraformDestroy(t *testing.T) {
11651165
}
11661166
baseVariableSecret := &corev1.Secret{
11671167
ObjectMeta: metav1.ObjectMeta{
1168-
Name: fmt.Sprintf(process.TFVariableSecret, secretSuffix),
1168+
Name: fmt.Sprintf(types.TFVariableSecret, secretSuffix),
11691169
Namespace: controllerNamespace,
11701170
},
11711171
Type: corev1.SecretTypeOpaque,
@@ -1197,7 +1197,7 @@ func TestTerraformDestroy(t *testing.T) {
11971197
Name: baseProvider.Name,
11981198
Namespace: baseProvider.Namespace,
11991199
},
1200-
VariableSecretName: fmt.Sprintf(process.TFVariableSecret, secretSuffix),
1200+
VariableSecretName: fmt.Sprintf(types.TFVariableSecret, secretSuffix),
12011201
ConfigurationCMName: configurationCMName,
12021202
// True is default value if user ignores configuration.Spec.DeleteResource
12031203
DeleteResource: true,
@@ -1208,7 +1208,7 @@ func TestTerraformDestroy(t *testing.T) {
12081208
ApplyJobName: applyJobName,
12091209
DestroyJobName: destroyJobName,
12101210
ConfigurationCMName: configurationCMName,
1211-
VariableSecretName: fmt.Sprintf(process.TFVariableSecret, secretSuffix),
1211+
VariableSecretName: fmt.Sprintf(types.TFVariableSecret, secretSuffix),
12121212
}
12131213

12141214
metaWithDeleteResourceIsFalse := baseMeta
+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package container
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/oam-dev/terraform-controller/api/types"
7+
v1 "k8s.io/api/core/v1"
8+
"k8s.io/apimachinery/pkg/api/resource"
9+
)
10+
11+
func (a *Assembler) ApplyContainer(executionType types.TerraformExecutionType, resourceQuota types.ResourceQuota) v1.Container {
12+
13+
c := v1.Container{
14+
Name: types.TerraformContainerName,
15+
Image: a.TerraformImage,
16+
ImagePullPolicy: v1.PullIfNotPresent,
17+
Command: []string{
18+
"bash",
19+
"-c",
20+
fmt.Sprintf("terraform %s -lock=false -auto-approve", executionType),
21+
},
22+
VolumeMounts: []v1.VolumeMount{
23+
{
24+
Name: a.Name,
25+
MountPath: types.WorkingVolumeMountPath,
26+
},
27+
{
28+
Name: types.InputTFConfigurationVolumeName,
29+
MountPath: types.InputTFConfigurationVolumeMountPath,
30+
},
31+
},
32+
Env: a.Envs,
33+
}
34+
35+
if resourceQuota.ResourcesLimitsCPU != "" || resourceQuota.ResourcesLimitsMemory != "" ||
36+
resourceQuota.ResourcesRequestsCPU != "" || resourceQuota.ResourcesRequestsMemory != "" {
37+
resourceRequirements := v1.ResourceRequirements{}
38+
if resourceQuota.ResourcesLimitsCPU != "" || resourceQuota.ResourcesLimitsMemory != "" {
39+
resourceRequirements.Limits = map[v1.ResourceName]resource.Quantity{}
40+
if resourceQuota.ResourcesLimitsCPU != "" {
41+
resourceRequirements.Limits["cpu"] = resourceQuota.ResourcesLimitsCPUQuantity
42+
}
43+
if resourceQuota.ResourcesLimitsMemory != "" {
44+
resourceRequirements.Limits["memory"] = resourceQuota.ResourcesLimitsMemoryQuantity
45+
}
46+
}
47+
if resourceQuota.ResourcesRequestsCPU != "" || resourceQuota.ResourcesLimitsMemory != "" {
48+
resourceRequirements.Requests = map[v1.ResourceName]resource.Quantity{}
49+
if resourceQuota.ResourcesRequestsCPU != "" {
50+
resourceRequirements.Requests["cpu"] = resourceQuota.ResourcesRequestsCPUQuantity
51+
}
52+
if resourceQuota.ResourcesRequestsMemory != "" {
53+
resourceRequirements.Requests["memory"] = resourceQuota.ResourcesRequestsMemoryQuantity
54+
}
55+
}
56+
c.Resources = resourceRequirements
57+
}
58+
59+
return c
60+
}

0 commit comments

Comments
 (0)