github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/cmd/helmExecute.go (about) 1 package cmd 2 3 import ( 4 "fmt" 5 "os" 6 "path" 7 "path/filepath" 8 9 "github.com/SAP/jenkins-library/pkg/kubernetes" 10 "github.com/SAP/jenkins-library/pkg/log" 11 "github.com/SAP/jenkins-library/pkg/piperenv" 12 "github.com/SAP/jenkins-library/pkg/telemetry" 13 "github.com/SAP/jenkins-library/pkg/versioning" 14 ) 15 16 func helmExecute(config helmExecuteOptions, telemetryData *telemetry.CustomData, commonPipelineEnvironment *helmExecuteCommonPipelineEnvironment) { 17 helmConfig := kubernetes.HelmExecuteOptions{ 18 AdditionalParameters: config.AdditionalParameters, 19 ChartPath: config.ChartPath, 20 Image: config.Image, 21 Namespace: config.Namespace, 22 KubeContext: config.KubeContext, 23 KeepFailedDeployments: config.KeepFailedDeployments, 24 KubeConfig: config.KubeConfig, 25 HelmDeployWaitSeconds: config.HelmDeployWaitSeconds, 26 DockerConfigJSON: config.DockerConfigJSON, 27 AppVersion: config.AppVersion, 28 Dependency: config.Dependency, 29 PackageDependencyUpdate: config.PackageDependencyUpdate, 30 HelmValues: config.HelmValues, 31 FilterTest: config.FilterTest, 32 DumpLogs: config.DumpLogs, 33 TargetRepositoryURL: config.TargetRepositoryURL, 34 TargetRepositoryName: config.TargetRepositoryName, 35 TargetRepositoryUser: config.TargetRepositoryUser, 36 TargetRepositoryPassword: config.TargetRepositoryPassword, 37 SourceRepositoryName: config.SourceRepositoryName, 38 SourceRepositoryURL: config.SourceRepositoryURL, 39 SourceRepositoryUser: config.SourceRepositoryUser, 40 SourceRepositoryPassword: config.SourceRepositoryPassword, 41 HelmCommand: config.HelmCommand, 42 CustomTLSCertificateLinks: config.CustomTLSCertificateLinks, 43 Version: config.Version, 44 PublishVersion: config.Version, 45 RenderSubchartNotes: config.RenderSubchartNotes, 46 } 47 48 utils := kubernetes.NewDeployUtilsBundle(helmConfig.CustomTLSCertificateLinks) 49 50 artifactOpts := versioning.Options{ 51 VersioningScheme: "library", 52 } 53 54 buildDescriptorFile := "" 55 if helmConfig.ChartPath != "" { 56 buildDescriptorFile = filepath.Join(helmConfig.ChartPath, "Chart.yaml") 57 } 58 59 artifact, err := versioning.GetArtifact("helm", buildDescriptorFile, &artifactOpts, utils) 60 if err != nil { 61 log.Entry().WithError(err).Fatalf("getting artifact information failed: %v", err) 62 } 63 artifactInfo, err := artifact.GetCoordinates() 64 if err != nil { 65 log.Entry().WithError(err).Fatalf("getting artifact coordinates failed: %v", err) 66 } 67 68 helmConfig.DeploymentName = artifactInfo.ArtifactID 69 70 if len(helmConfig.PublishVersion) == 0 { 71 helmConfig.PublishVersion = artifactInfo.Version 72 } 73 74 helmExecutor := kubernetes.NewHelmExecutor(helmConfig, utils, GeneralConfig.Verbose, log.Writer()) 75 76 // error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end 77 if err := runHelmExecute(config, helmExecutor, utils, commonPipelineEnvironment); err != nil { 78 log.Entry().WithError(err).Fatalf("step execution failed: %v", err) 79 } 80 } 81 82 func runHelmExecute(config helmExecuteOptions, helmExecutor kubernetes.HelmExecutor, utils fileHandler, commonPipelineEnvironment *helmExecuteCommonPipelineEnvironment) error { 83 if config.RenderValuesTemplate { 84 err := parseAndRenderCPETemplate(config, GeneralConfig.EnvRootPath, utils) 85 if err != nil { 86 log.Entry().WithError(err).Fatalf("failed to parse/render template: %v", err) 87 } 88 } 89 switch config.HelmCommand { 90 case "upgrade": 91 if err := helmExecutor.RunHelmUpgrade(); err != nil { 92 return fmt.Errorf("failed to execute upgrade: %v", err) 93 } 94 case "lint": 95 if err := helmExecutor.RunHelmLint(); err != nil { 96 return fmt.Errorf("failed to execute helm lint: %v", err) 97 } 98 case "install": 99 if err := helmExecutor.RunHelmInstall(); err != nil { 100 return fmt.Errorf("failed to execute helm install: %v", err) 101 } 102 case "test": 103 if err := helmExecutor.RunHelmTest(); err != nil { 104 return fmt.Errorf("failed to execute helm test: %v", err) 105 } 106 case "uninstall": 107 if err := helmExecutor.RunHelmUninstall(); err != nil { 108 return fmt.Errorf("failed to execute helm uninstall: %v", err) 109 } 110 case "dependency": 111 if err := helmExecutor.RunHelmDependency(); err != nil { 112 return fmt.Errorf("failed to execute helm dependency: %v", err) 113 } 114 case "publish": 115 targetURL, err := helmExecutor.RunHelmPublish() 116 if err != nil { 117 return fmt.Errorf("failed to execute helm publish: %v", err) 118 } 119 commonPipelineEnvironment.custom.helmChartURL = targetURL 120 default: 121 if err := runHelmExecuteDefault(config, helmExecutor, commonPipelineEnvironment); err != nil { 122 return err 123 } 124 } 125 126 return nil 127 } 128 129 func runHelmExecuteDefault(config helmExecuteOptions, helmExecutor kubernetes.HelmExecutor, commonPipelineEnvironment *helmExecuteCommonPipelineEnvironment) error { 130 if err := helmExecutor.RunHelmLint(); err != nil { 131 return fmt.Errorf("failed to execute helm lint: %v", err) 132 } 133 134 if len(config.Dependency) > 0 { 135 if err := helmExecutor.RunHelmDependency(); err != nil { 136 return fmt.Errorf("failed to execute helm dependency: %v", err) 137 } 138 } 139 140 if config.Publish { 141 targetURL, err := helmExecutor.RunHelmPublish() 142 if err != nil { 143 return fmt.Errorf("failed to execute helm publish: %v", err) 144 } 145 commonPipelineEnvironment.custom.helmChartURL = targetURL 146 } 147 148 return nil 149 } 150 151 // parseAndRenderCPETemplate allows to parse and render a template which contains references to the CPE 152 func parseAndRenderCPETemplate(config helmExecuteOptions, rootPath string, utils fileHandler) error { 153 cpe := piperenv.CPEMap{} 154 err := cpe.LoadFromDisk(path.Join(rootPath, "commonPipelineEnvironment")) 155 if err != nil { 156 return fmt.Errorf("failed to load values from commonPipelineEnvironment: %v", err) 157 } 158 159 valueFiles := []string{} 160 defaultValueFile := fmt.Sprintf("%s/%s", config.ChartPath, "values.yaml") 161 defaultValueFileExists, err := utils.FileExists(defaultValueFile) 162 if err != nil { 163 return err 164 } 165 166 if defaultValueFileExists { 167 valueFiles = append(valueFiles, defaultValueFile) 168 } else { 169 if len(config.HelmValues) == 0 { 170 return fmt.Errorf("no value file to proccess, please provide value file(s)") 171 } 172 } 173 valueFiles = append(valueFiles, config.HelmValues...) 174 175 for _, valueFile := range valueFiles { 176 cpeTemplate, err := utils.FileRead(valueFile) 177 if err != nil { 178 return fmt.Errorf("failed to read file: %v", err) 179 } 180 generated, err := cpe.ParseTemplateWithDelimiter(string(cpeTemplate), config.TemplateStartDelimiter, config.TemplateEndDelimiter) 181 if err != nil { 182 return fmt.Errorf("failed to parse template: %v", err) 183 } 184 err = utils.FileWrite(valueFile, generated.Bytes(), 0700) 185 if err != nil { 186 return fmt.Errorf("failed to update file: %v", err) 187 } 188 } 189 190 return nil 191 } 192 193 type fileHandler interface { 194 FileExists(string) (bool, error) 195 FileRead(string) ([]byte, error) 196 FileWrite(string, []byte, os.FileMode) error 197 }