Skip to content

Commit

Permalink
[FEATURE] - Adding Custom Labelling
Browse files Browse the repository at this point in the history
Adding the ability to add additional labels on the pods which run the terraform
  • Loading branch information
gambol99 committed Nov 14, 2023
1 parent 40b9bc6 commit 4e2f431
Show file tree
Hide file tree
Showing 12 changed files with 68 additions and 10 deletions.
3 changes: 3 additions & 0 deletions charts/terranetes-controller/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ spec:
{{- if .Values.controller.templates.job }}
- --job-template={{ .Values.controller.templates.job }}
{{- end }}
{{- range $key, value = Values.controller.jobLabels }}
- --job-label={{ $key }}={{ $value }}
{{- end }}
{{- if .Values.controller.webhooks.enabled }}
- --tls-ca={{ .Values.controller.webhooks.tlsAuthority }}
- --tls-dir={{ .Values.controller.webhooks.tlsDir }}
Expand Down
4 changes: 4 additions & 0 deletions charts/terranetes-controller/templates/serviceaccount.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ metadata:
name: terranetes-controller
annotations:
{{ toYaml .Values.rbac.controller.annotations | indent 4 }}
labels:
{{ toYaml .Values.rbac.controller.labels | indent 4 }}
{{- end }}
{{- if .Values.rbac.executor.create }}
---
Expand All @@ -15,4 +17,6 @@ metadata:
name: terranetes-executor
annotations:
{{ toYaml .Values.rbac.executor.annotations | indent 4 }}
labels:
{{ toYaml .Values.rbac.executor.labels | indent 4 }}
{{- end }}
2 changes: 2 additions & 0 deletions charts/terranetes-controller/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ controller:
templates:
# is the name of config map holding a override to the job template
job: ""
# a collection of labels which are added to all jobs
jobsLabels: {}
# is the image pull policy
imagePullPolicy: IfNotPresent
# indicate we create the watcher jobs in user namespace, these allow users
Expand Down
1 change: 1 addition & 0 deletions cmd/controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func main() {
flags.StringVar(&config.InfracostsImage, "infracost-image", "infracosts/infracost:latest", "The image to use for the infracosts")
flags.StringVar(&config.InfracostsSecretName, "cost-secret", "", "Name of the secret on the controller namespace containing your infracost token")
flags.StringVar(&config.JobTemplate, "job-template", "", "Name of configmap in the controller namespace containing a template for the job")
flags.StringSliceVar(&config.JobLabels, "job-label", []string{}, "A collection of key=values to add to all jobs")
flags.StringVar(&config.Namespace, "namespace", os.Getenv("KUBE_NAMESPACE"), "The namespace the controller is running in and where jobs will run")
flags.StringVar(&config.PolicyImage, "policy-image", "bridgecrew/checkov:latest", "The image to use for the policy")
flags.StringVar(&config.PreloadImage, "preload-image", fmt.Sprintf("ghcr.io/appvia/terranetes-executor:%s", version.Version), "The image to use for the preload")
Expand Down
2 changes: 2 additions & 0 deletions pkg/controller/configuration/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ type Controller struct {
InfracostsImage string
// InfracostsSecretName is the name of the secret containing the api and token
InfracostsSecretName string
// JobLabels is a collection of labels to add to the job
JobLabels map[string]string
// JobTemplate is a custom override for the template to use
JobTemplate string
// PolicyImage is the image to use for all policy / checkov jobs
Expand Down
7 changes: 4 additions & 3 deletions pkg/controller/configuration/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,10 @@ func (c *Controller) ensureTerraformDestroy(configuration *terraformv1alpha1.Con
batch := jobs.New(configuration, state.provider)
runner, err := batch.NewTerraformDestroy(jobs.Options{
AdditionalJobSecrets: state.additionalJobSecrets,
AdditionalLabels: utils.MergeStringMaps(configuration.GetLabels(), map[string]string{
terraformv1alpha1.RetryAnnotation: configuration.GetAnnotations()[terraformv1alpha1.RetryAnnotation],
}),
AdditionalLabels: utils.MergeStringMaps(
utils.MergeStringMaps(configuration.GetLabels(), map[string]string{
terraformv1alpha1.RetryAnnotation: configuration.GetAnnotations()[terraformv1alpha1.RetryAnnotation],
}), c.JobLabels),
EnableInfraCosts: c.EnableInfracosts,
ExecutorImage: c.ExecutorImage,
ExecutorSecrets: c.ExecutorSecrets,
Expand Down
11 changes: 6 additions & 5 deletions pkg/controller/configuration/ensure.go
Original file line number Diff line number Diff line change
Expand Up @@ -702,10 +702,11 @@ func (c *Controller) ensureTerraformPlan(configuration *terraformv1alpha1.Config
// @step: lets build the options to render the job
options := jobs.Options{
AdditionalJobSecrets: state.additionalJobSecrets,
AdditionalLabels: utils.MergeStringMaps(configuration.GetLabels(), map[string]string{
terraformv1alpha1.DriftAnnotation: configuration.GetAnnotations()[terraformv1alpha1.DriftAnnotation],
terraformv1alpha1.RetryAnnotation: configuration.GetAnnotations()[terraformv1alpha1.RetryAnnotation],
}),
AdditionalLabels: utils.MergeStringMaps(
utils.MergeStringMaps(configuration.GetLabels(), map[string]string{
terraformv1alpha1.DriftAnnotation: configuration.GetAnnotations()[terraformv1alpha1.DriftAnnotation],
terraformv1alpha1.RetryAnnotation: configuration.GetAnnotations()[terraformv1alpha1.RetryAnnotation],
}), c.JobLabels),
EnableInfraCosts: c.EnableInfracosts,
ExecutorImage: c.ExecutorImage,
ExecutorSecrets: c.ExecutorSecrets,
Expand Down Expand Up @@ -1137,7 +1138,7 @@ func (c *Controller) ensureTerraformApply(configuration *terraformv1alpha1.Confi
// @step: create the terraform job
runner, err := jobs.New(configuration, state.provider).NewTerraformApply(jobs.Options{
AdditionalJobSecrets: state.additionalJobSecrets,
AdditionalLabels: configuration.GetLabels(),
AdditionalLabels: utils.MergeStringMaps(configuration.GetLabels(), c.JobLabels),
EnableInfraCosts: c.EnableInfracosts,
ExecutorImage: c.ExecutorImage,
ExecutorSecrets: c.ExecutorSecrets,
Expand Down
11 changes: 11 additions & 0 deletions pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import (
"github.com/appvia/terranetes-controller/pkg/controller/revision"
"github.com/appvia/terranetes-controller/pkg/register"
"github.com/appvia/terranetes-controller/pkg/schema"
"github.com/appvia/terranetes-controller/pkg/utils"
k8sutils "github.com/appvia/terranetes-controller/pkg/utils/kubernetes"
"github.com/appvia/terranetes-controller/pkg/version"
)
Expand Down Expand Up @@ -160,6 +161,15 @@ func New(cfg *rest.Config, config Config) (*Server, error) {
return nil, fmt.Errorf("failed to add the contexts controller: %w", err)
}

jobLabels := map[string]string{}
if len(config.JobLabels) > 0 {
labels, err := utils.ToMap(config.JobLabels)
if err != nil {
return nil, fmt.Errorf("failed to parse the job labels: %w", err)
}
jobLabels = labels
}

// @step: ensure the configuration controller is enabled
if err := (&configuration.Controller{
BackendTemplate: config.BackendTemplate,
Expand All @@ -173,6 +183,7 @@ func New(cfg *rest.Config, config Config) (*Server, error) {
InfracostsImage: config.InfracostsImage,
InfracostsSecretName: config.InfracostsSecretName,
JobTemplate: config.JobTemplate,
JobLabels: jobLabels,
PolicyImage: config.PolicyImage,
TerraformImage: config.TerraformImage,
}).Add(mgr); err != nil {
Expand Down
2 changes: 2 additions & 0 deletions pkg/server/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ type Config struct {
InfracostsSecretName string
// InfracostsImage is the image to use for infracosts
InfracostsImage string
// JobLabels is a collection of labels which are added to all jobs
JobLabels []string
// JobTemplate is the name of the configmap containing a template for the jobs
JobTemplate string
// MetricsPort is the port to listen on
Expand Down
4 changes: 2 additions & 2 deletions pkg/utils/jobs/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,13 +188,13 @@ func (r *Render) createTerraformFromTemplate(options Options, stage string) (*ba
params := map[string]interface{}{
"GenerateName": fmt.Sprintf("%s-%s-", r.configuration.Name, stage),
"Namespace": options.Namespace,
"Labels": utils.MergeStringMaps(map[string]string{
"Labels": utils.MergeStringMaps(options.AdditionalLabels, map[string]string{
terraformv1alpha1.ConfigurationGenerationLabel: fmt.Sprintf("%d", r.configuration.GetGeneration()),
terraformv1alpha1.ConfigurationNameLabel: r.configuration.GetName(),
terraformv1alpha1.ConfigurationNamespaceLabel: r.configuration.GetNamespace(),
terraformv1alpha1.ConfigurationStageLabel: stage,
terraformv1alpha1.ConfigurationUIDLabel: string(r.configuration.GetUID()),
}, options.AdditionalLabels),
}),
"Provider": map[string]interface{}{
"Name": r.provider.Name,
"Namespace": r.provider.Namespace,
Expand Down
19 changes: 19 additions & 0 deletions pkg/utils/slices.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,29 @@
package utils

import (
"errors"
"sort"
"strings"
)

// ToMap converts a list of strings to a map
func ToMap(slice []string) (map[string]string, error) {
m := make(map[string]string)

for _, item := range slice {
if item == "" {
return nil, errors.New("empty string found in slice")
}
items := strings.Split(item, "=")
if len(items) != 2 {
return nil, errors.New("invalid key=value pair found in slice")
}
m[items[0]] = items[1]
}

return m, nil
}

// MaxChars returns the maximum character length of a list of strings
func MaxChars(slice string, max int) string {
switch {
Expand Down
12 changes: 12 additions & 0 deletions pkg/utils/slices_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ import (
"github.com/stretchr/testify/assert"
)

func TestToMap(t *testing.T) {
m, err := ToMap([]string{"a=b", "c=d"})
assert.NoError(t, err)
assert.Equal(t, map[string]string{"a": "b", "c": "d"}, m)
}

func TestToMapError(t *testing.T) {
m, err := ToMap([]string{"a=b", "c"})
assert.Error(t, err)
assert.Nil(t, m)
}

func TestMaxChars(t *testing.T) {
v := MaxChars("hello", 3)
assert.Equal(t, "hel", v)
Expand Down

0 comments on commit 4e2f431

Please sign in to comment.