From 3a1c170140b5b38fffd159a3c522efc1cb369787 Mon Sep 17 00:00:00 2001 From: Joshua Edward McLaughlin Cox Date: Tue, 2 Dec 2025 20:40:57 -0600 Subject: [PATCH] Adding svc-optional --- internal/generator/chart.go | 2 +- internal/generator/katenaryfile/main.go | 2 ++ internal/generator/labels/katenaryLabels.go | 1 + internal/generator/labels/katenaryLabelsDoc.yaml | 6 ++++++ internal/generator/service.go | 15 +++++++++++++++ internal/generator/utils.go | 8 ++++++++ 6 files changed, 33 insertions(+), 1 deletion(-) diff --git a/internal/generator/chart.go b/internal/generator/chart.go index 39289c9..e3125da 100644 --- a/internal/generator/chart.go +++ b/internal/generator/chart.go @@ -195,7 +195,7 @@ func (chart *HelmChart) generateDeployment(service types.ServiceConfig, deployme return err } - // isgnored service + // is ignored service if isIgnored(service) { logger.Info("Ignoring service ", service.Name) return nil diff --git a/internal/generator/katenaryfile/main.go b/internal/generator/katenaryfile/main.go index f8a37d7..5556fd5 100644 --- a/internal/generator/katenaryfile/main.go +++ b/internal/generator/katenaryfile/main.go @@ -34,6 +34,7 @@ type Service struct { SamePod *string `yaml:"same-pod,omitempty" json:"same-pod,omitempty" jsonschema:"title=Same Pod,description=Service that should be in the same pod"` Description *string `yaml:"description,omitempty" json:"description,omitempty" jsonschema:"title=Description,description=Description of the service that will be injected in the values.yaml file"` Ignore *bool `yaml:"ignore,omitempty" json:"ignore,omitempty" jsonschema:"title=Ignore,description=Ignore the service in the conversion"` + SvcOptional *bool `yaml:"svc-optional,omitempty" json:"svc-optional,omitempty" jsonschema:"title=SvcOptional,description=SvcOptional the service in the conversion"` Dependencies []labelstructs.Dependency `yaml:"dependencies,omitempty" json:"dependencies,omitempty" jsonschema:"title=Dependencies,description=Services that should be injected in the Chart.yaml file"` ConfigMapFiles *labelstructs.ConfigMapFiles `yaml:"configmap-files,omitempty" json:"configmap-files,omitempty" jsonschema:"title=ConfigMap Files,description=Files that should be injected as ConfigMap"` MapEnv *labelstructs.MapEnv `yaml:"map-env,omitempty" json:"map-env,omitempty" jsonschema:"title=Map Env,description=Map environment variables to another value"` @@ -94,6 +95,7 @@ func OverrideWithConfig(project *types.Project) { mustGetLabelContent(s.SamePod, labels.LabelSamePod) mustGetLabelContent(s.Description, labels.LabelDescription) mustGetLabelContent(s.Ignore, labels.LabelIgnore) + mustGetLabelContent(s.SvcOptional, labels.LabelSvcOptional) mustGetLabelContent(s.Dependencies, labels.LabelDependencies) mustGetLabelContent(s.ConfigMapFiles, labels.LabelConfigMapFiles) mustGetLabelContent(s.MapEnv, labels.LabelMapEnv) diff --git a/internal/generator/labels/katenaryLabels.go b/internal/generator/labels/katenaryLabels.go index ac8dc30..2440b39 100644 --- a/internal/generator/labels/katenaryLabels.go +++ b/internal/generator/labels/katenaryLabels.go @@ -30,6 +30,7 @@ const ( LabelSamePod Label = KatenaryLabelPrefix + "/same-pod" LabelDescription Label = KatenaryLabelPrefix + "/description" LabelIgnore Label = KatenaryLabelPrefix + "/ignore" + LabelSvcOptional Label = KatenaryLabelPrefix + "/svc-optional" LabelDependencies Label = KatenaryLabelPrefix + "/dependencies" LabelConfigMapFiles Label = KatenaryLabelPrefix + "/configmap-files" LabelCronJob Label = KatenaryLabelPrefix + "/cronjob" diff --git a/internal/generator/labels/katenaryLabelsDoc.yaml b/internal/generator/labels/katenaryLabelsDoc.yaml index 5833b3f..99854bb 100644 --- a/internal/generator/labels/katenaryLabelsDoc.yaml +++ b/internal/generator/labels/katenaryLabelsDoc.yaml @@ -183,6 +183,12 @@ example: "labels:\n {{ .KatenaryPrefix }}/ignore: \"true\"" type: "bool" +"svc-optional": + short: "Make the service optional in the resulting helm chart" + long: "Making a service optional to be exported in helm chart." + example: "labels:\n {{ .KatenaryPrefix }}/svc-optional: \"true\"" + type: "bool" + "dependencies": short: "Add Helm dependencies to the service." long: |- diff --git a/internal/generator/service.go b/internal/generator/service.go index 5a667b2..3b595f9 100644 --- a/internal/generator/service.go +++ b/internal/generator/service.go @@ -84,6 +84,7 @@ func (s *Service) Yaml() ([]byte, error) { return nil, err } + // Remove any loadBalancer lines that may have been added unintentionally. lines := []string{} for line := range strings.SplitSeq(string(y), "\n") { if regexp.MustCompile(`^\s*loadBalancer:\s*`).MatchString(line) { @@ -93,5 +94,19 @@ func (s *Service) Yaml() ([]byte, error) { } y = []byte(strings.Join(lines, "\n")) + // If the service has the label "katenary.v3/svc-optional", wrap the output + // with a Helm values conditional. + if s.service != nil && s.service.Labels != nil { + if _, ok := s.service.Labels["katenary.v3/svc-optional"]; ok { + // Ensure we have a trailing newline before appending the closing block. + content := string(y) + if !strings.HasSuffix(content, "\n") { + content += "\n" + } + content = "{{- if .Values.service.enabled }}\n" + content + "{{- end }}\n" + y = []byte(content) + } + } + return y, err } diff --git a/internal/generator/utils.go b/internal/generator/utils.go index 6150d55..7224503 100644 --- a/internal/generator/utils.go +++ b/internal/generator/utils.go @@ -83,6 +83,14 @@ func isIgnored(service types.ServiceConfig) bool { return false } +// isSvcOptionald returns true if the service is optional. +func isSvcOptional(service types.ServiceConfig) bool { + if v, ok := service.Labels[labels.LabelSvcOptional]; ok { + return v == "true" || v == "yes" || v == "1" + } + return false +} + // UnWrapTPL removes the line wrapping from a template. func UnWrapTPL(in []byte) []byte { return regexpLineWrap.ReplaceAll(in, []byte(" }}"))