github.com/SAP/jenkins-library@v1.362.0/cmd/readPipelineEnv.go (about)

     1  package cmd
     2  
     3  import (
     4  	"crypto/aes"
     5  	"crypto/cipher"
     6  	"crypto/rand"
     7  	"crypto/sha256"
     8  	"encoding/base64"
     9  	"encoding/json"
    10  	"fmt"
    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/spf13/cobra"
    15  	"io"
    16  	"os"
    17  	"path"
    18  )
    19  
    20  // ReadPipelineEnv reads the commonPipelineEnvironment from disk and outputs it as JSON
    21  func ReadPipelineEnv() *cobra.Command {
    22  	var stepConfig artifactPrepareVersionOptions
    23  	var encryptedCPE bool
    24  	metadata := artifactPrepareVersionMetadata()
    25  
    26  	readPipelineEnvCmd := &cobra.Command{
    27  		Use:   "readPipelineEnv",
    28  		Short: "Reads the commonPipelineEnvironment from disk and outputs it as JSON",
    29  		PreRun: func(cmd *cobra.Command, args []string) {
    30  			path, _ := os.Getwd()
    31  			fatalHook := &log.FatalHook{CorrelationID: GeneralConfig.CorrelationID, Path: path}
    32  			log.RegisterHook(fatalHook)
    33  
    34  			err := PrepareConfig(cmd, &metadata, "", &stepConfig, config.OpenPiperFile)
    35  			if err != nil {
    36  				log.SetErrorCategory(log.ErrorConfiguration)
    37  				return
    38  			}
    39  			log.RegisterSecret(stepConfig.Password)
    40  			log.RegisterSecret(stepConfig.Username)
    41  		},
    42  
    43  		Run: func(cmd *cobra.Command, args []string) {
    44  			err := runReadPipelineEnv(stepConfig.Password, encryptedCPE)
    45  			if err != nil {
    46  				log.Entry().Fatalf("error when writing reading Pipeline environment: %v", err)
    47  			}
    48  		},
    49  	}
    50  
    51  	readPipelineEnvCmd.Flags().BoolVar(&encryptedCPE, "encryptedCPE", false, "Bool to use encryption in CPE")
    52  	return readPipelineEnvCmd
    53  }
    54  
    55  func runReadPipelineEnv(stepConfigPassword string, encryptedCPE bool) error {
    56  	cpe := piperenv.CPEMap{}
    57  
    58  	err := cpe.LoadFromDisk(path.Join(GeneralConfig.EnvRootPath, "commonPipelineEnvironment"))
    59  	if err != nil {
    60  		return err
    61  	}
    62  
    63  	// try to encrypt
    64  	if encryptedCPE {
    65  		log.Entry().Debug("trying to encrypt CPE")
    66  		if stepConfigPassword == "" {
    67  			return fmt.Errorf("empty stepConfigPassword")
    68  		}
    69  
    70  		cpeJsonBytes, _ := json.Marshal(cpe)
    71  		encryptedCPEBytes, err := encrypt([]byte(stepConfigPassword), cpeJsonBytes)
    72  		if err != nil {
    73  			log.Entry().Fatal(err)
    74  		}
    75  
    76  		os.Stdout.Write(encryptedCPEBytes)
    77  		return nil
    78  	}
    79  
    80  	// fallback
    81  	encoder := json.NewEncoder(os.Stdout)
    82  	encoder.SetIndent("", "\t")
    83  	if err := encoder.Encode(cpe); err != nil {
    84  		return err
    85  	}
    86  
    87  	return nil
    88  }
    89  
    90  func encrypt(secret, inBytes []byte) ([]byte, error) {
    91  	// use SHA256 as key
    92  	key := sha256.Sum256(secret)
    93  	block, err := aes.NewCipher(key[:])
    94  	if err != nil {
    95  		return nil, fmt.Errorf("failed to create new cipher: %v", err)
    96  	}
    97  
    98  	// Make the cipher text a byte array of size BlockSize + the length of the message
    99  	cipherText := make([]byte, aes.BlockSize+len(inBytes))
   100  
   101  	// iv is the ciphertext up to the blocksize (16)
   102  	iv := cipherText[:aes.BlockSize]
   103  	if _, err = io.ReadFull(rand.Reader, iv); err != nil {
   104  		return nil, fmt.Errorf("failed to init iv: %v", err)
   105  	}
   106  
   107  	// Encrypt the data:
   108  	stream := cipher.NewCFBEncrypter(block, iv)
   109  	stream.XORKeyStream(cipherText[aes.BlockSize:], inBytes)
   110  
   111  	// Return string encoded in base64
   112  	return []byte(base64.StdEncoding.EncodeToString(cipherText)), err
   113  }