1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-03-03 15:02:35 +02:00

feat(kubernetesDeploy): support for image digests (#3613)

Co-authored-by: Sumit Kulhadia <sumit.kulhadia@sap.com>
This commit is contained in:
Pavel Busko 2022-03-09 09:48:19 +01:00 committed by GitHub
parent e2de22f5ea
commit d2ef57bf5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 77 additions and 0 deletions

View File

@ -469,6 +469,7 @@ func defineKubeSecretParams(config kubernetesDeployOptions, containerRegistry st
func defineDeploymentValues(config kubernetesDeployOptions, containerRegistry string) (*deploymentValues, error) {
var err error
var useDigests bool
dv := &deploymentValues{
mapping: config.ValuesMapping,
}
@ -477,12 +478,24 @@ func defineDeploymentValues(config kubernetesDeployOptions, containerRegistry st
log.SetErrorCategory(log.ErrorConfiguration)
return nil, fmt.Errorf("number of imageNames and imageNameTags must be equal")
}
if len(config.ImageDigests) > 0 {
if len(config.ImageDigests) != len(config.ImageNameTags) {
log.SetErrorCategory(log.ErrorConfiguration)
return nil, fmt.Errorf("number of imageDigests and imageNameTags must be equal")
}
useDigests = true
}
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])
}
if useDigests {
tag = fmt.Sprintf("%s@%s", tag, config.ImageDigests[i])
}
dv.add(joinKey("image", key, "repository"), fmt.Sprintf("%v/%v", containerRegistry, name))
dv.add(joinKey("image", key, "tag"), tag)

View File

@ -36,6 +36,7 @@ type kubernetesDeployOptions struct {
Image string `json:"image,omitempty"`
ImageNames []string `json:"imageNames,omitempty"`
ImageNameTags []string `json:"imageNameTags,omitempty"`
ImageDigests []string `json:"imageDigests,omitempty"`
IngressHosts []string `json:"ingressHosts,omitempty"`
KeepFailedDeployments bool `json:"keepFailedDeployments,omitempty"`
RunHelmTests bool `json:"runHelmTests,omitempty"`
@ -180,6 +181,7 @@ func addKubernetesDeployFlags(cmd *cobra.Command, stepConfig *kubernetesDeployOp
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.ImageDigests, "imageDigests", []string{}, "List of image digests of the images to be deployed, in the format `sha256:<hash>`. If provided, image digests will be appended to the image tag, e.g. `<repository>/<name>:<tag>@<digest>`")
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")
@ -443,6 +445,20 @@ func kubernetesDeployMetadata() config.StepData {
Aliases: []config.Alias{},
Default: []string{},
},
{
Name: "imageDigests",
ResourceRef: []config.ResourceReference{
{
Name: "commonPipelineEnvironment",
Param: "container/imageDigests",
},
},
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
Type: "[]string",
Mandatory: false,
Aliases: []config.Alias{},
Default: []string{},
},
{
Name: "ingressHosts",
ResourceRef: []config.ResourceReference{},

View File

@ -1293,6 +1293,44 @@ image3: {{ .Values.image.myImage_sub1.repository }}:{{ .Values.image.myImage_sub
assert.Contains(t, string(appTemplateFileContents), "image: my.registry:55555/myImage:myTag\nimage2: my.registry:55555/myImage:myTag\nimage3: my.registry:55555/myImage-sub1:myTag", "kubectl parameters incorrect")
})
t.Run("test kubectl - with multiple images and digests", func(t *testing.T) {
opts := kubernetesDeployOptions{
APIServer: "https://my.api.server",
AppTemplate: "test.yaml",
ContainerRegistryURL: "https://my.registry:55555",
ContainerRegistrySecret: "regSecret",
DeployTool: "kubectl",
KubeConfig: "This is my kubeconfig",
Namespace: "deploymentNamespace",
DeployCommand: "apply",
ValuesMapping: map[string]interface{}{
"subchart.image.repository": "image.myImage.repository",
"subchart.image.tag": "image.myImage.tag",
},
ImageNames: []string{"myImage", "myImage-sub1", "myImage-sub2"},
ImageNameTags: []string{"myImage:myTag", "myImage-sub1:myTag", "myImage-sub2:myTag"},
ImageDigests: []string{"sha256:111", "sha256:222", "sha256:333"},
}
mockUtils := newKubernetesDeployMockUtils()
mockUtils.AddFile("test.yaml", []byte(`image: {{ .Values.image.myImage.repository }}:{{ .Values.image.myImage.tag }}
image2: {{ .Values.subchart.image.repository }}:{{ .Values.subchart.image.tag }}
image3: {{ .Values.image.myImage_sub1.repository }}:{{ .Values.image.myImage_sub1.tag }}
image4: {{ .Values.image.myImage_sub2.repository }}:{{ .Values.image.myImage_sub2.tag }}`))
var stdout bytes.Buffer
runKubernetesDeploy(opts, &telemetry.CustomData{}, mockUtils, &stdout)
assert.Equal(t, "kubectl", mockUtils.Calls[0].Exec, "Wrong apply command")
appTemplateFileContents, err := mockUtils.FileRead(opts.AppTemplate)
assert.NoError(t, err)
assert.Contains(t, string(appTemplateFileContents), `image: my.registry:55555/myImage:myTag@sha256:111
image2: my.registry:55555/myImage:myTag@sha256:111
image3: my.registry:55555/myImage-sub1:myTag@sha256:222
image4: my.registry:55555/myImage-sub2:myTag@sha256:333`, "kubectl parameters incorrect")
})
t.Run("test kubectl - fail with multiple images using placeholder", func(t *testing.T) {
opts := kubernetesDeployOptions{
APIServer: "https://my.api.server",

View File

@ -323,6 +323,16 @@ spec:
- PARAMETERS
- STAGES
- STEPS
- name: imageDigests
type: "[]string"
description: List of image digests of the images to be deployed, in the format `sha256:<hash>`. If provided, image digests will be appended to the image tag, e.g. `<repository>/<name>:<tag>@<digest>`
resourceRef:
- name: commonPipelineEnvironment
param: container/imageDigests
scope:
- PARAMETERS
- STAGES
- STEPS
- name: ingressHosts
type: "[]string"
description: (Deprecated) List of ingress hosts to be exposed via helm deployment.