1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-10-30 23:57:50 +02:00

AAKaaS check steps to run without prior PV input (#2091)

* adding my steps

* messy step

* Update abapEnvironmentAssembly.go

* clean up

* change yaml

* corrections

* Update cloudFoundryDeploy.go

* update

* delete simulation step

* remove simulate

* Update PiperGoUtils.groovy

* Update PiperGoUtils.groovy

* Update CommonStepsTest.groovy

* add docu

* Update abapEnvironmentAssembly.md

* changes due to PR

* Update .gitignore

* b

* CV list

* Update abapEnvironmentAssembly.go

* testing with simulation

* Update abapEnvironmentAssembly.go

* remove simulation

* renaming

* Update mkdocs.yml

* moving service key to yaml and fixing code climate

* Update abapEnvironmentAssemblePackages.go

* Update abapEnvironmentAssemblePackages.go

* Update abapEnvironmentAssemblePackages.go

* Update abapEnvironmentAssemblePackages.go

* change input

* Update abapEnvironmentAssemblePackages.go

* change json tag

* fixed error handling

* documentation

* Update abapEnvironmentAssemblePackages.md

* Update abapEnvironmentAssemblePackages.md

* fixing code climate issues

* fixing code climate issues

* Update abapEnvironmentAssemblePackages.yaml

* fixing code climate issues

* Update abapEnvironmentAssemblePackages.yaml

* adding unittests

* adding unittests and improved logging

* yaml -> json

* change scope of cfServiceKeyName

* correct indentation

* Update CommonStepsTest.groovy

* maintain correct step order

* AAKaaS Checks as First Step

* remove old coding

Co-authored-by: rosemarieB <45030247+rosemarieB@users.noreply.github.com>
Co-authored-by: Daniel Mieg <56156797+DanielMieg@users.noreply.github.com>
Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com>
Co-authored-by: Chris <42861202+bluesbrother84@users.noreply.github.com>
This commit is contained in:
tiloKo
2020-09-30 10:30:53 +02:00
committed by GitHub
parent 4fec440030
commit 61dfa9d3d9
6 changed files with 161 additions and 98 deletions

View File

@@ -29,15 +29,15 @@ func abapAddonAssemblyKitCheckCVs(config abapAddonAssemblyKitCheckCVsOptions, te
func runAbapAddonAssemblyKitCheckCVs(config *abapAddonAssemblyKitCheckCVsOptions, telemetryData *telemetry.CustomData, client piperhttp.Sender,
cpe *abapAddonAssemblyKitCheckCVsCommonPipelineEnvironment, readAdoDescriptor abaputils.ReadAddonDescriptorType) error {
var addonDescriptorFromCPE abaputils.AddonDescriptor
json.Unmarshal([]byte(config.AddonDescriptor), &addonDescriptorFromCPE)
conn := new(abapbuild.Connector)
conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, client)
log.Entry().Infof("Reading Product Version Information from addonDescriptor (aka addon.yml) file: %s", config.AddonDescriptorFileName)
addonDescriptor, err := readAdoDescriptor(config.AddonDescriptorFileName)
if err != nil {
return err
}
addonDescriptor = combineYAMLRepositoriesWithCPEProduct(addonDescriptor, addonDescriptorFromCPE)
conn := new(abapbuild.Connector)
conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, client)
for i := range addonDescriptor.Repositories {
var c componentVersion
@@ -48,9 +48,20 @@ func runAbapAddonAssemblyKitCheckCVs(config *abapAddonAssemblyKitCheckCVsOptions
}
c.copyFieldsToRepo(&addonDescriptor.Repositories[i])
}
log.Entry().Info("Write the resolved versions to the CommonPipelineEnvironment")
toCPE, _ := json.Marshal(addonDescriptor)
cpe.abap.addonDescriptor = string(toCPE)
// now Software Component Versions fields are valid, but maybe Product Version was checked before, so copy that part from CPE
// we don't care for errors
// scenario 1: config.AddonDescriptor is empty since checkCVs is the first step in the pipeline, then the empty result is fine anyway
// scenario 2: for some reason config.AddonDescriptor is corrupt - then we insert the valid data but delete the repositories which will ensure issue is found later on
addonDescriptorCPE, _ := abaputils.ConstructAddonDescriptorFromJSON([]byte(config.AddonDescriptor))
if len(addonDescriptorCPE.AddonProduct) == 0 {
log.Entry().Info("No Product Version information present yet in the addonDescriptor of CommonPipelineEnvironment")
} else {
log.Entry().Infof("Information for Product Version %s taken from addonDescriptor of CommonPipelineEnvironment", addonDescriptorCPE.AddonProduct)
}
addonDescriptorCPE.SetRepositories(addonDescriptor.Repositories)
cpe.abap.addonDescriptor = string(addonDescriptorCPE.AsJSON())
log.Entry().Info("Wrote addonDescriptor to CommonPipelineEnvironment")
return nil
}

