mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-12 10:55:20 +02:00
feat(kubernetesDeploy): initial support for multiple images (#3548)
Co-authored-by: Philipp Stehle <philipp.stehle@sap.com> Co-authored-by: Ralf Pannemans <ralf.pannemans@sap.com>
This commit is contained in:
parent
8777fa793e
commit
402b8b28fa
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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{
|
||||
@ -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 {
|
||||
@ -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 {
|
||||
|
@ -33,6 +33,8 @@ type kubernetesDeployOptions struct {
|
||||
HelmDeployWaitSeconds int `json:"helmDeployWaitSeconds,omitempty"`
|
||||
HelmValues []string `json:"helmValues,omitempty"`
|
||||
Image string `json:"image,omitempty"`
|
||||
ImageNames []string `json:"imageNames,omitempty"`
|
||||
ImageNameTags []string `json:"imageNameTags,omitempty"`
|
||||
IngressHosts []string `json:"ingressHosts,omitempty"`
|
||||
KeepFailedDeployments bool `json:"keepFailedDeployments,omitempty"`
|
||||
RunHelmTests bool `json:"runHelmTests,omitempty"`
|
||||
@ -174,6 +176,8 @@ func addKubernetesDeployFlags(cmd *cobra.Command, stepConfig *kubernetesDeployOp
|
||||
cmd.Flags().IntVar(&stepConfig.HelmDeployWaitSeconds, "helmDeployWaitSeconds", 300, "Number of seconds before helm deploy returns.")
|
||||
cmd.Flags().StringSliceVar(&stepConfig.HelmValues, "helmValues", []string{}, "List of helm values as YAML file reference or URL (as per helm parameter description for `-f` / `--values`)")
|
||||
cmd.Flags().StringVar(&stepConfig.Image, "image", os.Getenv("PIPER_image"), "Full name of the image to be deployed.")
|
||||
cmd.Flags().StringSliceVar(&stepConfig.ImageNames, "imageNames", []string{}, "List of names of the images to be deployed.")
|
||||
cmd.Flags().StringSliceVar(&stepConfig.ImageNameTags, "imageNameTags", []string{}, "List of full names (registry and tag) of the images to be deployed.")
|
||||
cmd.Flags().StringSliceVar(&stepConfig.IngressHosts, "ingressHosts", []string{}, "(Deprecated) List of ingress hosts to be exposed via helm deployment.")
|
||||
cmd.Flags().BoolVar(&stepConfig.KeepFailedDeployments, "keepFailedDeployments", false, "Defines whether a failed deployment will be purged")
|
||||
cmd.Flags().BoolVar(&stepConfig.RunHelmTests, "runHelmTests", false, "Defines whether or not to run helm tests against the recently deployed release")
|
||||
@ -401,6 +405,34 @@ func kubernetesDeployMetadata() config.StepData {
|
||||
Aliases: []config.Alias{{Name: "deployImage"}},
|
||||
Default: os.Getenv("PIPER_image"),
|
||||
},
|
||||
{
|
||||
Name: "imageNames",
|
||||
ResourceRef: []config.ResourceReference{
|
||||
{
|
||||
Name: "commonPipelineEnvironment",
|
||||
Param: "container/imageNames",
|
||||
},
|
||||
},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "[]string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: []string{},
|
||||
},
|
||||
{
|
||||
Name: "imageNameTags",
|
||||
ResourceRef: []config.ResourceReference{
|
||||
{
|
||||
Name: "commonPipelineEnvironment",
|
||||
Param: "container/imageNameTags",
|
||||
},
|
||||
},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "[]string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: []string{},
|
||||
},
|
||||
{
|
||||
Name: "ingressHosts",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"github.com/SAP/jenkins-library/pkg/telemetry"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type kubernetesDeployMockUtils struct {
|
||||
@ -79,7 +80,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
"--namespace",
|
||||
"deploymentNamespace",
|
||||
"--set",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret,ingress.hosts[0]=ingress.host1,ingress.hosts[1]=ingress.host2",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,image.path/to/Image.repository=my.registry:55555/path/to/Image,image.path/to/Image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret,ingress.hosts[0]=ingress.host1,ingress.hosts[1]=ingress.host2",
|
||||
"--force",
|
||||
"--wait",
|
||||
"--timeout",
|
||||
@ -146,7 +147,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
|
||||
assert.Equal(t, "helm", mockUtils.Calls[2].Exec, "Wrong upgrade command")
|
||||
|
||||
assert.Contains(t, mockUtils.Calls[2].Params, "image.repository=my.registry:55555/path/to/Image,image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret,ingress.hosts[0]=ingress.host1,ingress.hosts[1]=ingress.host2", "Wrong upgrade parameters")
|
||||
assert.Contains(t, mockUtils.Calls[2].Params, "image.repository=my.registry:55555/path/to/Image,image.tag=latest,image.path/to/Image.repository=my.registry:55555/path/to/Image,image.path/to/Image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret,ingress.hosts[0]=ingress.host1,ingress.hosts[1]=ingress.host2", "Wrong upgrade parameters")
|
||||
})
|
||||
|
||||
t.Run("test helm - docker config.json path passed as parameter", func(t *testing.T) {
|
||||
@ -206,7 +207,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
"--namespace",
|
||||
"deploymentNamespace",
|
||||
"--set",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret,ingress.hosts[0]=ingress.host1,ingress.hosts[1]=ingress.host2",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,image.path/to/Image.repository=my.registry:55555/path/to/Image,image.path/to/Image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret,ingress.hosts[0]=ingress.host1,ingress.hosts[1]=ingress.host2",
|
||||
"--force",
|
||||
"--wait",
|
||||
"--timeout",
|
||||
@ -275,7 +276,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
"--namespace",
|
||||
"deploymentNamespace",
|
||||
"--set",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret,ingress.hosts[0]=ingress.host1,ingress.hosts[1]=ingress.host2",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,image.path/to/Image.repository=my.registry:55555/path/to/Image,image.path/to/Image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret,ingress.hosts[0]=ingress.host1,ingress.hosts[1]=ingress.host2",
|
||||
"--force",
|
||||
"--wait",
|
||||
"--timeout",
|
||||
@ -366,7 +367,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
"--namespace",
|
||||
"deploymentNamespace",
|
||||
"--set",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,image.path/to/Image.repository=my.registry:55555/path/to/Image,image.path/to/Image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret",
|
||||
"--force",
|
||||
"--wait",
|
||||
"--timeout",
|
||||
@ -441,7 +442,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
"--namespace",
|
||||
"deploymentNamespace",
|
||||
"--set",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,image.path/to/Image.repository=my.registry:55555/path/to/Image,image.path/to/Image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret",
|
||||
"--force",
|
||||
"--wait",
|
||||
"--timeout",
|
||||
@ -520,7 +521,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
"--namespace",
|
||||
"deploymentNamespace",
|
||||
"--set",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,image.path/to/Image.repository=my.registry:55555/path/to/Image,image.path/to/Image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret",
|
||||
"--force",
|
||||
"--wait",
|
||||
"--timeout",
|
||||
@ -600,7 +601,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
"--namespace",
|
||||
"deploymentNamespace",
|
||||
"--set",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,image.path/to/Image.repository=my.registry:55555/path/to/Image,image.path/to/Image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret",
|
||||
"--force",
|
||||
"--wait",
|
||||
"--timeout",
|
||||
@ -661,10 +662,143 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
|
||||
assert.Equal(t, "helm", mockUtils.Calls[1].Exec, "Wrong upgrade command")
|
||||
|
||||
assert.Contains(t, mockUtils.Calls[1].Params, "image.repository=my.registry:55555/path/to/Image,image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret", "Wrong upgrade parameters")
|
||||
assert.Contains(t, mockUtils.Calls[1].Params, "image.repository=my.registry:55555/path/to/Image,image.tag=latest,image.path/to/Image.repository=my.registry:55555/path/to/Image,image.path/to/Image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret", "Wrong upgrade parameters")
|
||||
|
||||
})
|
||||
|
||||
t.Run("test helm v3 - with multiple images", func(t *testing.T) {
|
||||
opts := kubernetesDeployOptions{
|
||||
ContainerRegistryURL: "https://my.registry:55555",
|
||||
ContainerRegistryUser: "registryUser",
|
||||
ContainerRegistryPassword: "dummy",
|
||||
ContainerRegistrySecret: "testSecret",
|
||||
ChartPath: "path/to/chart",
|
||||
DeploymentName: "deploymentName",
|
||||
DeployTool: "helm3",
|
||||
ForceUpdates: true,
|
||||
HelmDeployWaitSeconds: 400,
|
||||
HelmValues: []string{"values1.yaml", "values2.yaml"},
|
||||
ImageNames: []string{"myImage", "myImage.sub1", "myImage.sub2"},
|
||||
ImageNameTags: []string{"myImage:myTag", "myImage-sub1:myTag", "myImage-sub2:myTag"},
|
||||
AdditionalParameters: []string{"--testParam", "testValue"},
|
||||
KubeContext: "testCluster",
|
||||
Namespace: "deploymentNamespace",
|
||||
DockerConfigJSON: ".pipeline/docker/config.json",
|
||||
}
|
||||
|
||||
dockerConfigJSON := `{"kind": "Secret","data":{".dockerconfigjson": "ThisIsOurBase64EncodedSecret=="}}`
|
||||
|
||||
mockUtils := newKubernetesDeployMockUtils()
|
||||
mockUtils.StdoutReturn = map[string]string{
|
||||
`kubectl create secret generic testSecret --from-file=.dockerconfigjson=.pipeline/docker/config.json --type=kubernetes.io/dockerconfigjson --insecure-skip-tls-verify=true --dry-run=client --output=json`: dockerConfigJSON,
|
||||
}
|
||||
|
||||
var stdout bytes.Buffer
|
||||
|
||||
require.NoError(t, runKubernetesDeploy(opts, &telemetry.CustomData{}, mockUtils, &stdout))
|
||||
|
||||
assert.Equal(t, "kubectl", mockUtils.Calls[0].Exec, "Wrong secret creation command")
|
||||
assert.Equal(t, []string{
|
||||
"create",
|
||||
"secret",
|
||||
"generic",
|
||||
"testSecret",
|
||||
"--from-file=.dockerconfigjson=.pipeline/docker/config.json",
|
||||
"--type=kubernetes.io/dockerconfigjson",
|
||||
"--insecure-skip-tls-verify=true",
|
||||
"--dry-run=client",
|
||||
"--output=json"},
|
||||
mockUtils.Calls[0].Params, "Wrong secret creation parameters")
|
||||
|
||||
assert.Equal(t, "helm", mockUtils.Calls[1].Exec, "Wrong upgrade command")
|
||||
|
||||
assert.Contains(t, mockUtils.Calls[1].Params, `image.myImage.repository=my.registry:55555/myImage,image.myImage.tag=myTag,image.myImage\.sub1.repository=my.registry:55555/myImage-sub1,image.myImage\.sub1.tag=myTag,image.myImage\.sub2.repository=my.registry:55555/myImage-sub2,image.myImage\.sub2.tag=myTag,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret`, "Wrong upgrade parameters")
|
||||
|
||||
})
|
||||
|
||||
t.Run("test helm v3 - with one image in multiple images array", func(t *testing.T) {
|
||||
opts := kubernetesDeployOptions{
|
||||
ContainerRegistryURL: "https://my.registry:55555",
|
||||
ContainerRegistryUser: "registryUser",
|
||||
ContainerRegistryPassword: "dummy",
|
||||
ContainerRegistrySecret: "testSecret",
|
||||
ChartPath: "path/to/chart",
|
||||
DeploymentName: "deploymentName",
|
||||
DeployTool: "helm3",
|
||||
ForceUpdates: true,
|
||||
HelmDeployWaitSeconds: 400,
|
||||
HelmValues: []string{"values1.yaml", "values2.yaml"},
|
||||
ImageNames: []string{"myImage"},
|
||||
ImageNameTags: []string{"myImage:myTag"},
|
||||
AdditionalParameters: []string{"--testParam", "testValue"},
|
||||
KubeContext: "testCluster",
|
||||
Namespace: "deploymentNamespace",
|
||||
DockerConfigJSON: ".pipeline/docker/config.json",
|
||||
}
|
||||
|
||||
dockerConfigJSON := `{"kind": "Secret","data":{".dockerconfigjson": "ThisIsOurBase64EncodedSecret=="}}`
|
||||
|
||||
mockUtils := newKubernetesDeployMockUtils()
|
||||
mockUtils.StdoutReturn = map[string]string{
|
||||
`kubectl create secret generic testSecret --from-file=.dockerconfigjson=.pipeline/docker/config.json --type=kubernetes.io/dockerconfigjson --insecure-skip-tls-verify=true --dry-run=client --output=json`: dockerConfigJSON,
|
||||
}
|
||||
|
||||
var stdout bytes.Buffer
|
||||
|
||||
require.NoError(t, runKubernetesDeploy(opts, &telemetry.CustomData{}, mockUtils, &stdout))
|
||||
|
||||
assert.Equal(t, "kubectl", mockUtils.Calls[0].Exec, "Wrong secret creation command")
|
||||
assert.Equal(t, []string{
|
||||
"create",
|
||||
"secret",
|
||||
"generic",
|
||||
"testSecret",
|
||||
"--from-file=.dockerconfigjson=.pipeline/docker/config.json",
|
||||
"--type=kubernetes.io/dockerconfigjson",
|
||||
"--insecure-skip-tls-verify=true",
|
||||
"--dry-run=client",
|
||||
"--output=json"},
|
||||
mockUtils.Calls[0].Params, "Wrong secret creation parameters")
|
||||
|
||||
assert.Equal(t, "helm", mockUtils.Calls[1].Exec, "Wrong upgrade command")
|
||||
|
||||
assert.Contains(t, mockUtils.Calls[1].Params, `image.myImage.repository=my.registry:55555/myImage,image.myImage.tag=myTag,image.repository=my.registry:55555/myImage,image.tag=myTag,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret`, "Wrong upgrade parameters")
|
||||
|
||||
})
|
||||
|
||||
t.Run("test helm v3 - with multiple images - missing ImageNameTags", func(t *testing.T) {
|
||||
opts := kubernetesDeployOptions{
|
||||
ContainerRegistryURL: "https://my.registry:55555",
|
||||
ContainerRegistryUser: "registryUser",
|
||||
ContainerRegistryPassword: "dummy",
|
||||
ContainerRegistrySecret: "testSecret",
|
||||
ChartPath: "path/to/chart",
|
||||
DeploymentName: "deploymentName",
|
||||
DeployTool: "helm3",
|
||||
ForceUpdates: true,
|
||||
HelmDeployWaitSeconds: 400,
|
||||
HelmValues: []string{"values1.yaml", "values2.yaml"},
|
||||
ImageNames: []string{"myImage", "myImage.sub1", "myImage.sub2"},
|
||||
ImageNameTags: []string{"myImage:myTag"},
|
||||
AdditionalParameters: []string{"--testParam", "testValue"},
|
||||
KubeContext: "testCluster",
|
||||
Namespace: "deploymentNamespace",
|
||||
DockerConfigJSON: ".pipeline/docker/config.json",
|
||||
}
|
||||
|
||||
dockerConfigJSON := `{"kind": "Secret","data":{".dockerconfigjson": "ThisIsOurBase64EncodedSecret=="}}`
|
||||
|
||||
mockUtils := newKubernetesDeployMockUtils()
|
||||
mockUtils.StdoutReturn = map[string]string{
|
||||
`kubectl create secret generic testSecret --from-file=.dockerconfigjson=.pipeline/docker/config.json --type=kubernetes.io/dockerconfigjson --insecure-skip-tls-verify=true --dry-run=client --output=json`: dockerConfigJSON,
|
||||
}
|
||||
|
||||
var stdout bytes.Buffer
|
||||
|
||||
err := runKubernetesDeploy(opts, &telemetry.CustomData{}, mockUtils, &stdout)
|
||||
assert.EqualError(t, err, "number of imageNames and imageNameTags must be equal")
|
||||
})
|
||||
|
||||
t.Run("test helm3 - fails without image information", func(t *testing.T) {
|
||||
opts := kubernetesDeployOptions{
|
||||
ContainerRegistryURL: "https://my.registry:55555",
|
||||
@ -744,7 +878,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
"--namespace",
|
||||
"deploymentNamespace",
|
||||
"--set",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,image.path/to/Image.repository=my.registry:55555/path/to/Image,image.path/to/Image.tag=latest,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==,imagePullSecrets[0].name=testSecret",
|
||||
"--force",
|
||||
"--wait",
|
||||
"--timeout",
|
||||
@ -787,7 +921,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
"--namespace",
|
||||
"deploymentNamespace",
|
||||
"--set",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,imagePullSecrets[0].name=testSecret",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,image.path/to/Image.repository=my.registry:55555/path/to/Image,image.path/to/Image.tag=latest,imagePullSecrets[0].name=testSecret",
|
||||
"--force",
|
||||
"--wait",
|
||||
"--timeout",
|
||||
@ -871,7 +1005,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
"--namespace",
|
||||
"deploymentNamespace",
|
||||
"--set",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,imagePullSecrets[0].name=testSecret",
|
||||
"image.repository=my.registry:55555/path/to/Image,image.tag=latest,image.path/to/Image.repository=my.registry:55555/path/to/Image,image.path/to/Image.tag=latest,imagePullSecrets[0].name=testSecret",
|
||||
"--wait",
|
||||
"--timeout",
|
||||
"400s",
|
||||
|
@ -236,6 +236,26 @@ spec:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: imageNames
|
||||
type: "[]string"
|
||||
description: List of names of the images to be deployed.
|
||||
resourceRef:
|
||||
- name: commonPipelineEnvironment
|
||||
param: container/imageNames
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: imageNameTags
|
||||
type: "[]string"
|
||||
description: List of full names (registry and tag) of the images to be deployed.
|
||||
resourceRef:
|
||||
- name: commonPipelineEnvironment
|
||||
param: container/imageNameTags
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: ingressHosts
|
||||
type: "[]string"
|
||||
description: (Deprecated) List of ingress hosts to be exposed via helm deployment.
|
||||
|
Loading…
Reference in New Issue
Block a user