Skip to content

Commit

Permalink
feat(kubernetesDeploy): initial support for multiple images (SAP#3548)
Browse files Browse the repository at this point in the history
Co-authored-by: Philipp Stehle <[email protected]>
Co-authored-by: Ralf Pannemans <[email protected]>
  • Loading branch information
phil9909 and c0d1ngm0nk3y authored Feb 24, 2022
1 parent 8777fa7 commit 402b8b2
Show file tree
Hide file tree
Showing 4 changed files with 280 additions and 30 deletions.
100 changes: 82 additions & 18 deletions cmd/kubernetesDeploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,50 @@ func runHelmDeploy(config kubernetesDeployOptions, utils kubernetes.DeployUtils,
if err != nil {
log.Entry().WithError(err).Fatalf("Container registry url '%v' incorrect", config.ContainerRegistryURL)
}
//support either image or containerImageName and containerImageTag
containerImageName := ""
containerImageTag := ""

if len(config.Image) > 0 {
containerImageName, containerImageTag, err = splitFullImageName(config.Image)
if err != nil {
log.Entry().WithError(err).Fatalf("Container image '%v' incorrect", config.Image)
helmValues := helmValues{}

if len(config.ImageNames) > 0 {
if len(config.ImageNames) != len(config.ImageNameTags) {
log.SetErrorCategory(log.ErrorConfiguration)
return fmt.Errorf("number of imageNames and imageNameTags must be equal")
}
for i, key := range config.ImageNames {
name, tag, err := splitFullImageName(config.ImageNameTags[i])
if err != nil {
log.Entry().WithError(err).Fatalf("Container image '%v' incorrect", config.ImageNameTags[i])
}

helmValues.add(joinKey("image", key, "repository"), fmt.Sprintf("%v/%v", containerRegistry, name))
helmValues.add(joinKey("image", key, "tag"), tag)

if len(config.ImageNames) == 1 {
helmValues.add("image.repository", fmt.Sprintf("%v/%v", containerRegistry, name))
helmValues.add("image.tag", tag)
}
}
} else if len(config.ContainerImageName) > 0 && len(config.ContainerImageTag) > 0 {
containerImageName = config.ContainerImageName
containerImageTag = config.ContainerImageTag
} else {
return fmt.Errorf("image information not given - please either set image or containerImageName and containerImageTag")
//support either image or containerImageName and containerImageTag
containerImageName := ""
containerImageTag := ""
if len(config.Image) > 0 {
containerImageName, containerImageTag, err = splitFullImageName(config.Image)
if err != nil {
log.Entry().WithError(err).Fatalf("Container image '%v' incorrect", config.Image)
}
} else if len(config.ContainerImageName) > 0 && len(config.ContainerImageTag) > 0 {
containerImageName = config.ContainerImageName
containerImageTag = config.ContainerImageTag
} else {
return fmt.Errorf("image information not given - please either set image or containerImageName and containerImageTag")
}
helmValues.add("image.repository", fmt.Sprintf("%v/%v", containerRegistry, containerImageName))
helmValues.add("image.tag", containerImageTag)

helmValues.add(joinKey("image", containerImageName, "repository"), fmt.Sprintf("%v/%v", containerRegistry, containerImageName))
helmValues.add(joinKey("image", containerImageName, "tag"), containerImageTag)
}

helmLogFields := map[string]interface{}{}
helmLogFields["Chart Path"] = config.ChartPath
helmLogFields["Namespace"] = config.Namespace
Expand All @@ -89,11 +118,10 @@ func runHelmDeploy(config kubernetesDeployOptions, utils kubernetes.DeployUtils,
}
}

var secretsData string
if len(config.ContainerRegistryUser) == 0 && len(config.ContainerRegistryPassword) == 0 {
log.Entry().Info("No/incomplete container registry credentials provided: skipping secret creation")
if len(config.ContainerRegistrySecret) > 0 {
secretsData = fmt.Sprintf(",imagePullSecrets[0].name=%v", config.ContainerRegistrySecret)
helmValues.add("imagePullSecrets[0].name", config.ContainerRegistrySecret)
}
} else {
var dockerRegistrySecret bytes.Buffer
Expand Down Expand Up @@ -124,7 +152,9 @@ func runHelmDeploy(config kubernetesDeployOptions, utils kubernetes.DeployUtils,
log.Entry().Debugf("Secret created: %v", string(dockerRegistrySecret.Bytes()))

// pass secret in helm default template way and in Piper backward compatible way
secretsData = fmt.Sprintf(",secret.name=%v,secret.dockerconfigjson=%v,imagePullSecrets[0].name=%v", config.ContainerRegistrySecret, dockerRegistrySecretData.Data.DockerConfJSON, config.ContainerRegistrySecret)
helmValues.add("secret.name", config.ContainerRegistrySecret)
helmValues.add("secret.dockerconfigjson", dockerRegistrySecretData.Data.DockerConfJSON)
helmValues.add("imagePullSecrets[0].name", config.ContainerRegistrySecret)
}

// Deprecated functionality
Expand All @@ -133,9 +163,8 @@ func runHelmDeploy(config kubernetesDeployOptions, utils kubernetes.DeployUtils,
// Due to the way helm is implemented it is currently not possible to overwrite a part of a list:
// see: https://github.com/helm/helm/issues/5711#issuecomment-636177594
// Recommended way is to use a custom values file which contains the appropriate data
ingressHosts := ""
for i, h := range config.IngressHosts {
ingressHosts += fmt.Sprintf(",ingress.hosts[%v]=%v", i, h)
helmValues.add(fmt.Sprintf("ingress.hosts[%v]", i), h)
}

upgradeParams := []string{
Expand All @@ -152,8 +181,7 @@ func runHelmDeploy(config kubernetesDeployOptions, utils kubernetes.DeployUtils,
upgradeParams,
"--install",
"--namespace", config.Namespace,
"--set",
fmt.Sprintf("image.repository=%v/%v,image.tag=%v%v%v", containerRegistry, containerImageName, containerImageTag, secretsData, ingressHosts),
"--set", helmValues.marshal(),
)

if config.ForceUpdates {
Expand Down Expand Up @@ -311,6 +339,42 @@ func runKubectlDeploy(config kubernetesDeployOptions, utils kubernetes.DeployUti
return nil
}

type helmValues []struct {
key, value string
}

func joinKey(parts ...string) string {
escapedParts := make([]string, 0, len(parts))
replacer := strings.NewReplacer(".", "\\.", "=", "\\=")
for _, part := range parts {
escapedParts = append(escapedParts, replacer.Replace(part))
}
return strings.Join(escapedParts, ".")
}

func (values *helmValues) add(key, value string) {
*values = append(*values, struct {
key string
value string
}{
key: key,
value: value,
})
}

func (values helmValues) marshal() string {
builder := strings.Builder{}
for idx, item := range values {
if idx > 0 {
builder.WriteString(",")
}
builder.WriteString(item.key)
builder.WriteString("=")
builder.WriteString(item.value)
}
return builder.String()
}

func getTempDirForKubeCtlJson() string {
tmpFolder, err := ioutil.TempDir(".", "temp-")
if err != nil {
Expand Down
32 changes: 32 additions & 0 deletions cmd/kubernetesDeploy_generated.go

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

Loading

0 comments on commit 402b8b2

Please sign in to comment.