View File

@@ -29,43 +29,56 @@ func abapAddonAssemblyKitCheckPV(config abapAddonAssemblyKitCheckPVOptions, tele
func runAbapAddonAssemblyKitCheckPV(config *abapAddonAssemblyKitCheckPVOptions, telemetryData *telemetry.CustomData, client piperhttp.Sender,
cpe *abapAddonAssemblyKitCheckPVCommonPipelineEnvironment, readAdoDescriptor abaputils.ReadAddonDescriptorType) error {
var addonDescriptorFromCPE abaputils.AddonDescriptor
json.Unmarshal([]byte(config.AddonDescriptor), &addonDescriptorFromCPE)
addonDescriptor, err := readAdoDescriptor(config.AddonDescriptorFileName)
addonDescriptor = combineYAMLRepositoriesWithCPEProduct(addonDescriptor, addonDescriptorFromCPE)
if err != nil {
return err
}
conn := new(abapbuild.Connector)
conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, client)
var p productVersion
p.init(addonDescriptor, *conn)
err = p.validate()
log.Entry().Infof("Reading Product Version Information from addonDescriptor (aka addon.yml) file: %s", config.AddonDescriptorFileName)
addonDescriptor, err := readAdoDescriptor(config.AddonDescriptorFileName)
if err != nil {
return err
}
p.copyFieldsToRepo(&addonDescriptor)
log.Entry().Info("Write the resolved version to the CommonPipelineEnvironment")
toCPE, _ := json.Marshal(addonDescriptor)
cpe.abap.addonDescriptor = string(toCPE)
pv := new(productVersion).init(addonDescriptor, *conn)
err = pv.validateAndResolveVersionFields()
if err != nil {
return err
}
pv.transferVersionFields(&addonDescriptor)
// now Product Version fields are valid, but maybe Component Versions (Repositories) were checked before, so copy that part from CPE
// we don't care for errors
// scenario 1: config.AddonDescriptor is empty since checkPV is the first step in the pipeline, then the empty result is fine anyway
// scenario 2: for some reason config.AddonDescriptor is corrupt - then we insert the valid data but delete the repositories which will ensure issue is found later on
addonDescriptorCPE, _ := abaputils.ConstructAddonDescriptorFromJSON([]byte(config.AddonDescriptor))
if len(addonDescriptorCPE.Repositories) == 0 {
log.Entry().Info("No Software Component Information present yet in the addonDescriptor of CommonPipelineEnvironment")
} else {
log.Entry().Infof("Information for %v Software Component Repositories taken from addonDescriptor of CommonPipelineEnvironment", len(addonDescriptorCPE.Repositories))
}
addonDescriptor.SetRepositories(addonDescriptorCPE.Repositories)
cpe.abap.addonDescriptor = string(addonDescriptor.AsJSON())
log.Entry().Info("Wrote addonDescriptor to CommonPipelineEnvironment")
return nil
}
func (p *productVersion) init(desc abaputils.AddonDescriptor, conn abapbuild.Connector) {
func (p *productVersion) init(desc abaputils.AddonDescriptor, conn abapbuild.Connector) *productVersion {
p.Connector = conn
p.Name = desc.AddonProduct
p.VersionYAML = desc.AddonVersionYAML
return p
}
func (p *productVersion) copyFieldsToRepo(initialAddonDescriptor *abaputils.AddonDescriptor) {
func (p *productVersion) transferVersionFields(initialAddonDescriptor *abaputils.AddonDescriptor) {
initialAddonDescriptor.AddonVersion = p.Version
initialAddonDescriptor.AddonSpsLevel = p.SpsLevel
initialAddonDescriptor.AddonPatchLevel = p.PatchLevel
}
func (p *productVersion) validate() error {
log.Entry().Infof("Validate product %s version %s and resolve version", p.Name, p.VersionYAML)
func (p *productVersion) validateAndResolveVersionFields() error {
log.Entry().Infof("Validate product %s version '%s' and resolve version", p.Name, p.VersionYAML)
appendum := "/odata/aas_ocs_package/ValidateProductVersion?Name='" + p.Name + "'&Version='" + p.VersionYAML + "'"
body, err := p.Connector.Get(appendum)
if err != nil {

View File

@@ -70,7 +70,7 @@ func TestValidatePV(t *testing.T) {
Name: "/DRNMSPC/PRD01",
VersionYAML: "3.2.1",
}
err := pv.validate()
err := pv.validateAndResolveVersionFields()
assert.NoError(t, err)
assert.Equal(t, "0003", pv.Version)
assert.Equal(t, "0002", pv.SpsLevel)
@@ -86,7 +86,7 @@ func TestValidatePV(t *testing.T) {
Name: "/DRNMSPC/PRD01",
VersionYAML: "3.2.1",
}
err := pv.validate()
err := pv.validateAndResolveVersionFields()
assert.Error(t, err)
assert.Equal(t, "", pv.Version)
assert.Equal(t, "", pv.SpsLevel)
@@ -104,7 +104,7 @@ func TestCopyFieldsPV(t *testing.T) {
pv.Version = "0003"
pv.SpsLevel = "0002"
pv.PatchLevel = "0001"
pv.copyFieldsToRepo(&prodVers)
pv.transferVersionFields(&prodVers)
assert.Equal(t, "0003", prodVers.AddonVersion)
assert.Equal(t, "0002", prodVers.AddonSpsLevel)
assert.Equal(t, "0001", prodVers.AddonPatchLevel)

View File

@@ -45,7 +45,7 @@ func (conn Connector) Get(appendum string) ([]byte, error) {
url := conn.Baseurl + appendum
response, err := conn.Client.SendRequest("GET", url, nil, conn.Header, nil)
if err != nil {
if response == nil {
if response == nil || response.Body == nil {
return nil, errors.Wrap(err, "Get failed")
}
defer response.Body.Close()

View File

@@ -7,7 +7,6 @@ import (
"io"
"io/ioutil"
"net/http"
"path/filepath"
"regexp"
"strconv"
"strings"
@@ -17,7 +16,6 @@ import (
"github.com/SAP/jenkins-library/pkg/command"
piperhttp "github.com/SAP/jenkins-library/pkg/http"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/ghodss/yaml"
"github.com/pkg/errors"
)
@@ -194,42 +192,6 @@ func ConvertTime(logTimeStamp string) time.Time {
return t
}
// ReadAddonDescriptorType is the type for ReadAddonDescriptor for mocking
type ReadAddonDescriptorType func(FileName string) (AddonDescriptor, error)
// ReadAddonDescriptor parses AddonDescriptor YAML file
func ReadAddonDescriptor(FileName string) (AddonDescriptor, error) {
var addonDescriptor AddonDescriptor
var addonYAMLFile []byte
filelocation, err := filepath.Glob(FileName)
if err != nil || len(filelocation) != 1 {
return addonDescriptor, errors.New(fmt.Sprintf("Could not find %v", FileName))
}
filename, err := filepath.Abs(filelocation[0])
if err != nil {
return addonDescriptor, errors.New(fmt.Sprintf("Could not get path of %v", FileName))
}
addonYAMLFile, err = ioutil.ReadFile(filename)
if err != nil {
return addonDescriptor, errors.New(fmt.Sprintf("Could not read %v", FileName))
}
var jsonBytes []byte
jsonBytes, err = yaml.YAMLToJSON(addonYAMLFile)
if err != nil {
return addonDescriptor, errors.New(fmt.Sprintf("Could not parse %v", FileName))
}
err = json.Unmarshal(jsonBytes, &addonDescriptor)
if err != nil {
return addonDescriptor, errors.New(fmt.Sprintf("Could not unmarshal %v", FileName))
}
return addonDescriptor, nil
}
/*******************************
* Structs for specific steps *
*******************************/
@@ -322,36 +284,6 @@ type AbapBinding struct {
Env string `json:"env"`
}
// AddonDescriptor contains fields about the addonProduct
type AddonDescriptor struct {
AddonProduct string `json:"addonProduct"`
AddonVersionYAML string `json:"addonVersion"`
AddonVersion string `json:"addonVersionAAK"`
AddonUniqueID string `json:"addonUniqueID"`
CustomerID interface{} `json:"customerID"`
AddonSpsLevel string
AddonPatchLevel string
TargetVectorID string
Repositories []Repository `json:"repositories"`
}
// Repository contains fields for the repository/component version
type Repository struct {
Name string `json:"name"`
Tag string `json:"tag"`
Branch string `json:"branch"`
VersionYAML string `json:"version"`
Version string `json:"versionAAK"`
PackageName string
PackageType string
SpLevel string
PatchLevel string
PredecessorCommitID string
Status string
Namespace string
SarXMLFilePath string
}
/********************************
* Testing with a client mock *
********************************/

View File

@@ -0,0 +1,107 @@
package abaputils
import (
"encoding/json"
"fmt"
"io/ioutil"
"path/filepath"
"github.com/ghodss/yaml"
"github.com/pkg/errors"
)
// AddonDescriptor contains fields about the addonProduct
type AddonDescriptor struct {
AddonProduct string `json:"addonProduct"`
AddonVersionYAML string `json:"addonVersion"`
AddonVersion string `json:"addonVersionAAK"`
AddonUniqueID string `json:"addonUniqueID"`
CustomerID interface{} `json:"customerID"`
AddonSpsLevel string
AddonPatchLevel string
TargetVectorID string
Repositories []Repository `json:"repositories"`
}
// Repository contains fields for the repository/component version
type Repository struct {
Name string `json:"name"`
Tag string `json:"tag"`
Branch string `json:"branch"`
VersionYAML string `json:"version"`
Version string `json:"versionAAK"`
PackageName string
PackageType string
SpLevel string
PatchLevel string
PredecessorCommitID string
Status string
Namespace string
SarXMLFilePath string
}
// ReadAddonDescriptorType is the type for ReadAddonDescriptor for mocking
type ReadAddonDescriptorType func(FileName string) (AddonDescriptor, error)
// ReadAddonDescriptor parses AddonDescriptor YAML file
func ReadAddonDescriptor(FileName string) (AddonDescriptor, error) {
var addonDescriptor AddonDescriptor
err := addonDescriptor.initFromYmlFile(FileName)
return addonDescriptor, err
}
// ConstructAddonDescriptorFromJSON : Create new AddonDescriptor filled with data from JSON
func ConstructAddonDescriptorFromJSON(JSON []byte) (AddonDescriptor, error) {
var addonDescriptor AddonDescriptor
err := addonDescriptor.initFromJSON(JSON)
return addonDescriptor, err
}
// initFromYmlFile : Reads from file
func (me *AddonDescriptor) initFromYmlFile(FileName string) error {
filelocation, err := filepath.Glob(FileName)
if err != nil || len(filelocation) != 1 {
return errors.New(fmt.Sprintf("Could not find %v", FileName))
}
filename, err := filepath.Abs(filelocation[0])
if err != nil {
return errors.New(fmt.Sprintf("Could not get path of %v", FileName))
}
var yamlBytes []byte
yamlBytes, err = ioutil.ReadFile(filename)
if err != nil {
return errors.New(fmt.Sprintf("Could not read %v", FileName))
}
var jsonBytes []byte
jsonBytes, err = yaml.YAMLToJSON(yamlBytes)
if err != nil {
return errors.New(fmt.Sprintf("Could not parse %v", FileName))
}
err = me.initFromJSON(jsonBytes)
if err != nil {
return errors.New(fmt.Sprintf("Could not unmarshal %v", FileName))
}
return nil
}
// initFromJSON : Init from json
func (me *AddonDescriptor) initFromJSON(JSON []byte) error {
return json.Unmarshal(JSON, me)
}
// AsJSON : dito
func (me *AddonDescriptor) AsJSON() []byte {
//hopefully no errors should happen here or they are covered by the users unit tests
jsonBytes, _ := json.Marshal(me)
return jsonBytes
}
// SetRepositories : dito
func (me *AddonDescriptor) SetRepositories(Repositories []Repository) {
me.Repositories = Repositories
}