github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/cmd/writePipelineEnv.go (about) 1 package cmd 2 3 import ( 4 "bytes" 5 "crypto/aes" 6 "crypto/cipher" 7 "crypto/sha256" 8 b64 "encoding/base64" 9 "encoding/json" 10 "fmt" 11 "github.com/SAP/jenkins-library/pkg/config" 12 "io" 13 "os" 14 "path/filepath" 15 16 "github.com/SAP/jenkins-library/pkg/log" 17 "github.com/SAP/jenkins-library/pkg/piperenv" 18 "github.com/spf13/cobra" 19 ) 20 21 // WritePipelineEnv Serializes the commonPipelineEnvironment JSON to disk 22 func WritePipelineEnv() *cobra.Command { 23 var stepConfig artifactPrepareVersionOptions 24 var encryptedCPE bool 25 metadata := artifactPrepareVersionMetadata() 26 27 writePipelineEnv := &cobra.Command{ 28 Use: "writePipelineEnv", 29 Short: "Serializes the commonPipelineEnvironment JSON to disk", 30 PreRun: func(cmd *cobra.Command, args []string) { 31 path, _ := os.Getwd() 32 fatalHook := &log.FatalHook{CorrelationID: GeneralConfig.CorrelationID, Path: path} 33 log.RegisterHook(fatalHook) 34 35 err := PrepareConfig(cmd, &metadata, "", &stepConfig, config.OpenPiperFile) 36 if err != nil { 37 log.SetErrorCategory(log.ErrorConfiguration) 38 return 39 } 40 log.RegisterSecret(stepConfig.Password) 41 log.RegisterSecret(stepConfig.Username) 42 }, 43 44 Run: func(cmd *cobra.Command, args []string) { 45 err := runWritePipelineEnv(stepConfig.Password, encryptedCPE) 46 if err != nil { 47 log.Entry().Fatalf("error when writing common Pipeline environment: %v", err) 48 } 49 }, 50 } 51 52 writePipelineEnv.Flags().BoolVar(&encryptedCPE, "encryptedCPE", false, "Bool to use encryption in CPE") 53 return writePipelineEnv 54 } 55 56 func runWritePipelineEnv(stepConfigPassword string, encryptedCPE bool) error { 57 var err error 58 pipelineEnv, ok := os.LookupEnv("PIPER_pipelineEnv") 59 inBytes := []byte(pipelineEnv) 60 if !ok { 61 var err error 62 inBytes, err = io.ReadAll(os.Stdin) 63 if err != nil { 64 return err 65 } 66 } 67 if len(inBytes) == 0 { 68 return nil 69 } 70 71 // try to decrypt 72 if encryptedCPE { 73 log.Entry().Debug("trying to decrypt CPE") 74 if stepConfigPassword == "" { 75 return fmt.Errorf("empty stepConfigPassword") 76 } 77 78 inBytes, err = decrypt([]byte(stepConfigPassword), inBytes) 79 if err != nil { 80 log.Entry().Fatal(err) 81 } 82 } 83 84 commonPipelineEnv := piperenv.CPEMap{} 85 decoder := json.NewDecoder(bytes.NewReader(inBytes)) 86 decoder.UseNumber() 87 err = decoder.Decode(&commonPipelineEnv) 88 if err != nil { 89 return err 90 } 91 92 rootPath := filepath.Join(GeneralConfig.EnvRootPath, "commonPipelineEnvironment") 93 err = commonPipelineEnv.WriteToDisk(rootPath) 94 if err != nil { 95 return err 96 } 97 98 writtenBytes, err := json.MarshalIndent(commonPipelineEnv, "", "\t") 99 if err != nil { 100 return err 101 } 102 _, err = os.Stdout.Write(writtenBytes) 103 if err != nil { 104 return err 105 } 106 return nil 107 } 108 109 func decrypt(secret, base64CipherText []byte) ([]byte, error) { 110 // decode from base64 111 cipherText, err := b64.StdEncoding.DecodeString(string(base64CipherText)) 112 if err != nil { 113 return nil, fmt.Errorf("failed to decode from base64: %v", err) 114 } 115 116 // use SHA256 as key 117 key := sha256.Sum256(secret) 118 block, err := aes.NewCipher(key[:]) 119 if err != nil { 120 return nil, fmt.Errorf("failed to create new cipher: %v", err) 121 } 122 123 if len(cipherText) < aes.BlockSize { 124 return nil, fmt.Errorf("invalid ciphertext block size") 125 } 126 127 iv := cipherText[:aes.BlockSize] 128 cipherText = cipherText[aes.BlockSize:] 129 130 stream := cipher.NewCFBDecrypter(block, iv) 131 stream.XORKeyStream(cipherText, cipherText) 132 133 return cipherText, nil 134 }