2019-10-24 10:59:58 +02:00
package cmd
import (
2019-10-25 14:58:59 +02:00
"encoding/json"
2019-10-24 10:59:58 +02:00
"fmt"
"io"
"os"
2019-10-25 14:58:59 +02:00
"github.com/SAP/jenkins-library/pkg/config"
2019-11-11 10:52:44 +02:00
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/piperutils"
2019-10-25 14:58:59 +02:00
"github.com/pkg/errors"
2019-10-24 10:59:58 +02:00
"github.com/spf13/cobra"
)
2019-11-06 17:22:50 +02:00
// GeneralConfigOptions contains all global configuration options for piper binary
type GeneralConfigOptions struct {
CustomConfig string
DefaultConfig [ ] string //ordered list of Piper default configurations. Can be filePath or ENV containing JSON in format 'ENV:MY_ENV_VAR'
ParametersJSON string
2020-01-15 13:16:25 +02:00
EnvRootPath string
2019-11-06 17:22:50 +02:00
StageName string
StepConfigJSON string
StepMetadata string //metadata to be considered, can be filePath or ENV containing JSON in format 'ENV:MY_ENV_VAR'
StepName string
Verbose bool
2019-10-24 10:59:58 +02:00
}
var rootCmd = & cobra . Command {
Use : "piper" ,
Short : "Executes CI/CD steps from project 'Piper' " ,
Long : `
This project ' Piper ' binary provides a CI / CD step libary .
It contains many steps which can be used within CI / CD systems as well as directly on e . g . a developer ' s machine .
` ,
//ToDo: respect stageName to also come from parametersJSON -> first env.STAGE_NAME, second: parametersJSON, third: flag
}
2019-11-06 15:07:41 +02:00
// GeneralConfig contains global configuration flags for piper binary
2019-11-06 17:22:50 +02:00
var GeneralConfig GeneralConfigOptions
2019-10-24 10:59:58 +02:00
// Execute is the starting point of the piper command line tool
func Execute ( ) {
rootCmd . AddCommand ( ConfigCommand ( ) )
2019-10-31 14:57:29 +02:00
rootCmd . AddCommand ( VersionCommand ( ) )
2019-12-13 11:55:45 +02:00
rootCmd . AddCommand ( DetectExecuteScanCommand ( ) )
2019-10-30 10:20:25 +02:00
rootCmd . AddCommand ( KarmaExecuteTestsCommand ( ) )
2020-01-24 15:30:27 +02:00
rootCmd . AddCommand ( KubernetesDeployCommand ( ) )
2019-12-05 15:22:38 +02:00
rootCmd . AddCommand ( XsDeployCommand ( ) )
2019-11-04 17:07:30 +02:00
rootCmd . AddCommand ( GithubPublishReleaseCommand ( ) )
2019-12-16 18:34:12 +02:00
rootCmd . AddCommand ( GithubCreatePullRequestCommand ( ) )
2019-10-25 14:58:59 +02:00
addRootFlags ( rootCmd )
if err := rootCmd . Execute ( ) ; err != nil {
fmt . Println ( err )
os . Exit ( 1 )
}
}
func addRootFlags ( rootCmd * cobra . Command ) {
2019-11-06 17:22:50 +02:00
rootCmd . PersistentFlags ( ) . StringVar ( & GeneralConfig . CustomConfig , "customConfig" , ".pipeline/config.yml" , "Path to the pipeline configuration file" )
2019-11-21 17:09:57 +02:00
rootCmd . PersistentFlags ( ) . StringSliceVar ( & GeneralConfig . DefaultConfig , "defaultConfig" , [ ] string { ".pipeline/defaults.yaml" } , "Default configurations, passed as path to yaml file" )
2019-11-06 17:22:50 +02:00
rootCmd . PersistentFlags ( ) . StringVar ( & GeneralConfig . ParametersJSON , "parametersJSON" , os . Getenv ( "PIPER_parametersJSON" ) , "Parameters to be considered in JSON format" )
2020-01-15 13:16:25 +02:00
rootCmd . PersistentFlags ( ) . StringVar ( & GeneralConfig . EnvRootPath , "envRootPath" , ".pipeline" , "Root path to Piper pipeline shared environments" )
2019-11-06 17:22:50 +02:00
rootCmd . PersistentFlags ( ) . StringVar ( & GeneralConfig . StageName , "stageName" , os . Getenv ( "STAGE_NAME" ) , "Name of the stage for which configuration should be included" )
rootCmd . PersistentFlags ( ) . StringVar ( & GeneralConfig . StepConfigJSON , "stepConfigJSON" , os . Getenv ( "PIPER_stepConfigJSON" ) , "Step configuration in JSON format" )
rootCmd . PersistentFlags ( ) . BoolVarP ( & GeneralConfig . Verbose , "verbose" , "v" , false , "verbose output" )
2019-10-24 10:59:58 +02:00
2019-10-25 14:58:59 +02:00
}
// PrepareConfig reads step configuration from various sources and merges it (defaults, config file, flags, ...)
func PrepareConfig ( cmd * cobra . Command , metadata * config . StepData , stepName string , options interface { } , openFile func ( s string ) ( io . ReadCloser , error ) ) error {
filters := metadata . GetParameterFilters ( )
2020-01-15 13:16:25 +02:00
resourceParams := metadata . GetResourceParameters ( GeneralConfig . EnvRootPath , "commonPipelineEnvironment" )
2019-10-25 14:58:59 +02:00
flagValues := config . AvailableFlagValues ( cmd , & filters )
var myConfig config . Config
var stepConfig config . StepConfig
2019-11-06 17:22:50 +02:00
if len ( GeneralConfig . StepConfigJSON ) != 0 {
2019-10-25 14:58:59 +02:00
// ignore config & defaults in favor of passed stepConfigJSON
2019-11-06 17:22:50 +02:00
stepConfig = config . GetStepConfigWithJSON ( flagValues , GeneralConfig . StepConfigJSON , filters )
2019-10-25 14:58:59 +02:00
} else {
// use config & defaults
2019-11-11 10:52:44 +02:00
var customConfig io . ReadCloser
var err error
2019-10-25 14:58:59 +02:00
//accept that config file and defaults cannot be loaded since both are not mandatory here
2019-12-11 11:13:23 +02:00
{
exists , e := piperutils . FileExists ( GeneralConfig . CustomConfig )
if e != nil {
return e
2019-11-11 10:52:44 +02:00
}
2019-12-11 11:13:23 +02:00
if exists {
if customConfig , err = openFile ( GeneralConfig . CustomConfig ) ; err != nil {
errors . Wrapf ( err , "Cannot read '%s'" , GeneralConfig . CustomConfig )
}
} else {
log . Entry ( ) . Infof ( "Project config file '%s' does not exist. No project configuration available." , GeneralConfig . CustomConfig )
customConfig = nil
}
}
2019-10-25 14:58:59 +02:00
var defaultConfig [ ] io . ReadCloser
2019-11-06 17:22:50 +02:00
for _ , f := range GeneralConfig . DefaultConfig {
2019-10-25 14:58:59 +02:00
//ToDo: support also https as source
fc , _ := openFile ( f )
defaultConfig = append ( defaultConfig , fc )
}
2020-01-15 13:16:25 +02:00
stepConfig , err = myConfig . GetStepConfig ( flagValues , GeneralConfig . ParametersJSON , customConfig , defaultConfig , filters , metadata . Spec . Inputs . Parameters , resourceParams , GeneralConfig . StageName , stepName )
2019-10-25 14:58:59 +02:00
if err != nil {
return errors . Wrap ( err , "retrieving step configuration failed" )
}
2019-10-24 10:59:58 +02:00
}
2019-10-25 14:58:59 +02:00
confJSON , _ := json . Marshal ( stepConfig . Config )
json . Unmarshal ( confJSON , & options )
config . MarkFlagsWithValue ( cmd , stepConfig )
return nil
2019-10-24 10:59:58 +02:00
}