Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] - Adding Custom Labels #1093

Merged
merged 1 commit into from
Nov 14, 2023
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
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 }}
Copy link
Member

Choose a reason for hiding this comment

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

Oh I see what you mean about CLI parameter now 👍

{{- 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")
}
Copy link
Member

Choose a reason for hiding this comment

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

where would these errors come out, would they be surfaced to a user? Could it be better to log and silently ignore invalid values?

Copy link
Member Author

Choose a reason for hiding this comment

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

eekk .. too late :-D ..

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