Skip to content

Commit

Permalink
feat/merge-pod-specs (#30)
Browse files Browse the repository at this point in the history
* feat: merge pod spec with spec from repository and layer

* build: regenerate form new specs

* chore: update dependencies

* feat: merge spec manually
  • Loading branch information
spoukke authored Dec 30, 2022
1 parent b63de84 commit ed2dc74
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 18 deletions.
12 changes: 12 additions & 0 deletions api/v1alpha1/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package v1alpha1

import (
corev1 "k8s.io/api/core/v1"
)

type OverrideRunnerSpec struct {
ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
ServiceAccountName string `json:"serviceAccountName,omitempty"`
}
2 changes: 1 addition & 1 deletion api/v1alpha1/terraformlayer_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type TerraformLayerSpec struct {
Repository TerraformLayerRepository `json:"repository,omitempty"`
RemediationStrategy TerraformLayerRemediationStrategy `json:"remediationStrategy,omitempty"`
PlanOnPullRequest bool `json:"planOnPullRequest,omitempty"`
// RunnerPodTemplate corev1.PodSpec `json:"template,omitempty"`
OverrideRunnerSpec OverrideRunnerSpec `json:"overrideRunnerSpec,omitempty"`
}

type TerraformLayerRemediationStrategy struct {
Expand Down
3 changes: 2 additions & 1 deletion api/v1alpha1/terraformrepository_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ type TerraformRepositorySpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file

Repository TerraformRepositoryRepository `json:"repository,omitempty"`
Repository TerraformRepositoryRepository `json:"repository,omitempty"`
OverrideRunnerSpec OverrideRunnerSpec `json:"overrideRunnerSpec,omitempty"`
}

type TerraformRepositoryRepository struct {
Expand Down
47 changes: 42 additions & 5 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions config/crd/bases/config.terraform.padok.cloud_terraformlayers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,67 @@ spec:
properties:
branch:
type: string
overrideRunnerSpec:
properties:
imagePullSecrets:
items:
description: LocalObjectReference contains enough information
to let you locate the referenced object inside the same namespace.
properties:
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
type: string
type: object
x-kubernetes-map-type: atomic
type: array
nodeSelector:
additionalProperties:
type: string
type: object
serviceAccountName:
type: string
tolerations:
items:
description: The pod this Toleration is attached to tolerates
any taint that matches the triple <key,value,effect> using
the matching operator <operator>.
properties:
effect:
description: Effect indicates the taint effect to match.
Empty means match all taint effects. When specified, allowed
values are NoSchedule, PreferNoSchedule and NoExecute.
type: string
key:
description: Key is the taint key that the toleration applies
to. Empty means match all taint keys. If the key is empty,
operator must be Exists; this combination means to match
all values and all keys.
type: string
operator:
description: Operator represents a key's relationship to
the value. Valid operators are Exists and Equal. Defaults
to Equal. Exists is equivalent to wildcard for value,
so that a pod can tolerate all taints of a particular
category.
type: string
tolerationSeconds:
description: TolerationSeconds represents the period of
time the toleration (which must be of effect NoExecute,
otherwise this field is ignored) tolerates the taint.
By default, it is not set, which means tolerate the taint
forever (do not evict). Zero and negative values will
be treated as 0 (evict immediately) by the system.
format: int64
type: integer
value:
description: Value is the taint value the toleration matches
to. If the operator is Exists, the value should be empty,
otherwise just a regular string.
type: string
type: object
type: array
type: object
path:
type: string
planOnPullRequest:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,67 @@ spec:
spec:
description: TerraformRepositorySpec defines the desired state of TerraformRepository
properties:
overrideRunnerSpec:
properties:
imagePullSecrets:
items:
description: LocalObjectReference contains enough information
to let you locate the referenced object inside the same namespace.
properties:
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
type: string
type: object
x-kubernetes-map-type: atomic
type: array
nodeSelector:
additionalProperties:
type: string
type: object
serviceAccountName:
type: string
tolerations:
items:
description: The pod this Toleration is attached to tolerates
any taint that matches the triple <key,value,effect> using
the matching operator <operator>.
properties:
effect:
description: Effect indicates the taint effect to match.
Empty means match all taint effects. When specified, allowed
values are NoSchedule, PreferNoSchedule and NoExecute.
type: string
key:
description: Key is the taint key that the toleration applies
to. Empty means match all taint keys. If the key is empty,
operator must be Exists; this combination means to match
all values and all keys.
type: string
operator:
description: Operator represents a key's relationship to
the value. Valid operators are Exists and Equal. Defaults
to Equal. Exists is equivalent to wildcard for value,
so that a pod can tolerate all taints of a particular
category.
type: string
tolerationSeconds:
description: TolerationSeconds represents the period of
time the toleration (which must be of effect NoExecute,
otherwise this field is ignored) tolerates the taint.
By default, it is not set, which means tolerate the taint
forever (do not evict). Zero and negative values will
be treated as 0 (evict immediately) by the system.
format: int64
type: integer
value:
description: Value is the taint value the toleration matches
to. If the operator is Exists, the value should be empty,
otherwise just a regular string.
type: string
type: object
type: array
type: object
repository:
properties:
secretName:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ require (
github.com/hashicorp/hc-install v0.4.0
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/terraform-exec v0.17.3
github.com/imdario/mergo v0.3.13 // indirect
github.com/imdario/mergo v0.3.13
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
Expand Down
55 changes: 45 additions & 10 deletions internal/controllers/terraformlayer/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,22 @@ const (
)

func (r *Reconciler) getPod(layer *configv1alpha1.TerraformLayer, repository *configv1alpha1.TerraformRepository, action Action) corev1.Pod {
pod := corev1.Pod{
Spec: defaultPodSpec(r.Config, layer, repository),
}
pod.SetNamespace(layer.Namespace)
pod.SetGenerateName(fmt.Sprintf("%s-%s-", layer.Name, action))
defaultSpec := defaultPodSpec(r.Config, layer, repository)

switch action {
case PlanAction:
pod.Spec.Containers[0].Env = append(pod.Spec.Containers[0].Env, corev1.EnvVar{
defaultSpec.Containers[0].Env = append(defaultSpec.Containers[0].Env, corev1.EnvVar{
Name: "BURRITO_RUNNER_ACTION",
Value: "plan",
})
case ApplyAction:
pod.Spec.Containers[0].Env = append(pod.Spec.Containers[0].Env, corev1.EnvVar{
defaultSpec.Containers[0].Env = append(defaultSpec.Containers[0].Env, corev1.EnvVar{
Name: "BURRITO_RUNNER_ACTION",
Value: "apply",
})
}
if repository.Spec.Repository.SecretName != "" {
pod.Spec.Containers[0].Env = append(pod.Spec.Containers[0].Env, corev1.EnvVar{
defaultSpec.Containers[0].Env = append(defaultSpec.Containers[0].Env, corev1.EnvVar{
Name: "BURRITO_RUNNER_REPOSITORY_USERNAME",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Expand All @@ -46,7 +43,7 @@ func (r *Reconciler) getPod(layer *configv1alpha1.TerraformLayer, repository *co
},
},
})
pod.Spec.Containers[0].Env = append(pod.Spec.Containers[0].Env, corev1.EnvVar{
defaultSpec.Containers[0].Env = append(defaultSpec.Containers[0].Env, corev1.EnvVar{
Name: "BURRITO_RUNNER_REPOSITORY_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Expand All @@ -58,7 +55,7 @@ func (r *Reconciler) getPod(layer *configv1alpha1.TerraformLayer, repository *co
},
},
})
pod.Spec.Containers[0].Env = append(pod.Spec.Containers[0].Env, corev1.EnvVar{
defaultSpec.Containers[0].Env = append(defaultSpec.Containers[0].Env, corev1.EnvVar{
Name: "BURRITO_RUNNER_REPOSITORY_SSHPRIVATEKEY",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Expand All @@ -71,6 +68,13 @@ func (r *Reconciler) getPod(layer *configv1alpha1.TerraformLayer, repository *co
},
})
}

pod := corev1.Pod{
Spec: mergeSpecs(defaultSpec, repository.Spec.OverrideRunnerSpec, layer.Spec.OverrideRunnerSpec),
}
pod.SetNamespace(layer.Namespace)
pod.SetGenerateName(fmt.Sprintf("%s-%s-", layer.Name, action))

return pod
}

Expand Down Expand Up @@ -157,3 +161,34 @@ func defaultPodSpec(config *config.Config, layer *configv1alpha1.TerraformLayer,
},
}
}

func mergeSpecs(defaultSpec corev1.PodSpec, repositorySpec configv1alpha1.OverrideRunnerSpec, layerSpec configv1alpha1.OverrideRunnerSpec) corev1.PodSpec {
if len(repositorySpec.ImagePullSecrets) > 0 {
defaultSpec.ImagePullSecrets = repositorySpec.ImagePullSecrets
}
if len(layerSpec.ImagePullSecrets) > 0 {
defaultSpec.ImagePullSecrets = layerSpec.ImagePullSecrets
}

if len(repositorySpec.Tolerations) > 0 {
defaultSpec.Tolerations = repositorySpec.Tolerations
}
if len(layerSpec.Tolerations) > 0 {
defaultSpec.Tolerations = layerSpec.Tolerations
}

if len(repositorySpec.NodeSelector) > 0 {
defaultSpec.NodeSelector = repositorySpec.NodeSelector
}
if len(layerSpec.NodeSelector) > 0 {
defaultSpec.NodeSelector = layerSpec.NodeSelector
}

if len(repositorySpec.ServiceAccountName) > 0 {
defaultSpec.ServiceAccountName = repositorySpec.ServiceAccountName
}
if len(layerSpec.ServiceAccountName) > 0 {
defaultSpec.ServiceAccountName = layerSpec.ServiceAccountName
}
return defaultSpec
}

0 comments on commit ed2dc74

Please sign in to comment.