mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-01-18 05:18:24 +02:00
feat(kubernetesDeploy): use go templating for the deployTool: kubectl
(#3600)
Co-authored-by: Johannes Dillmann <j.dillmann@sap.com>
This commit is contained in:
parent
3e89fb0cd7
commit
e2de22f5ea
@ -9,14 +9,17 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/docker"
|
||||
"github.com/SAP/jenkins-library/pkg/kubernetes"
|
||||
"github.com/SAP/jenkins-library/pkg/log"
|
||||
"github.com/SAP/jenkins-library/pkg/telemetry"
|
||||
"github.com/pkg/errors"
|
||||
"helm.sh/helm/v3/pkg/cli/values"
|
||||
)
|
||||
|
||||
func kubernetesDeploy(config kubernetesDeployOptions, telemetryData *telemetry.CustomData) {
|
||||
@ -53,49 +56,9 @@ func runHelmDeploy(config kubernetesDeployOptions, utils kubernetes.DeployUtils,
|
||||
log.Entry().WithError(err).Fatalf("Container registry url '%v' incorrect", config.ContainerRegistryURL)
|
||||
}
|
||||
|
||||
helmValues := helmValues{
|
||||
mapping: config.ValuesMapping,
|
||||
}
|
||||
|
||||
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 {
|
||||
// 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)
|
||||
helmValues, err := defineDeploymentValues(config, containerRegistry)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to process deployment values")
|
||||
}
|
||||
|
||||
helmLogFields := map[string]interface{}{}
|
||||
@ -152,7 +115,7 @@ func runHelmDeploy(config kubernetesDeployOptions, utils kubernetes.DeployUtils,
|
||||
// make sure that secret is hidden in log output
|
||||
log.RegisterSecret(dockerRegistrySecretData.Data.DockerConfJSON)
|
||||
|
||||
log.Entry().Debugf("Secret created: %v", string(dockerRegistrySecret.Bytes()))
|
||||
log.Entry().Debugf("Secret created: %v", dockerRegistrySecret.String())
|
||||
|
||||
// pass secret in helm default template way and in Piper backward compatible way
|
||||
helmValues.add("secret.name", config.ContainerRegistrySecret)
|
||||
@ -189,7 +152,7 @@ func runHelmDeploy(config kubernetesDeployOptions, utils kubernetes.DeployUtils,
|
||||
upgradeParams,
|
||||
"--install",
|
||||
"--namespace", config.Namespace,
|
||||
"--set", helmValues.marshal(),
|
||||
"--set", strings.Join(helmValues.marshal(), ","),
|
||||
)
|
||||
|
||||
if config.ForceUpdates {
|
||||
@ -295,7 +258,7 @@ func runKubectlDeploy(config kubernetesDeployOptions, utils kubernetes.DeployUti
|
||||
}
|
||||
|
||||
// write the json output to a file
|
||||
tmpFolder := getTempDirForKubeCtlJson()
|
||||
tmpFolder := getTempDirForKubeCtlJSON()
|
||||
defer os.RemoveAll(tmpFolder) // clean up
|
||||
jsonData, _ := json.Marshal(dockerRegistrySecretData)
|
||||
ioutil.WriteFile(filepath.Join(tmpFolder, "secret.json"), jsonData, 0777)
|
||||
@ -312,28 +275,45 @@ func runKubectlDeploy(config kubernetesDeployOptions, utils kubernetes.DeployUti
|
||||
log.Entry().WithError(err).Fatalf("Error when reading appTemplate '%v'", config.AppTemplate)
|
||||
}
|
||||
|
||||
// support either image or containerImageName and containerImageTag
|
||||
fullImage := ""
|
||||
|
||||
if len(config.Image) > 0 {
|
||||
fullImage = config.Image
|
||||
} else if len(config.ContainerImageName) > 0 && len(config.ContainerImageTag) > 0 {
|
||||
fullImage = config.ContainerImageName + ":" + config.ContainerImageTag
|
||||
} else {
|
||||
return fmt.Errorf("image information not given - please either set image or containerImageName and containerImageTag")
|
||||
values, err := defineDeploymentValues(config, containerRegistry)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to process deployment values")
|
||||
}
|
||||
err = values.mapValues()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to map values using 'valuesMapping' configuration")
|
||||
}
|
||||
|
||||
// Update image name in deployment yaml, expects placeholder like 'image: <image-name>'
|
||||
re := regexp.MustCompile(`image:[ ]*<image-name>`)
|
||||
appTemplate = []byte(re.ReplaceAllString(string(appTemplate), fmt.Sprintf("image: %v/%v", containerRegistry, fullImage)))
|
||||
placeholderFound := re.Match(appTemplate)
|
||||
|
||||
err = utils.FileWrite(config.AppTemplate, appTemplate, 0700)
|
||||
if placeholderFound {
|
||||
log.Entry().Warn("image placeholder '<image-name>' is deprecated and does not support multi-image replacement, please use Helm-like template syntax '{{ .Values.image.[image-name].reposotory }}:{{ .Values.image.[image-name].tag }}")
|
||||
if values.singleImage {
|
||||
// Update image name in deployment yaml, expects placeholder like 'image: <image-name>'
|
||||
appTemplate = []byte(re.ReplaceAllString(string(appTemplate), fmt.Sprintf("image: %s:%s", values.get("image.repository"), values.get("image.tag"))))
|
||||
} else {
|
||||
return fmt.Errorf("multi-image replacement not supported for single image placeholder")
|
||||
}
|
||||
}
|
||||
|
||||
buf := bytes.NewBufferString("")
|
||||
tpl, err := template.New("appTemplate").Parse(string(appTemplate))
|
||||
if err != nil {
|
||||
log.Entry().WithError(err).Fatalf("Error when updating appTemplate '%v'", config.AppTemplate)
|
||||
return errors.Wrap(err, "failed to parse app-template file")
|
||||
}
|
||||
err = tpl.Execute(buf, values.asHelmValues())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to render app-template file")
|
||||
}
|
||||
|
||||
err = utils.FileWrite(config.AppTemplate, buf.Bytes(), 0700)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Error when updating appTemplate '%v'", config.AppTemplate)
|
||||
}
|
||||
|
||||
kubeParams = append(kubeParams, config.DeployCommand, "--filename", config.AppTemplate)
|
||||
if config.ForceUpdates == true && config.DeployCommand == "replace" {
|
||||
if config.ForceUpdates && config.DeployCommand == "replace" {
|
||||
kubeParams = append(kubeParams, "--force")
|
||||
}
|
||||
|
||||
@ -347,24 +327,16 @@ func runKubectlDeploy(config kubernetesDeployOptions, utils kubernetes.DeployUti
|
||||
return nil
|
||||
}
|
||||
|
||||
type helmValues struct {
|
||||
mapping map[string]interface{}
|
||||
values []struct {
|
||||
type deploymentValues struct {
|
||||
mapping map[string]interface{}
|
||||
singleImage bool
|
||||
values []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 (hv *helmValues) add(key, value string) {
|
||||
hv.values = append(hv.values, struct {
|
||||
func (dv *deploymentValues) add(key, value string) {
|
||||
dv.values = append(dv.values, struct {
|
||||
key string
|
||||
value string
|
||||
}{
|
||||
@ -373,8 +345,8 @@ func (hv *helmValues) add(key, value string) {
|
||||
})
|
||||
}
|
||||
|
||||
func (hv helmValues) get(key string) string {
|
||||
for _, item := range hv.values {
|
||||
func (dv deploymentValues) get(key string) string {
|
||||
for _, item := range dv.values {
|
||||
if item.key == key {
|
||||
return item.value
|
||||
}
|
||||
@ -383,36 +355,58 @@ func (hv helmValues) get(key string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (hv *helmValues) mapValues() error {
|
||||
for dst, src := range hv.mapping {
|
||||
srcString, ok := src.(string)
|
||||
func (dv *deploymentValues) mapValues() error {
|
||||
var keys []string
|
||||
for k := range dv.mapping {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, dst := range keys {
|
||||
srcString, ok := dv.mapping[dst].(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid path '%#v' is used for valuesMapping, only strings are supported", src)
|
||||
return fmt.Errorf("invalid path '%#v' is used for valuesMapping, only strings are supported", dv.mapping[dst])
|
||||
}
|
||||
if val := hv.get(srcString); val != "" {
|
||||
hv.add(dst, val)
|
||||
if val := dv.get(srcString); val != "" {
|
||||
dv.add(dst, val)
|
||||
} else {
|
||||
log.Entry().Warnf("can not map '%s: %s', %s is not set", dst, src, src)
|
||||
log.Entry().Warnf("can not map '%s: %s', %s is not set", dst, dv.mapping[dst], dv.mapping[dst])
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hv helmValues) marshal() string {
|
||||
builder := strings.Builder{}
|
||||
for idx, item := range hv.values {
|
||||
if idx > 0 {
|
||||
builder.WriteString(",")
|
||||
}
|
||||
builder.WriteString(item.key)
|
||||
builder.WriteString("=")
|
||||
builder.WriteString(item.value)
|
||||
func (dv deploymentValues) marshal() []string {
|
||||
var result []string
|
||||
for _, item := range dv.values {
|
||||
result = append(result, fmt.Sprintf("%s=%s", item.key, item.value))
|
||||
}
|
||||
return builder.String()
|
||||
return result
|
||||
}
|
||||
|
||||
func getTempDirForKubeCtlJson() string {
|
||||
func (dv *deploymentValues) asHelmValues() map[string]interface{} {
|
||||
valuesOpts := values.Options{
|
||||
Values: dv.marshal(),
|
||||
}
|
||||
mergedValues, err := valuesOpts.MergeValues(nil)
|
||||
if err != nil {
|
||||
log.Entry().WithError(err).Fatal("failed to process deployment values")
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"Values": mergedValues,
|
||||
}
|
||||
}
|
||||
|
||||
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 getTempDirForKubeCtlJSON() string {
|
||||
tmpFolder, err := ioutil.TempDir(".", "temp-")
|
||||
if err != nil {
|
||||
log.Entry().WithError(err).WithField("path", tmpFolder).Debug("creating temp directory failed")
|
||||
@ -472,3 +466,55 @@ func defineKubeSecretParams(config kubernetesDeployOptions, containerRegistry st
|
||||
"--output=json",
|
||||
}
|
||||
}
|
||||
|
||||
func defineDeploymentValues(config kubernetesDeployOptions, containerRegistry string) (*deploymentValues, error) {
|
||||
var err error
|
||||
dv := &deploymentValues{
|
||||
mapping: config.ValuesMapping,
|
||||
}
|
||||
if len(config.ImageNames) > 0 {
|
||||
if len(config.ImageNames) != len(config.ImageNameTags) {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return nil, 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])
|
||||
}
|
||||
|
||||
dv.add(joinKey("image", key, "repository"), fmt.Sprintf("%v/%v", containerRegistry, name))
|
||||
dv.add(joinKey("image", key, "tag"), tag)
|
||||
|
||||
if len(config.ImageNames) == 1 {
|
||||
dv.singleImage = true
|
||||
dv.add("image.repository", fmt.Sprintf("%v/%v", containerRegistry, name))
|
||||
dv.add("image.tag", tag)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// support either image or containerImageName and containerImageTag
|
||||
containerImageName := ""
|
||||
containerImageTag := ""
|
||||
dv.singleImage = true
|
||||
|
||||
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 nil, fmt.Errorf("image information not given - please either set image or containerImageName and containerImageTag")
|
||||
}
|
||||
dv.add("image.repository", fmt.Sprintf("%v/%v", containerRegistry, containerImageName))
|
||||
dv.add("image.tag", containerImageTag)
|
||||
|
||||
dv.add(joinKey("image", containerImageName, "repository"), fmt.Sprintf("%v/%v", containerRegistry, containerImageName))
|
||||
dv.add(joinKey("image", containerImageName, "tag"), containerImageTag)
|
||||
}
|
||||
|
||||
return dv, nil
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ helm upgrade <deploymentName> <chartPath> --install --force --namespace <namespa
|
||||
func addKubernetesDeployFlags(cmd *cobra.Command, stepConfig *kubernetesDeployOptions) {
|
||||
cmd.Flags().StringSliceVar(&stepConfig.AdditionalParameters, "additionalParameters", []string{}, "Defines additional parameters for \"helm install\" or \"kubectl apply\" command.")
|
||||
cmd.Flags().StringVar(&stepConfig.APIServer, "apiServer", os.Getenv("PIPER_apiServer"), "Defines the Url of the API Server of the Kubernetes cluster.")
|
||||
cmd.Flags().StringVar(&stepConfig.AppTemplate, "appTemplate", os.Getenv("PIPER_appTemplate"), "Defines the filename for the kubernetes app template (e.g. k8s_apptemplate.yaml). Within this file `image` needs to be set as `image: <image-name>` for the image to be overwritten with other parameters.")
|
||||
cmd.Flags().StringVar(&stepConfig.AppTemplate, "appTemplate", os.Getenv("PIPER_appTemplate"), "Defines the filename for the kubernetes app template (e.g. k8s_apptemplate.yaml).")
|
||||
cmd.Flags().StringVar(&stepConfig.ChartPath, "chartPath", os.Getenv("PIPER_chartPath"), "Defines the chart path for deployments using helm. It is a mandatory parameter when `deployTool:helm` or `deployTool:helm3`.")
|
||||
cmd.Flags().StringVar(&stepConfig.ContainerRegistryPassword, "containerRegistryPassword", os.Getenv("PIPER_containerRegistryPassword"), "Password for container registry access - typically provided by the CI/CD environment.")
|
||||
cmd.Flags().StringVar(&stepConfig.ContainerImageName, "containerImageName", os.Getenv("PIPER_containerImageName"), "Name of the container which will be built - will be used together with `containerImageTag` instead of parameter `containerImage`")
|
||||
|
@ -307,7 +307,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
var stdout bytes.Buffer
|
||||
|
||||
err := runKubernetesDeploy(opts, &telemetry.CustomData{}, mockUtils, &stdout)
|
||||
assert.EqualError(t, err, "image information not given - please either set image or containerImageName and containerImageTag")
|
||||
assert.EqualError(t, err, "failed to process deployment values: image information not given - please either set image or containerImageName and containerImageTag")
|
||||
})
|
||||
|
||||
t.Run("test helm v3", func(t *testing.T) {
|
||||
@ -712,7 +712,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
|
||||
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")
|
||||
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")
|
||||
|
||||
})
|
||||
|
||||
@ -796,7 +796,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
var stdout bytes.Buffer
|
||||
|
||||
err := runKubernetesDeploy(opts, &telemetry.CustomData{}, mockUtils, &stdout)
|
||||
assert.EqualError(t, err, "number of imageNames and imageNameTags must be equal")
|
||||
assert.EqualError(t, err, "failed to process deployment values: number of imageNames and imageNameTags must be equal")
|
||||
})
|
||||
|
||||
t.Run("test helm v3 - with multiple images and valuesMapping", func(t *testing.T) {
|
||||
@ -852,10 +852,10 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
pos := 11
|
||||
assert.Contains(t, mockUtils.Calls[1].Params[pos], "image.myImage.repository=my.registry:55555/myImage", "Missing update parameter")
|
||||
assert.Contains(t, mockUtils.Calls[1].Params[pos], "image.myImage.tag=myTag", "Wrong upgrade parameters")
|
||||
assert.Contains(t, mockUtils.Calls[1].Params[pos], "image.myImage\\.sub1.repository=my.registry:55555/myImage-sub1", "Missing update parameter")
|
||||
assert.Contains(t, mockUtils.Calls[1].Params[pos], "image.myImage\\.sub1.tag=myTag", "Missing update parameter")
|
||||
assert.Contains(t, mockUtils.Calls[1].Params[pos], "image.myImage\\.sub2.repository=my.registry:55555/myImage-sub2", "Missing update parameter")
|
||||
assert.Contains(t, mockUtils.Calls[1].Params[pos], "image.myImage\\.sub2.tag=myTag,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==", "Missing update parameter")
|
||||
assert.Contains(t, mockUtils.Calls[1].Params[pos], "image.myImage_sub1.repository=my.registry:55555/myImage-sub1", "Missing update parameter")
|
||||
assert.Contains(t, mockUtils.Calls[1].Params[pos], "image.myImage_sub1.tag=myTag", "Missing update parameter")
|
||||
assert.Contains(t, mockUtils.Calls[1].Params[pos], "image.myImage_sub2.repository=my.registry:55555/myImage-sub2", "Missing update parameter")
|
||||
assert.Contains(t, mockUtils.Calls[1].Params[pos], "image.myImage_sub2.tag=myTag,secret.name=testSecret,secret.dockerconfigjson=ThisIsOurBase64EncodedSecret==", "Missing update parameter")
|
||||
assert.Contains(t, mockUtils.Calls[1].Params[pos], "imagePullSecrets[0].name=testSecret", "Missing update parameter")
|
||||
assert.Contains(t, mockUtils.Calls[1].Params[pos], "subchart.image.registry=my.registry:55555/myImage", "Missing update parameter")
|
||||
assert.Contains(t, mockUtils.Calls[1].Params[pos], "subchart.image.tag=myTag", "Missing update parameter")
|
||||
@ -916,7 +916,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
var stdout bytes.Buffer
|
||||
|
||||
err := runKubernetesDeploy(opts, &telemetry.CustomData{}, mockUtils, &stdout)
|
||||
assert.EqualError(t, err, "image information not given - please either set image or containerImageName and containerImageTag")
|
||||
assert.EqualError(t, err, "failed to process deployment values: image information not given - please either set image or containerImageName and containerImageTag")
|
||||
})
|
||||
|
||||
t.Run("test helm v3 - keep failed deployments", func(t *testing.T) {
|
||||
@ -1233,6 +1233,88 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
assert.Contains(t, string(appTemplateFileContents), "image: my.registry:55555/path/to/Image:latest", "kubectl parameters incorrect")
|
||||
})
|
||||
|
||||
t.Run("test kubectl - with containerImageName and containerImageTag instead of image using go template", func(t *testing.T) {
|
||||
opts := kubernetesDeployOptions{
|
||||
APIServer: "https://my.api.server",
|
||||
AppTemplate: "test.yaml",
|
||||
ContainerRegistryURL: "https://my.registry:55555",
|
||||
ContainerRegistrySecret: "regSecret",
|
||||
DeployTool: "kubectl",
|
||||
ContainerImageTag: "latest",
|
||||
ContainerImageName: "path/to/Image",
|
||||
KubeConfig: "This is my kubeconfig",
|
||||
Namespace: "deploymentNamespace",
|
||||
DeployCommand: "apply",
|
||||
}
|
||||
|
||||
mockUtils := newKubernetesDeployMockUtils()
|
||||
mockUtils.AddFile("test.yaml", []byte("image: {{ .Values.image.repository }}:{{ .Values.image.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/path/to/Image:latest", "kubectl parameters incorrect")
|
||||
})
|
||||
|
||||
t.Run("test kubectl - with multiple images using go template", 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"},
|
||||
}
|
||||
|
||||
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 }}`))
|
||||
|
||||
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\nimage2: my.registry:55555/myImage:myTag\nimage3: my.registry:55555/myImage-sub1:myTag", "kubectl parameters incorrect")
|
||||
})
|
||||
|
||||
t.Run("test kubectl - fail with multiple images using placeholder", 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",
|
||||
ImageNames: []string{"myImage", "myImage-sub1", "myImage-sub2"},
|
||||
ImageNameTags: []string{"myImage:myTag", "myImage-sub1:myTag", "myImage-sub2:myTag"},
|
||||
}
|
||||
|
||||
mockUtils := newKubernetesDeployMockUtils()
|
||||
mockUtils.AddFile("test.yaml", []byte("image: <image-name>"))
|
||||
|
||||
var stdout bytes.Buffer
|
||||
err := runKubernetesDeploy(opts, &telemetry.CustomData{}, mockUtils, &stdout)
|
||||
assert.EqualError(t, err, "multi-image replacement not supported for single image placeholder")
|
||||
})
|
||||
|
||||
t.Run("test kubectl - fails without image information", func(t *testing.T) {
|
||||
opts := kubernetesDeployOptions{
|
||||
APIServer: "https://my.api.server",
|
||||
@ -1251,7 +1333,7 @@ func TestRunKubernetesDeploy(t *testing.T) {
|
||||
var stdout bytes.Buffer
|
||||
|
||||
err := runKubernetesDeploy(opts, &telemetry.CustomData{}, mockUtils, &stdout)
|
||||
assert.EqualError(t, err, "image information not given - please either set image or containerImageName and containerImageTag")
|
||||
assert.EqualError(t, err, "failed to process deployment values: image information not given - please either set image or containerImageName and containerImageTag")
|
||||
})
|
||||
|
||||
t.Run("test kubectl - use replace deploy command", func(t *testing.T) {
|
||||
|
112
go.mod
112
go.mod
@ -11,9 +11,9 @@ require (
|
||||
github.com/bmatcuk/doublestar v1.3.4
|
||||
github.com/bndr/gojenkins v1.1.1-0.20210520222939-90ed82bfdff6
|
||||
github.com/buildpacks/lifecycle v0.13.0
|
||||
github.com/docker/cli v20.10.9+incompatible
|
||||
github.com/docker/cli v20.10.11+incompatible
|
||||
github.com/elliotchance/orderedmap v1.4.0
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible
|
||||
github.com/getsentry/sentry-go v0.11.0
|
||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
|
||||
github.com/go-git/go-billy/v5 v5.3.1
|
||||
@ -23,7 +23,7 @@ require (
|
||||
github.com/go-playground/locales v0.14.0
|
||||
github.com/go-playground/universal-translator v0.18.0
|
||||
github.com/go-playground/validator/v10 v10.9.0
|
||||
github.com/google/go-cmp v0.5.6
|
||||
github.com/google/go-cmp v0.5.7
|
||||
github.com/google/go-containerregistry v0.6.0
|
||||
github.com/google/go-github/v32 v32.1.0
|
||||
github.com/google/uuid v1.3.0
|
||||
@ -36,31 +36,37 @@ require (
|
||||
github.com/magiconair/properties v1.8.5
|
||||
github.com/magicsong/sonargo v0.0.1
|
||||
github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5
|
||||
github.com/mitchellh/mapstructure v1.4.2
|
||||
github.com/mitchellh/mapstructure v1.4.3
|
||||
github.com/motemen/go-nuts v0.0.0-20210915132349-615a782f2c69
|
||||
github.com/pelletier/go-toml v1.9.4
|
||||
github.com/piper-validation/fortify-client-go v0.0.0-20220126145513-7b3e9a72af01
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/spf13/cobra v1.2.1
|
||||
github.com/spf13/cobra v1.3.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/testcontainers/testcontainers-go v0.10.0
|
||||
github.com/xuri/excelize/v2 v2.4.1
|
||||
golang.org/x/mod v0.5.1
|
||||
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1
|
||||
google.golang.org/api v0.47.0
|
||||
gopkg.in/ini.v1 v1.63.2
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||
google.golang.org/api v0.67.0
|
||||
gopkg.in/ini.v1 v1.66.2
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
helm.sh/helm/v3 v3.8.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.83.0 // indirect
|
||||
cloud.google.com/go v0.100.2 // indirect
|
||||
cloud.google.com/go/compute v0.1.0 // indirect
|
||||
cloud.google.com/go/iam v0.1.0 // indirect
|
||||
cloud.google.com/go/kms v1.3.0 // indirect
|
||||
cloud.google.com/go/monitoring v1.3.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go v58.3.0+incompatible // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.11.21 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.14 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.15 // indirect
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.8 // indirect
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.4.2 // indirect
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||
@ -71,10 +77,11 @@ require (
|
||||
github.com/BurntSushi/toml v0.4.1 // indirect
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible // indirect
|
||||
github.com/Jeffail/gabs v1.1.1 // indirect
|
||||
github.com/Masterminds/goutils v1.1.0 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.1 // indirect
|
||||
github.com/Microsoft/hcsshim v0.9.0 // indirect
|
||||
github.com/Microsoft/hcsshim v0.9.1 // indirect
|
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
@ -93,11 +100,11 @@ require (
|
||||
github.com/buildpacks/imgutil v0.0.0-20211001201950-cf7ae41c3771 // indirect
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
github.com/cenkalti/backoff/v3 v3.0.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible // indirect
|
||||
github.com/circonus-labs/circonusllhist v0.1.3 // indirect
|
||||
github.com/containerd/cgroups v1.0.1 // indirect
|
||||
github.com/containerd/containerd v1.5.7 // indirect
|
||||
github.com/containerd/cgroups v1.0.2 // indirect
|
||||
github.com/containerd/containerd v1.5.9 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.7.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/deepmap/oapi-codegen v1.8.2 // indirect
|
||||
@ -105,39 +112,44 @@ require (
|
||||
github.com/digitalocean/godo v1.7.5 // indirect
|
||||
github.com/dimchansky/utfbom v1.1.1 // indirect
|
||||
github.com/docker/distribution v2.7.1+incompatible // indirect
|
||||
github.com/docker/docker v20.10.10+incompatible // indirect
|
||||
github.com/docker/docker v20.10.12+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.6.4 // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-metrics v0.0.1 // indirect
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/emirpasic/gods v1.12.0 // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.5.0 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/form3tech-oss/jwt-go v3.2.5+incompatible // indirect
|
||||
github.com/go-errors/errors v1.4.1 // indirect
|
||||
github.com/go-git/gcfg v1.5.0 // indirect
|
||||
github.com/go-logr/logr v0.4.0 // indirect
|
||||
github.com/go-logr/logr v1.2.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.5 // indirect
|
||||
github.com/go-openapi/analysis v0.19.10 // indirect
|
||||
github.com/go-openapi/errors v0.19.8 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.3 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.5 // indirect
|
||||
github.com/go-openapi/loads v0.19.5 // indirect
|
||||
github.com/go-openapi/spec v0.19.8 // indirect
|
||||
github.com/go-openapi/swag v0.19.9 // indirect
|
||||
github.com/go-openapi/swag v0.19.14 // indirect
|
||||
github.com/go-openapi/validate v0.19.10 // indirect
|
||||
github.com/go-sql-driver/mysql v1.5.0 // indirect
|
||||
github.com/go-stack/stack v1.8.0 // indirect
|
||||
github.com/go-test/deep v1.0.8 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.0.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/go-metrics-stackdriver v0.2.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/gofuzz v1.1.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.0.5 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.1.1 // indirect
|
||||
github.com/googleapis/gnostic v0.5.5 // indirect
|
||||
github.com/gophercloud/gophercloud v0.1.0 // indirect
|
||||
github.com/hashicorp/consul/sdk v0.8.0 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-discover v0.0.0-20210818145131-c573d69da192 // indirect
|
||||
@ -163,7 +175,7 @@ require (
|
||||
github.com/hashicorp/go-version v1.3.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/hashicorp/hcl v1.0.1-vault-3 // indirect
|
||||
github.com/hashicorp/mdns v1.0.1 // indirect
|
||||
github.com/hashicorp/mdns v1.0.4 // indirect
|
||||
github.com/hashicorp/raft v1.3.1 // indirect
|
||||
github.com/hashicorp/raft-autopilot v0.1.3 // indirect
|
||||
github.com/hashicorp/raft-boltdb/v2 v2.0.0-20210421194847-a7e34179d62c // indirect
|
||||
@ -178,50 +190,56 @@ require (
|
||||
github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f // indirect
|
||||
github.com/jefferai/jsonx v1.0.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/jstemmer/go-junit-report v0.9.1 // indirect
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
|
||||
github.com/keybase/go-crypto v0.0.0-20190403132359-d65b6b94177f // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/lib/pq v1.10.3 // indirect
|
||||
github.com/lib/pq v1.10.4 // indirect
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||
github.com/linode/linodego v0.7.1 // indirect
|
||||
github.com/magicsong/color-glog v0.0.1 // indirect
|
||||
github.com/mailru/easyjson v0.7.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.11 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||
github.com/miekg/dns v1.1.40 // indirect
|
||||
github.com/miekg/dns v1.1.41 // indirect
|
||||
github.com/mitchellh/cli v1.1.2 // indirect
|
||||
github.com/mitchellh/copystructure v1.0.0 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/sys/mount v0.2.0 // indirect
|
||||
github.com/moby/sys/mountinfo v0.4.1 // indirect
|
||||
github.com/moby/sys/mountinfo v0.5.0 // indirect
|
||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 // indirect
|
||||
github.com/oklog/run v1.0.0 // indirect
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/onsi/ginkgo v1.16.4 // indirect
|
||||
github.com/onsi/gomega v1.16.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||
github.com/opencontainers/runc v1.0.2 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/oracle/oci-go-sdk v13.1.0+incompatible // indirect
|
||||
github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
|
||||
github.com/pierrec/lz4 v2.5.2+incompatible // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/posener/complete v1.2.3 // indirect
|
||||
github.com/prometheus/client_golang v1.11.0 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.26.0 // indirect
|
||||
github.com/prometheus/common v0.28.0 // indirect
|
||||
github.com/prometheus/procfs v0.6.0 // indirect
|
||||
github.com/rboyer/safeio v0.2.1 // indirect
|
||||
github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect
|
||||
@ -240,35 +258,41 @@ require (
|
||||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c // indirect
|
||||
github.com/vmware/govmomi v0.18.0 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
||||
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
|
||||
github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
go.mongodb.org/mongo-driver v1.7.3 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
|
||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309 // indirect
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 // indirect
|
||||
golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 // indirect
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 // indirect
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
||||
golang.org/x/tools v0.1.5 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c // indirect
|
||||
google.golang.org/grpc v1.41.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00 // indirect
|
||||
google.golang.org/grpc v1.44.0 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/resty.v1 v1.12.0 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
k8s.io/api v0.22.2 // indirect
|
||||
k8s.io/apimachinery v0.22.2 // indirect
|
||||
k8s.io/client-go v0.22.2 // indirect
|
||||
k8s.io/klog/v2 v2.9.0 // indirect
|
||||
k8s.io/api v0.23.1 // indirect
|
||||
k8s.io/apimachinery v0.23.1 // indirect
|
||||
k8s.io/cli-runtime v0.23.1 // indirect
|
||||
k8s.io/client-go v0.23.1 // indirect
|
||||
k8s.io/klog/v2 v2.30.0 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
|
||||
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b // indirect
|
||||
oras.land/oras-go v1.1.0 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
|
||||
sigs.k8s.io/kustomize/api v0.10.1 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.13.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect
|
||||
sigs.k8s.io/yaml v1.2.0 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
||||
|
@ -70,7 +70,58 @@ spec:
|
||||
aliases:
|
||||
- name: k8sAppTemplate
|
||||
type: string
|
||||
description: 'Defines the filename for the kubernetes app template (e.g. k8s_apptemplate.yaml). Within this file `image` needs to be set as `image: <image-name>` for the image to be overwritten with other parameters.'
|
||||
description: Defines the filename for the kubernetes app template (e.g. k8s_apptemplate.yaml).
|
||||
longDescription: |
|
||||
There are two supported ways for the template rendering:
|
||||
|
||||
1. For a deployments using single image, you can use a placeholder `<image-name>`, which will be replaced with the image GUN.
|
||||
```
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: app
|
||||
labels:
|
||||
app: app
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: app
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: app
|
||||
spec:
|
||||
containers:
|
||||
- name: app
|
||||
image: <image-name>
|
||||
```
|
||||
|
||||
2. Helm styled templates, with the support for multi-image deployments.
|
||||
|
||||
```
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: app
|
||||
labels:
|
||||
app: app
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: app
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: app
|
||||
spec:
|
||||
containers:
|
||||
- name: app-1
|
||||
image: "{{ .Values.image.repository}}:{{ .Values.image.tag }}"
|
||||
- name: app-2
|
||||
image: "{{ .Values.image.app_2.repository}}:{{ .Values.image.app_2.tag }}"
|
||||
```
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
|
Loading…
x
Reference in New Issue
Block a user