Skip to content

Commit

Permalink
Adapt clone step to work with customer-managed Repos (BYOG) (#4966)
Browse files Browse the repository at this point in the history
* adding byog credentials for clone command

* adding unit tests for clone body

* adding parameters

* adding optional byog parameters

* fixing typo in username

* remove aliases in config yaml

* change yaml config

* logs

* change info log

* change logs

* remove logs

* adding log statements

* remove log statements

* fixing typo in test class

* change repoTest structure

* remove comment

* remove comment

* generate

* adding unit test comments

* adding error handling

* adding isByog check

* fixing unit test

* generate

* Update manageGitRepositoryUtils_test.go

* restructure isByog parameter

* adding empty line for md linter

* adding config.yaml example to docs

* Update documentation/docs/steps/abapEnvironmentCloneGitRepo.md

Co-authored-by: Daniel Mieg <[email protected]>

* Update documentation/docs/steps/abapEnvironmentCloneGitRepo.md

Co-authored-by: Daniel Mieg <[email protected]>

* Update documentation/docs/steps/abapEnvironmentCloneGitRepo.md

Co-authored-by: Daniel Mieg <[email protected]>

* Update documentation/docs/steps/abapEnvironmentCloneGitRepo.md

Co-authored-by: Daniel Mieg <[email protected]>

* Update documentation/docs/steps/abapEnvironmentCloneGitRepo.md

Co-authored-by: Daniel Mieg <[email protected]>

* adding release

---------

Co-authored-by: Daniel Mieg <[email protected]>
  • Loading branch information
doldsimo and DanielMieg authored Jun 25, 2024
1 parent b9022dc commit 65dbd45
Show file tree
Hide file tree
Showing 14 changed files with 281 additions and 44 deletions.
10 changes: 8 additions & 2 deletions cmd/abapEnvironmentCloneGitRepo.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func runAbapEnvironmentCloneGitRepo(config *abapEnvironmentCloneGitRepoOptions,
return errors.Wrap(errConfig, "The provided configuration is not allowed")
}

repositories, errGetRepos := abaputils.GetRepositories(&abaputils.RepositoriesConfig{BranchName: config.BranchName, RepositoryName: config.RepositoryName, Repositories: config.Repositories}, false)
repositories, errGetRepos := abaputils.GetRepositories(&abaputils.RepositoriesConfig{BranchName: config.BranchName, RepositoryName: config.RepositoryName, Repositories: config.Repositories, ByogUsername: config.ByogUsername, ByogPassword: config.ByogPassword, ByogAuthMethod: config.ByogAuthMethod}, false)
if errGetRepos != nil {
return errors.Wrap(errGetRepos, "Could not read repositories")
}
Expand Down Expand Up @@ -85,12 +85,15 @@ func cloneSingleRepo(apiManager abaputils.SoftwareComponentApiManagerInterface,
log.Entry().Info("Start cloning " + logString)
abaputils.AddDefaultDashedLine(1)

alreadyCloned, activeBranch, errCheckCloned := api.GetRepository()
alreadyCloned, activeBranch, errCheckCloned, isByog := api.GetRepository()
if errCheckCloned != nil {
return errors.Wrapf(errCheckCloned, errorString)
}

if !alreadyCloned {
if isByog {
api.UpdateRepoWithBYOGCredentials(config.ByogAuthMethod, config.ByogUsername, config.ByogPassword)
}
errClone := api.Clone()
if errClone != nil {
return errors.Wrapf(errClone, errorString)
Expand Down Expand Up @@ -186,5 +189,8 @@ func convertCloneConfig(config *abapEnvironmentCloneGitRepoOptions) abaputils.Ab
subOptions.Host = config.Host
subOptions.Password = config.Password
subOptions.Username = config.Username
subOptions.ByogUsername = config.ByogUsername
subOptions.ByogPassword = config.ByogPassword
subOptions.ByogAuthMethod = config.ByogAuthMethod
return subOptions
}
50 changes: 50 additions & 0 deletions cmd/abapEnvironmentCloneGitRepo_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions documentation/docs/steps/abapEnvironmentCloneGitRepo.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,39 @@ abapEnvironmentCloneGitRepo (
cfServiceKeyName: 'cfServiceKeyName'
)
```

## Example: Cloning a Bring Your Own Git (BYOG) repository

> Feature will be available in November 2024.

Since a ByoG repository is an external repository, you must be authenticated to clone it.
For this, the corresponding credentials must be stored in Jenkins as a username and password/token.

<strong> Store the credentials: </strong> <br>
A new credential with the type username and password must be stored.<br>
`Jenkins Dashboard > Manage Jenkins > Credentials` <br>
These credentials are used to clone the ByoG repository.
More information on configuring the credentials can be found [here](https://www.jenkins.io/doc/book/using/using-credentials/).

The config.yaml should look like this:

```yaml
steps:
abapEnvironmentCloneGitRepo:
repositories: 'repos.yaml'
byogCredentialsId: 'byogCredentialsId'
abapCredentialsId: 'abapCredentialsId'
host: '1234-abcd-5678-efgh-ijk.abap.eu10.hana.ondemand.com'
```

`byogCredentialsId: 'byogCredentialsId'` is the reference to the defined credential in Jenkins. So take care that this matches with your setup.
After that, the ByoG repository that is to be cloned must be specified in the repos.yaml:
```yaml
repositories:
- name: '/DMO/REPO_BYOG'
branch: 'main'
```
After the pipeline has run through, the repository has been cloned.
3 changes: 3 additions & 0 deletions pkg/abaputils/abaputils.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,9 @@ type AbapEnvironmentRunATCCheckOptions struct {
type AbapEnvironmentOptions struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
ByogUsername string `json:"byogUsername,omitempty"`
ByogPassword string `json:"byogPassword,omitempty"`
ByogAuthMethod string `json:"byogAuthMethod,omitempty"`
Host string `json:"host,omitempty"`
CfAPIEndpoint string `json:"cfApiEndpoint,omitempty"`
CfOrg string `json:"cfOrg,omitempty"`
Expand Down
4 changes: 4 additions & 0 deletions pkg/abaputils/descriptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ type Repository struct {
Tag string `json:"tag,omitempty"`
Branch string `json:"branch,omitempty"`
CommitID string `json:"commitID,omitempty"`
ByogUsername string `json:"byogUsername"`
ByogPassword string `json:"byogPassword"`
ByogAuthMethod string `json:"byogAuthMethod"`
IsByog bool `json:",omitempty"`
VersionYAML string `json:"version,omitempty"`
Version string `json:"versionAAK"`
AdditionalPiecelist string `json:"additionalPiecelist,omitempty"`
Expand Down
36 changes: 32 additions & 4 deletions pkg/abaputils/manageGitRepositoryUtils.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func printHeader(logEntry LogResultsV2, api SoftwareComponentApiInterface) {
}
}

// GetRepositories for parsing one or multiple branches and repositories from repositories file or branchName and repositoryName configuration
// GetRepositories for parsing one or multiple branches and repositories from repositories file or branchName and repositoryName configuration
func GetRepositories(config *RepositoriesConfig, branchRequired bool) ([]Repository, error) {
var repositories = make([]Repository, 0)
if reflect.DeepEqual(RepositoriesConfig{}, config) {
Expand Down Expand Up @@ -193,6 +193,7 @@ func GetRepositories(config *RepositoriesConfig, branchRequired bool) ([]Reposit
if config.RepositoryName != "" && !branchRequired {
repositories = append(repositories, Repository{Name: config.RepositoryName, CommitID: config.CommitID})
}

if len(config.RepositoryNames) > 0 {
for _, repository := range config.RepositoryNames {
repositories = append(repositories, Repository{Name: repository})
Expand All @@ -210,6 +211,25 @@ func (repo *Repository) GetRequestBodyForCommitOrTag() (requestBodyString string
return requestBodyString
}

func (repo *Repository) GetRequestBodyForBYOGCredentials() (string, error) {
var byogBodyString string

if repo.ByogAuthMethod != "" {
byogBodyString += `, "auth_method":"` + repo.ByogAuthMethod + `"`
}
if repo.ByogUsername != "" {
byogBodyString += `, "username":"` + repo.ByogUsername + `"`
} else {
return "", fmt.Errorf("Failed to get BYOG credentials: %w", errors.New("Username for BYOG is missing, please provide git username to authenticate"))
}
if repo.ByogPassword != "" {
byogBodyString += `, "password":"` + repo.ByogPassword + `"`
} else {
return "", fmt.Errorf("Failed to get BYOG credentials: %w", errors.New("Password/Token for BYOG is missing, please provide git password or token to authenticate"))
}
return byogBodyString, nil
}

func (repo *Repository) GetLogStringForCommitOrTag() (logString string) {
if repo.CommitID != "" {
logString = ", commit '" + repo.CommitID + "'"
Expand All @@ -228,13 +248,21 @@ func (repo *Repository) GetCloneRequestBodyWithSWC() (body string) {
return body
}

func (repo *Repository) GetCloneRequestBody() (body string) {
func (repo *Repository) GetCloneRequestBody() (body string, err error) {
if repo.CommitID != "" && repo.Tag != "" {
log.Entry().WithField("Tag", repo.Tag).WithField("Commit ID", repo.CommitID).Info("The commit ID takes precedence over the tag")
}
requestBodyString := repo.GetRequestBodyForCommitOrTag()
body = `{"branch_name":"` + repo.Branch + `"` + requestBodyString + `}`
return body
var byogBodyString = ""
if repo.IsByog {
byogBodyString, err = repo.GetRequestBodyForBYOGCredentials()
if err != nil {
return "", err
}
}

body = `{"branch_name":"` + repo.Branch + `"` + requestBodyString + byogBodyString + `}`
return body, nil
}

func (repo *Repository) GetCloneLogString() (logString string) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/abaputils/manageGitRepositoryUtils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ func TestCreateRequestBodies(t *testing.T) {
CommitID: "1234567",
Tag: "myTag",
}
body := repo.GetCloneRequestBody()
body, _ := repo.GetCloneRequestBody()
assert.Equal(t, `{"branch_name":"main", "commit_id":"1234567"}`, body, "Expected different body")
})
t.Run("Clone Body Tag", func(t *testing.T) {
Expand Down
23 changes: 14 additions & 9 deletions pkg/abaputils/sap_com_0510.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,44 +225,44 @@ func (api *SAP_COM_0510) GetAction() (string, error) {
return abapStatusCode, nil
}

func (api *SAP_COM_0510) GetRepository() (bool, string, error) {
func (api *SAP_COM_0510) GetRepository() (bool, string, error, bool) {

if api.repository.Name == "" {
return false, "", errors.New("An empty string was passed for the parameter 'repositoryName'")
return false, "", errors.New("An empty string was passed for the parameter 'repositoryName'"), false
}

swcConnectionDetails := api.con
swcConnectionDetails.URL = api.con.URL + api.path + api.repositoryEntity + "('" + strings.Replace(api.repository.Name, "/", "%2F", -1) + "')"
resp, err := GetHTTPResponse("GET", swcConnectionDetails, nil, api.client)
if err != nil {
_, errRepo := HandleHTTPError(resp, err, "Reading the Repository / Software Component failed", api.con)
return false, "", errRepo
return false, "", errRepo, false
}
defer resp.Body.Close()

var body RepositoryEntity
var abapResp map[string]*json.RawMessage
bodyText, errRead := io.ReadAll(resp.Body)
if errRead != nil {
return false, "", err
return false, "", err, false
}

if err := json.Unmarshal(bodyText, &abapResp); err != nil {
return false, "", err
return false, "", err, false
}
if err := json.Unmarshal(*abapResp["d"], &body); err != nil {
return false, "", err
return false, "", err, false
}
if reflect.DeepEqual(RepositoryEntity{}, body) {
log.Entry().WithField("StatusCode", resp.Status).WithField("repositoryName", api.repository.Name).WithField("branchName", api.repository.Branch).WithField("commitID", api.repository.CommitID).WithField("Tag", api.repository.Tag).Error("Could not Clone the Repository / Software Component")
err := errors.New("Request to ABAP System not successful")
return false, "", err
return false, "", err, false
}

if body.AvailOnInst {
return true, body.ActiveBranch, nil
return true, body.ActiveBranch, nil, false
}
return false, "", err
return false, "", err, false

}

Expand Down Expand Up @@ -399,3 +399,8 @@ func (api *SAP_COM_0510) ConvertTime(logTimeStamp string) time.Time {
t := time.Unix(n, 0).UTC()
return t
}

// Dummy implementation of the "optional" method UpdateRepoWithBYOGCredentials (only used in SAP_COM_0948)
func (api *SAP_COM_0510) UpdateRepoWithBYOGCredentials(byogAuthMethod string, byogUsername string, byogPassword string) {
panic("UpdateRepoWithBYOGCredentials cannot be used in SAP_COM_0510")
}
2 changes: 1 addition & 1 deletion pkg/abaputils/sap_com_0510_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ func TestGetRepo(t *testing.T) {
assert.NoError(t, err)
assert.IsType(t, &SAP_COM_0510{}, api.(*SAP_COM_0510), "API has wrong type")

cloned, activeBranch, errAction := api.GetRepository()
cloned, activeBranch, errAction, _ := api.GetRepository()
assert.True(t, cloned)
assert.Equal(t, "testBranch1", activeBranch)
assert.NoError(t, errAction)
Expand Down
Loading

0 comments on commit 65dbd45

Please sign in to comment.