mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-01-18 05:18:24 +02:00
Add helm dependency command (#3669)
* Add helm dependency command * Change name of flag for package command Co-authored-by: “Vitalii <“vitalii.sidorov@sap.com”> Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com>
This commit is contained in:
parent
b6a5ceaa03
commit
d62c3d73a0
@ -17,7 +17,8 @@ func helmExecute(config helmExecuteOptions, telemetryData *telemetry.CustomData)
|
||||
KubeConfig: config.KubeConfig,
|
||||
HelmDeployWaitSeconds: config.HelmDeployWaitSeconds,
|
||||
AppVersion: config.AppVersion,
|
||||
DependencyUpdate: config.DependencyUpdate,
|
||||
Dependency: config.Dependency,
|
||||
PackageDependencyUpdate: config.PackageDependencyUpdate,
|
||||
HelmValues: config.HelmValues,
|
||||
FilterTest: config.FilterTest,
|
||||
DumpLogs: config.DumpLogs,
|
||||
@ -69,9 +70,9 @@ func runHelmExecute(config helmExecuteOptions, helmExecutor kubernetes.HelmExecu
|
||||
if err := helmExecutor.RunHelmUninstall(); err != nil {
|
||||
return fmt.Errorf("failed to execute helm uninstall: %v", err)
|
||||
}
|
||||
case "package":
|
||||
if err := helmExecutor.RunHelmPackage(); err != nil {
|
||||
return fmt.Errorf("failed to execute helm package: %v", err)
|
||||
case "dependency":
|
||||
if err := helmExecutor.RunHelmDependency(); err != nil {
|
||||
return fmt.Errorf("failed to execute helm dependency: %v", err)
|
||||
}
|
||||
case "publish":
|
||||
if err := helmExecutor.RunHelmPublish(); err != nil {
|
||||
@ -91,8 +92,10 @@ func runHelmExecuteDefault(config helmExecuteOptions, helmExecutor kubernetes.He
|
||||
return fmt.Errorf("failed to execute helm lint: %v", err)
|
||||
}
|
||||
|
||||
if err := helmExecutor.RunHelmPackage(); err != nil {
|
||||
return fmt.Errorf("failed to execute helm package: %v", err)
|
||||
if len(config.Dependency) > 0 {
|
||||
if err := helmExecutor.RunHelmDependency(); err != nil {
|
||||
return fmt.Errorf("failed to execute helm dependency: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if config.Publish {
|
||||
|
@ -30,9 +30,10 @@ type helmExecuteOptions struct {
|
||||
KubeContext string `json:"kubeContext,omitempty"`
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
DockerConfigJSON string `json:"dockerConfigJSON,omitempty"`
|
||||
HelmCommand string `json:"helmCommand,omitempty" validate:"possible-values=upgrade install lint test uninstall package publish"`
|
||||
HelmCommand string `json:"helmCommand,omitempty" validate:"possible-values=upgrade lint install test uninstall dependency publish"`
|
||||
AppVersion string `json:"appVersion,omitempty"`
|
||||
DependencyUpdate bool `json:"dependencyUpdate,omitempty"`
|
||||
Dependency string `json:"dependency,omitempty" validate:"possible-values=build list update"`
|
||||
PackageDependencyUpdate bool `json:"packageDependencyUpdate,omitempty"`
|
||||
DumpLogs bool `json:"dumpLogs,omitempty"`
|
||||
FilterTest string `json:"filterTest,omitempty"`
|
||||
CustomTLSCertificateLinks []string `json:"customTlsCertificateLinks,omitempty"`
|
||||
@ -62,15 +63,15 @@ Executes helm functionality as the package manager for Kubernetes.
|
||||
* [Helm Charts] (https://artifacthub.io/)
|
||||
` + "`" + `` + "`" + `` + "`" + `
|
||||
Available Commands:
|
||||
install install a chart
|
||||
lint examine a chart for possible issues
|
||||
package package a chart directory into a chart archive
|
||||
repo add, list, remove, update, and index chart repositories
|
||||
test run tests for a release
|
||||
uninstall uninstall a release
|
||||
upgrade upgrade a release
|
||||
verify verify that a chart at the given path has been signed and is valid
|
||||
push upload a chart to a registry
|
||||
` + "`" + `upgrade` + "`" + `, ` + "`" + `lint` + "`" + `, ` + "`" + `install` + "`" + `, ` + "`" + `test` + "`" + `, ` + "`" + `uninstall` + "`" + `, ` + "`" + `dependency` + "`" + `, ` + "`" + `publish` + "`" + `
|
||||
|
||||
upgrade upgrade a release
|
||||
lint examine a chart for possible issues
|
||||
install install a chart
|
||||
test run tests for a release
|
||||
uninstall uninstall a release
|
||||
dependency package a chart directory into a chart archive
|
||||
publish package and puslish a release
|
||||
|
||||
` + "`" + `` + "`" + `` + "`" + `
|
||||
|
||||
@ -167,9 +168,10 @@ func addHelmExecuteFlags(cmd *cobra.Command, stepConfig *helmExecuteOptions) {
|
||||
cmd.Flags().StringVar(&stepConfig.KubeContext, "kubeContext", os.Getenv("PIPER_kubeContext"), "Defines the context to use from the \"kubeconfig\" file.")
|
||||
cmd.Flags().StringVar(&stepConfig.Namespace, "namespace", `default`, "Defines the target Kubernetes namespace for the deployment.")
|
||||
cmd.Flags().StringVar(&stepConfig.DockerConfigJSON, "dockerConfigJSON", os.Getenv("PIPER_dockerConfigJSON"), "Path to the file `.docker/config.json` - this is typically provided by your CI/CD system. You can find more details about the Docker credentials in the [Docker documentation](https://docs.docker.com/engine/reference/commandline/login/).")
|
||||
cmd.Flags().StringVar(&stepConfig.HelmCommand, "helmCommand", os.Getenv("PIPER_helmCommand"), "Helm: defines the command `install`, `lint`, `package`, `test`, `upgrade` and etc.")
|
||||
cmd.Flags().StringVar(&stepConfig.HelmCommand, "helmCommand", os.Getenv("PIPER_helmCommand"), "Helm: defines the command `upgrade`, `lint`, `install`, `test`, `uninstall`, `dependency`, `publish`.")
|
||||
cmd.Flags().StringVar(&stepConfig.AppVersion, "appVersion", os.Getenv("PIPER_appVersion"), "set the appVersion on the chart to this version")
|
||||
cmd.Flags().BoolVar(&stepConfig.DependencyUpdate, "dependencyUpdate", false, "set the appVersion on the chart to this version")
|
||||
cmd.Flags().StringVar(&stepConfig.Dependency, "dependency", os.Getenv("PIPER_dependency"), "manage a chart's dependencies")
|
||||
cmd.Flags().BoolVar(&stepConfig.PackageDependencyUpdate, "packageDependencyUpdate", false, "update dependencies from \"Chart.yaml\" to dir \"charts/\" before packaging")
|
||||
cmd.Flags().BoolVar(&stepConfig.DumpLogs, "dumpLogs", false, "dump the logs from test pods (this runs after all tests are complete, but before any cleanup)")
|
||||
cmd.Flags().StringVar(&stepConfig.FilterTest, "filterTest", os.Getenv("PIPER_filterTest"), "specify tests by attribute (currently `name`) using attribute=value syntax or `!attribute=value` to exclude a test (can specify multiple or separate values with commas `name=test1,name=test2`)")
|
||||
cmd.Flags().StringSliceVar(&stepConfig.CustomTLSCertificateLinks, "customTlsCertificateLinks", []string{}, "List of download links to custom TLS certificates. This is required to ensure trusted connections to instances with repositories (like nexus) when publish flag is set to true.")
|
||||
@ -399,7 +401,16 @@ func helmExecuteMetadata() config.StepData {
|
||||
Default: os.Getenv("PIPER_appVersion"),
|
||||
},
|
||||
{
|
||||
Name: "dependencyUpdate",
|
||||
Name: "dependency",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: os.Getenv("PIPER_dependency"),
|
||||
},
|
||||
{
|
||||
Name: "packageDependencyUpdate",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "bool",
|
||||
|
@ -196,7 +196,7 @@ func TestRunHelmUninstall(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunHelmPackage(t *testing.T) {
|
||||
func TestRunHelmDependency(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testTable := []struct {
|
||||
@ -206,23 +206,23 @@ func TestRunHelmPackage(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
config: helmExecuteOptions{
|
||||
HelmCommand: "package",
|
||||
HelmCommand: "dependency",
|
||||
},
|
||||
methodError: nil,
|
||||
},
|
||||
{
|
||||
config: helmExecuteOptions{
|
||||
HelmCommand: "package",
|
||||
HelmCommand: "dependency",
|
||||
},
|
||||
methodError: errors.New("some error"),
|
||||
expectedErrStr: "failed to execute helm package: some error",
|
||||
expectedErrStr: "failed to execute helm dependency: some error",
|
||||
},
|
||||
}
|
||||
|
||||
for i, testCase := range testTable {
|
||||
t.Run(fmt.Sprint("case ", i), func(t *testing.T) {
|
||||
helmExecute := &mocks.HelmExecutor{}
|
||||
helmExecute.On("RunHelmPackage").Return(testCase.methodError)
|
||||
helmExecute.On("RunHelmDependency").Return(testCase.methodError)
|
||||
|
||||
err := runHelmExecute(testCase.config, helmExecute)
|
||||
if err != nil {
|
||||
@ -300,7 +300,7 @@ func TestRunHelmDefaultCommand(t *testing.T) {
|
||||
HelmCommand: "",
|
||||
},
|
||||
methodPackageError: errors.New("some error"),
|
||||
expectedErrStr: "failed to execute helm package: some error",
|
||||
expectedErrStr: "failed to execute helm dependency: some error",
|
||||
},
|
||||
{
|
||||
config: helmExecuteOptions{
|
||||
@ -315,7 +315,7 @@ func TestRunHelmDefaultCommand(t *testing.T) {
|
||||
t.Run(fmt.Sprint("case ", i), func(t *testing.T) {
|
||||
helmExecute := &mocks.HelmExecutor{}
|
||||
helmExecute.On("RunHelmLint").Return(testCase.methodLintError)
|
||||
helmExecute.On("RunHelmPackage").Return(testCase.methodPackageError)
|
||||
helmExecute.On("RunHelmDependency").Return(testCase.methodPackageError)
|
||||
helmExecute.On("RunHelmPublish").Return(testCase.methodPublishError)
|
||||
|
||||
err := runHelmExecute(testCase.config, helmExecute)
|
||||
|
@ -16,9 +16,9 @@ type HelmExecutor interface {
|
||||
RunHelmLint() error
|
||||
RunHelmInstall() error
|
||||
RunHelmUninstall() error
|
||||
RunHelmPackage() error
|
||||
RunHelmTest() error
|
||||
RunHelmPublish() error
|
||||
RunHelmDependency() error
|
||||
}
|
||||
|
||||
// HelmExecute struct
|
||||
@ -45,7 +45,8 @@ type HelmExecuteOptions struct {
|
||||
DockerConfigJSON string `json:"dockerConfigJSON,omitempty"`
|
||||
PackageVersion string `json:"packageVersion,omitempty"`
|
||||
AppVersion string `json:"appVersion,omitempty"`
|
||||
DependencyUpdate bool `json:"dependencyUpdate,omitempty"`
|
||||
Dependency string `json:"dependency,omitempty" validate:"possible-values=build list update"`
|
||||
PackageDependencyUpdate bool `json:"packageDependencyUpdate,omitempty"`
|
||||
DumpLogs bool `json:"dumpLogs,omitempty"`
|
||||
FilterTest string `json:"filterTest,omitempty"`
|
||||
TargetRepositoryURL string `json:"targetRepositoryURL,omitempty"`
|
||||
@ -265,7 +266,7 @@ func (h *HelmExecute) RunHelmUninstall() error {
|
||||
}
|
||||
|
||||
// RunHelmPackage is used to package a chart directory into a chart archive
|
||||
func (h *HelmExecute) RunHelmPackage() error {
|
||||
func (h *HelmExecute) runHelmPackage() error {
|
||||
err := h.runHelmInit()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute deployments: %v", err)
|
||||
@ -278,7 +279,7 @@ func (h *HelmExecute) RunHelmPackage() error {
|
||||
if len(h.config.PackageVersion) > 0 {
|
||||
helmParams = append(helmParams, "--version", h.config.PackageVersion)
|
||||
}
|
||||
if h.config.DependencyUpdate {
|
||||
if h.config.PackageDependencyUpdate {
|
||||
helmParams = append(helmParams, "--dependency-update")
|
||||
}
|
||||
if len(h.config.AppVersion) > 0 {
|
||||
@ -323,6 +324,31 @@ func (h *HelmExecute) RunHelmTest() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunHelmDependency is used to manage a chart's dependencies
|
||||
func (h *HelmExecute) RunHelmDependency() error {
|
||||
if len(h.config.Dependency) == 0 {
|
||||
return fmt.Errorf("there is no dependency value. Possible values are build, list, update")
|
||||
}
|
||||
|
||||
helmParams := []string{
|
||||
"dependency",
|
||||
}
|
||||
|
||||
helmParams = append(helmParams, h.config.Dependency)
|
||||
|
||||
helmParams = append(helmParams, h.config.ChartPath)
|
||||
|
||||
if len(h.config.AdditionalParameters) > 0 {
|
||||
helmParams = append(helmParams, h.config.AdditionalParameters...)
|
||||
}
|
||||
|
||||
if err := h.runHelmCommand(helmParams); err != nil {
|
||||
log.Entry().WithError(err).Fatal("Helm dependency call failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//RunHelmPublish is used to upload a chart to a registry
|
||||
func (h *HelmExecute) RunHelmPublish() error {
|
||||
err := h.runHelmInit()
|
||||
@ -330,6 +356,11 @@ func (h *HelmExecute) RunHelmPublish() error {
|
||||
return fmt.Errorf("failed to execute deployments: %v", err)
|
||||
}
|
||||
|
||||
err = h.runHelmPackage()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute deployments: %v", err)
|
||||
}
|
||||
|
||||
if len(h.config.TargetRepositoryURL) == 0 {
|
||||
return fmt.Errorf("there's no target repository for helm chart publishing configured")
|
||||
}
|
||||
|
@ -241,11 +241,11 @@ func TestRunHelm(t *testing.T) {
|
||||
},
|
||||
{
|
||||
config: HelmExecuteOptions{
|
||||
ChartPath: ".",
|
||||
DeploymentName: "testPackage",
|
||||
PackageVersion: "1.2.3",
|
||||
DependencyUpdate: true,
|
||||
AppVersion: "9.8.7",
|
||||
ChartPath: ".",
|
||||
DeploymentName: "testPackage",
|
||||
PackageVersion: "1.2.3",
|
||||
PackageDependencyUpdate: true,
|
||||
AppVersion: "9.8.7",
|
||||
},
|
||||
expectedConfig: []string{"package", ".", "--version", "1.2.3", "--dependency-update", "--app-version", "9.8.7"},
|
||||
},
|
||||
@ -258,7 +258,7 @@ func TestRunHelm(t *testing.T) {
|
||||
verbose: false,
|
||||
stdout: log.Writer(),
|
||||
}
|
||||
err := helmExecute.RunHelmPackage()
|
||||
err := helmExecute.runHelmPackage()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, mock.ExecCall{Exec: "helm", Params: testCase.expectedConfig}, utils.Calls[i])
|
||||
}
|
||||
@ -373,6 +373,50 @@ func TestRunHelm(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Helm dependency command", func(t *testing.T) {
|
||||
utils := newHelmMockUtilsBundle()
|
||||
|
||||
testTable := []struct {
|
||||
config HelmExecuteOptions
|
||||
expectedError error
|
||||
expectedResult []string
|
||||
}{
|
||||
{
|
||||
config: HelmExecuteOptions{
|
||||
ChartPath: ".",
|
||||
},
|
||||
expectedError: errors.New("there is no dependency value. Possible values are build, list, update"),
|
||||
expectedResult: nil,
|
||||
},
|
||||
{
|
||||
config: HelmExecuteOptions{
|
||||
ChartPath: ".",
|
||||
Dependency: "update",
|
||||
},
|
||||
expectedError: nil,
|
||||
expectedResult: []string{"dependency", "update", "."},
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testTable {
|
||||
helmExecute := HelmExecute{
|
||||
utils: utils,
|
||||
config: testCase.config,
|
||||
verbose: false,
|
||||
stdout: log.Writer(),
|
||||
}
|
||||
err := helmExecute.RunHelmDependency()
|
||||
if testCase.expectedError != nil {
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, testCase.expectedError, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, mock.ExecCall{Exec: "helm", Params: testCase.expectedResult}, utils.Calls[0])
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Helm publish command", func(t *testing.T) {
|
||||
utils := newHelmMockUtilsBundle()
|
||||
|
||||
|
@ -9,8 +9,8 @@ type HelmExecutor struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// RunHelmAdd provides a mock function with given fields:
|
||||
func (_m *HelmExecutor) RunHelmAdd() error {
|
||||
// RunHelmDependency provides a mock function with given fields:
|
||||
func (_m *HelmExecutor) RunHelmDependency() error {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 error
|
||||
@ -51,20 +51,6 @@ func (_m *HelmExecutor) RunHelmLint() error {
|
||||
return r0
|
||||
}
|
||||
|
||||
// RunHelmPackage provides a mock function with given fields:
|
||||
func (_m *HelmExecutor) RunHelmPackage() error {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func() error); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// RunHelmPublish provides a mock function with given fields:
|
||||
func (_m *HelmExecutor) RunHelmPublish() error {
|
||||
ret := _m.Called()
|
||||
|
@ -11,15 +11,15 @@ metadata:
|
||||
* [Helm Charts] (https://artifacthub.io/)
|
||||
```
|
||||
Available Commands:
|
||||
install install a chart
|
||||
lint examine a chart for possible issues
|
||||
package package a chart directory into a chart archive
|
||||
repo add, list, remove, update, and index chart repositories
|
||||
test run tests for a release
|
||||
uninstall uninstall a release
|
||||
upgrade upgrade a release
|
||||
verify verify that a chart at the given path has been signed and is valid
|
||||
push upload a chart to a registry
|
||||
`upgrade`, `lint`, `install`, `test`, `uninstall`, `dependency`, `publish`
|
||||
|
||||
upgrade upgrade a release
|
||||
lint examine a chart for possible issues
|
||||
install install a chart
|
||||
test run tests for a release
|
||||
uninstall uninstall a release
|
||||
dependency package a chart directory into a chart archive
|
||||
publish package and puslish a release
|
||||
|
||||
```
|
||||
|
||||
@ -189,18 +189,18 @@ spec:
|
||||
default: docker-config
|
||||
- name: helmCommand
|
||||
type: string
|
||||
description: "Helm: defines the command `install`, `lint`, `package`, `test`, `upgrade` and etc."
|
||||
description: "Helm: defines the command `upgrade`, `lint`, `install`, `test`, `uninstall`, `dependency`, `publish`."
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
possibleValues:
|
||||
- upgrade
|
||||
- install
|
||||
- lint
|
||||
- install
|
||||
- test
|
||||
- uninstall
|
||||
- package
|
||||
- dependency
|
||||
- publish
|
||||
- name: appVersion
|
||||
type: string
|
||||
@ -210,9 +210,20 @@ spec:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: dependencyUpdate
|
||||
- name: dependency
|
||||
type: string
|
||||
description: "manage a chart's dependencies"
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
possibleValues:
|
||||
- build
|
||||
- list
|
||||
- update
|
||||
- name: packageDependencyUpdate
|
||||
type: bool
|
||||
description: set the appVersion on the chart to this version
|
||||
description: update dependencies from "Chart.yaml" to dir "charts/" before packaging
|
||||
default: false
|
||||
scope:
|
||||
- GENERAL
|
||||
|
Loading…
x
Reference in New Issue
Block a user