github.com/jaylevin/jenkins-library@v1.230.4/cmd/cnbBuild_generated.go (about)

     1  // Code generated by piper's step-generator. DO NOT EDIT.
     2  
     3  package cmd
     4  
     5  import (
     6  	"fmt"
     7  	"os"
     8  	"path/filepath"
     9  	"time"
    10  
    11  	"github.com/SAP/jenkins-library/pkg/config"
    12  	"github.com/SAP/jenkins-library/pkg/log"
    13  	"github.com/SAP/jenkins-library/pkg/piperenv"
    14  	"github.com/SAP/jenkins-library/pkg/splunk"
    15  	"github.com/SAP/jenkins-library/pkg/telemetry"
    16  	"github.com/SAP/jenkins-library/pkg/validation"
    17  	"github.com/spf13/cobra"
    18  )
    19  
    20  type cnbBuildOptions struct {
    21  	ContainerImageName        string                   `json:"containerImageName,omitempty"`
    22  	ContainerImageTag         string                   `json:"containerImageTag,omitempty"`
    23  	ContainerRegistryURL      string                   `json:"containerRegistryUrl,omitempty"`
    24  	Buildpacks                []string                 `json:"buildpacks,omitempty"`
    25  	BuildEnvVars              map[string]interface{}   `json:"buildEnvVars,omitempty"`
    26  	Path                      string                   `json:"path,omitempty"`
    27  	ProjectDescriptor         string                   `json:"projectDescriptor,omitempty"`
    28  	DockerConfigJSON          string                   `json:"dockerConfigJSON,omitempty"`
    29  	CustomTLSCertificateLinks []string                 `json:"customTlsCertificateLinks,omitempty"`
    30  	AdditionalTags            []string                 `json:"additionalTags,omitempty"`
    31  	Bindings                  map[string]interface{}   `json:"bindings,omitempty"`
    32  	MultipleImages            []map[string]interface{} `json:"multipleImages,omitempty"`
    33  	PreserveFiles             []string                 `json:"preserveFiles,omitempty"`
    34  }
    35  
    36  type cnbBuildCommonPipelineEnvironment struct {
    37  	container struct {
    38  		registryURL   string
    39  		imageDigest   string
    40  		imageNameTag  string
    41  		imageNames    []string
    42  		imageNameTags []string
    43  		imageDigests  []string
    44  	}
    45  }
    46  
    47  func (p *cnbBuildCommonPipelineEnvironment) persist(path, resourceName string) {
    48  	content := []struct {
    49  		category string
    50  		name     string
    51  		value    interface{}
    52  	}{
    53  		{category: "container", name: "registryUrl", value: p.container.registryURL},
    54  		{category: "container", name: "imageDigest", value: p.container.imageDigest},
    55  		{category: "container", name: "imageNameTag", value: p.container.imageNameTag},
    56  		{category: "container", name: "imageNames", value: p.container.imageNames},
    57  		{category: "container", name: "imageNameTags", value: p.container.imageNameTags},
    58  		{category: "container", name: "imageDigests", value: p.container.imageDigests},
    59  	}
    60  
    61  	errCount := 0
    62  	for _, param := range content {
    63  		err := piperenv.SetResourceParameter(path, resourceName, filepath.Join(param.category, param.name), param.value)
    64  		if err != nil {
    65  			log.Entry().WithError(err).Error("Error persisting piper environment.")
    66  			errCount++
    67  		}
    68  	}
    69  	if errCount > 0 {
    70  		log.Entry().Error("failed to persist Piper environment")
    71  	}
    72  }
    73  
    74  // CnbBuildCommand Executes Cloud Native Buildpacks.
    75  func CnbBuildCommand() *cobra.Command {
    76  	const STEP_NAME = "cnbBuild"
    77  
    78  	metadata := cnbBuildMetadata()
    79  	var stepConfig cnbBuildOptions
    80  	var startTime time.Time
    81  	var commonPipelineEnvironment cnbBuildCommonPipelineEnvironment
    82  	var logCollector *log.CollectorHook
    83  	var splunkClient *splunk.Splunk
    84  	telemetryClient := &telemetry.Telemetry{}
    85  
    86  	var createCnbBuildCmd = &cobra.Command{
    87  		Use:   STEP_NAME,
    88  		Short: "Executes Cloud Native Buildpacks.",
    89  		Long: `Executes a Cloud Native Buildpacks build for creating Docker image(s).
    90  **Important:** Please note, that the cnbBuild step is in **beta** state, and there could be breaking changes before we remove the beta notice.`,
    91  		PreRunE: func(cmd *cobra.Command, _ []string) error {
    92  			startTime = time.Now()
    93  			log.SetStepName(STEP_NAME)
    94  			log.SetVerbose(GeneralConfig.Verbose)
    95  
    96  			GeneralConfig.GitHubAccessTokens = ResolveAccessTokens(GeneralConfig.GitHubTokens)
    97  
    98  			path, _ := os.Getwd()
    99  			fatalHook := &log.FatalHook{CorrelationID: GeneralConfig.CorrelationID, Path: path}
   100  			log.RegisterHook(fatalHook)
   101  
   102  			err := PrepareConfig(cmd, &metadata, STEP_NAME, &stepConfig, config.OpenPiperFile)
   103  			if err != nil {
   104  				log.SetErrorCategory(log.ErrorConfiguration)
   105  				return err
   106  			}
   107  			log.RegisterSecret(stepConfig.DockerConfigJSON)
   108  
   109  			if len(GeneralConfig.HookConfig.SentryConfig.Dsn) > 0 {
   110  				sentryHook := log.NewSentryHook(GeneralConfig.HookConfig.SentryConfig.Dsn, GeneralConfig.CorrelationID)
   111  				log.RegisterHook(&sentryHook)
   112  			}
   113  
   114  			if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 {
   115  				splunkClient = &splunk.Splunk{}
   116  				logCollector = &log.CollectorHook{CorrelationID: GeneralConfig.CorrelationID}
   117  				log.RegisterHook(logCollector)
   118  			}
   119  
   120  			validation, err := validation.New(validation.WithJSONNamesForStructFields(), validation.WithPredefinedErrorMessages())
   121  			if err != nil {
   122  				return err
   123  			}
   124  			if err = validation.ValidateStruct(stepConfig); err != nil {
   125  				log.SetErrorCategory(log.ErrorConfiguration)
   126  				return err
   127  			}
   128  
   129  			return nil
   130  		},
   131  		Run: func(_ *cobra.Command, _ []string) {
   132  			stepTelemetryData := telemetry.CustomData{}
   133  			stepTelemetryData.ErrorCode = "1"
   134  			handler := func() {
   135  				commonPipelineEnvironment.persist(GeneralConfig.EnvRootPath, "commonPipelineEnvironment")
   136  				config.RemoveVaultSecretFiles()
   137  				stepTelemetryData.Duration = fmt.Sprintf("%v", time.Since(startTime).Milliseconds())
   138  				stepTelemetryData.ErrorCategory = log.GetErrorCategory().String()
   139  				stepTelemetryData.PiperCommitHash = GitCommit
   140  				telemetryClient.SetData(&stepTelemetryData)
   141  				telemetryClient.Send()
   142  				if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 {
   143  					splunkClient.Send(telemetryClient.GetData(), logCollector)
   144  				}
   145  			}
   146  			log.DeferExitHandler(handler)
   147  			defer handler()
   148  			telemetryClient.Initialize(GeneralConfig.NoTelemetry, STEP_NAME)
   149  			if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 {
   150  				splunkClient.Initialize(GeneralConfig.CorrelationID,
   151  					GeneralConfig.HookConfig.SplunkConfig.Dsn,
   152  					GeneralConfig.HookConfig.SplunkConfig.Token,
   153  					GeneralConfig.HookConfig.SplunkConfig.Index,
   154  					GeneralConfig.HookConfig.SplunkConfig.SendLogs)
   155  			}
   156  			cnbBuild(stepConfig, &stepTelemetryData, &commonPipelineEnvironment)
   157  			stepTelemetryData.ErrorCode = "0"
   158  			log.Entry().Info("SUCCESS")
   159  		},
   160  	}
   161  
   162  	addCnbBuildFlags(createCnbBuildCmd, &stepConfig)
   163  	return createCnbBuildCmd
   164  }
   165  
   166  func addCnbBuildFlags(cmd *cobra.Command, stepConfig *cnbBuildOptions) {
   167  	cmd.Flags().StringVar(&stepConfig.ContainerImageName, "containerImageName", os.Getenv("PIPER_containerImageName"), "Name of the container which will be built\n`cnbBuild` step will try to identify a containerImageName using the following precedence:\n  1. `containerImageName` parameter.\n  2. `project.id` field of a `project.toml` file.\n  3. `git/repository` parameter of the `commonPipelineEnvironment`.\n  4. `github/repository` parameter of the `commonPipelineEnvironment`.\nIf none of the above was found - an error will be raised.\n")
   168  	cmd.Flags().StringVar(&stepConfig.ContainerImageTag, "containerImageTag", os.Getenv("PIPER_containerImageTag"), "Tag of the container which will be built")
   169  	cmd.Flags().StringVar(&stepConfig.ContainerRegistryURL, "containerRegistryUrl", os.Getenv("PIPER_containerRegistryUrl"), "Container registry where the image should be pushed to")
   170  	cmd.Flags().StringSliceVar(&stepConfig.Buildpacks, "buildpacks", []string{}, "List of custom buildpacks to use in the form of '$HOSTNAME/$REPO[:$TAG]'.")
   171  
   172  	cmd.Flags().StringVar(&stepConfig.Path, "path", os.Getenv("PIPER_path"), "Glob that should either point to a directory with your sources or one artifact in zip format.\nThis property determines the input to the buildpack.\n")
   173  	cmd.Flags().StringVar(&stepConfig.ProjectDescriptor, "projectDescriptor", `project.toml`, "Relative path to the project.toml file.\nSee [buildpacks.io](https://buildpacks.io/docs/reference/config/project-descriptor/) for the reference.\nParameters passed to the cnbBuild step will take precedence over the parameters set in the project.toml file, except the `env` block.\nEnvironment variables declared in a project descriptor file, will be merged with the `buildEnvVars` property, with the `buildEnvVars` having a precedence.\n\n*Note*: The project descriptor path should be relative to what is set in the [path](#path) property. If the `path` property is pointing to a zip archive (e.g. jar file), project descriptor path will be relative to the root of the workspace.\n\n*Note*: Inline buildpacks (see [specification](https://buildpacks.io/docs/reference/config/project-descriptor/#build-_table-optional_)) are not supported yet.\n")
   174  	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/).")
   175  	cmd.Flags().StringSliceVar(&stepConfig.CustomTLSCertificateLinks, "customTlsCertificateLinks", []string{}, "List containing download links of custom TLS certificates. This is required to ensure trusted connections to registries with custom certificates.")
   176  	cmd.Flags().StringSliceVar(&stepConfig.AdditionalTags, "additionalTags", []string{}, "List of tags which will be pushed to the registry (additionally to the provided `containerImageTag`), e.g. \"latest\".")
   177  
   178  	cmd.Flags().StringSliceVar(&stepConfig.PreserveFiles, "preserveFiles", []string{}, "List of globs, for keeping build results in the Jenkins workspace.\n\n*Note*: globs will be calculated relative to the [path](#path) property.\n")
   179  
   180  	cmd.MarkFlagRequired("containerImageTag")
   181  	cmd.MarkFlagRequired("containerRegistryUrl")
   182  }
   183  
   184  // retrieve step metadata
   185  func cnbBuildMetadata() config.StepData {
   186  	var theMetaData = config.StepData{
   187  		Metadata: config.StepMetadata{
   188  			Name:        "cnbBuild",
   189  			Aliases:     []config.Alias{},
   190  			Description: "Executes Cloud Native Buildpacks.",
   191  		},
   192  		Spec: config.StepSpec{
   193  			Inputs: config.StepInputs{
   194  				Secrets: []config.StepSecrets{
   195  					{Name: "dockerConfigJsonCredentialsId", Description: "Jenkins 'Secret file' credentials ID containing Docker config.json (with registry credential(s)) in the following format:\n\n```json\n{\n    \"auths\": {\n            \"$server\": {\n                    \"auth\": \"base64($username + ':' + $password)\"\n            }\n    }\n}\n```\n\nExample:\n\n```json\n{\n    \"auths\": {\n            \"example.com\": {\n                    \"auth\": \"dXNlcm5hbWU6cGFzc3dvcmQ=\"\n            }\n    }\n}\n```\n", Type: "jenkins"},
   196  				},
   197  				Parameters: []config.StepParameters{
   198  					{
   199  						Name:        "containerImageName",
   200  						ResourceRef: []config.ResourceReference{},
   201  						Scope:       []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
   202  						Type:        "string",
   203  						Mandatory:   false,
   204  						Aliases:     []config.Alias{{Name: "dockerImageName"}},
   205  						Default:     os.Getenv("PIPER_containerImageName"),
   206  					},
   207  					{
   208  						Name: "containerImageTag",
   209  						ResourceRef: []config.ResourceReference{
   210  							{
   211  								Name:  "commonPipelineEnvironment",
   212  								Param: "artifactVersion",
   213  							},
   214  
   215  							{
   216  								Name:  "commonPipelineEnvironment",
   217  								Param: "git/commitId",
   218  							},
   219  						},
   220  						Scope:     []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
   221  						Type:      "string",
   222  						Mandatory: true,
   223  						Aliases:   []config.Alias{{Name: "artifactVersion"}},
   224  						Default:   os.Getenv("PIPER_containerImageTag"),
   225  					},
   226  					{
   227  						Name: "containerRegistryUrl",
   228  						ResourceRef: []config.ResourceReference{
   229  							{
   230  								Name:  "commonPipelineEnvironment",
   231  								Param: "container/registryUrl",
   232  							},
   233  						},
   234  						Scope:     []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
   235  						Type:      "string",
   236  						Mandatory: true,
   237  						Aliases:   []config.Alias{{Name: "dockerRegistryUrl"}},
   238  						Default:   os.Getenv("PIPER_containerRegistryUrl"),
   239  					},
   240  					{
   241  						Name: "buildpacks",
   242  						ResourceRef: []config.ResourceReference{
   243  							{
   244  								Name:  "commonPipelineEnvironment",
   245  								Param: "container/buildpacks",
   246  							},
   247  						},
   248  						Scope:     []string{"PARAMETERS", "STAGES", "STEPS"},
   249  						Type:      "[]string",
   250  						Mandatory: false,
   251  						Aliases:   []config.Alias{},
   252  						Default:   []string{},
   253  					},
   254  					{
   255  						Name:        "buildEnvVars",
   256  						ResourceRef: []config.ResourceReference{},
   257  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   258  						Type:        "map[string]interface{}",
   259  						Mandatory:   false,
   260  						Aliases:     []config.Alias{},
   261  					},
   262  					{
   263  						Name:        "path",
   264  						ResourceRef: []config.ResourceReference{},
   265  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   266  						Type:        "string",
   267  						Mandatory:   false,
   268  						Aliases:     []config.Alias{},
   269  						Default:     os.Getenv("PIPER_path"),
   270  					},
   271  					{
   272  						Name:        "projectDescriptor",
   273  						ResourceRef: []config.ResourceReference{},
   274  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   275  						Type:        "string",
   276  						Mandatory:   false,
   277  						Aliases:     []config.Alias{},
   278  						Default:     `project.toml`,
   279  					},
   280  					{
   281  						Name: "dockerConfigJSON",
   282  						ResourceRef: []config.ResourceReference{
   283  							{
   284  								Name:  "commonPipelineEnvironment",
   285  								Param: "custom/dockerConfigJSON",
   286  							},
   287  
   288  							{
   289  								Name: "dockerConfigJsonCredentialsId",
   290  								Type: "secret",
   291  							},
   292  
   293  							{
   294  								Name:    "dockerConfigFileVaultSecretName",
   295  								Type:    "vaultSecretFile",
   296  								Default: "docker-config",
   297  							},
   298  						},
   299  						Scope:     []string{"PARAMETERS"},
   300  						Type:      "string",
   301  						Mandatory: false,
   302  						Aliases:   []config.Alias{},
   303  						Default:   os.Getenv("PIPER_dockerConfigJSON"),
   304  					},
   305  					{
   306  						Name:        "customTlsCertificateLinks",
   307  						ResourceRef: []config.ResourceReference{},
   308  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   309  						Type:        "[]string",
   310  						Mandatory:   false,
   311  						Aliases:     []config.Alias{},
   312  						Default:     []string{},
   313  					},
   314  					{
   315  						Name:        "additionalTags",
   316  						ResourceRef: []config.ResourceReference{},
   317  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   318  						Type:        "[]string",
   319  						Mandatory:   false,
   320  						Aliases:     []config.Alias{},
   321  						Default:     []string{},
   322  					},
   323  					{
   324  						Name:        "bindings",
   325  						ResourceRef: []config.ResourceReference{},
   326  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   327  						Type:        "map[string]interface{}",
   328  						Mandatory:   false,
   329  						Aliases:     []config.Alias{},
   330  					},
   331  					{
   332  						Name:        "multipleImages",
   333  						ResourceRef: []config.ResourceReference{},
   334  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   335  						Type:        "[]map[string]interface{}",
   336  						Mandatory:   false,
   337  						Aliases:     []config.Alias{{Name: "images"}},
   338  					},
   339  					{
   340  						Name:        "preserveFiles",
   341  						ResourceRef: []config.ResourceReference{},
   342  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   343  						Type:        "[]string",
   344  						Mandatory:   false,
   345  						Aliases:     []config.Alias{},
   346  						Default:     []string{},
   347  					},
   348  				},
   349  			},
   350  			Containers: []config.Container{
   351  				{Image: "paketobuildpacks/builder:base"},
   352  			},
   353  			Outputs: config.StepOutputs{
   354  				Resources: []config.StepResources{
   355  					{
   356  						Name: "commonPipelineEnvironment",
   357  						Type: "piperEnvironment",
   358  						Parameters: []map[string]interface{}{
   359  							{"name": "container/registryUrl"},
   360  							{"name": "container/imageDigest"},
   361  							{"name": "container/imageNameTag"},
   362  							{"name": "container/imageNames", "type": "[]string"},
   363  							{"name": "container/imageNameTags", "type": "[]string"},
   364  							{"name": "container/imageDigests", "type": "[]string"},
   365  						},
   366  					},
   367  				},
   368  			},
   369  		},
   370  	}
   371  	return theMetaData
   372  }