Skip to content

Commit 65dbd45

Browse files
doldsimoDanielMieg
andauthored
Adapt clone step to work with customer-managed Repos (BYOG) (#4966)
* 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]>
1 parent b9022dc commit 65dbd45

14 files changed

+281
-44
lines changed

cmd/abapEnvironmentCloneGitRepo.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func runAbapEnvironmentCloneGitRepo(config *abapEnvironmentCloneGitRepoOptions,
4242
return errors.Wrap(errConfig, "The provided configuration is not allowed")
4343
}
4444

45-
repositories, errGetRepos := abaputils.GetRepositories(&abaputils.RepositoriesConfig{BranchName: config.BranchName, RepositoryName: config.RepositoryName, Repositories: config.Repositories}, false)
45+
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)
4646
if errGetRepos != nil {
4747
return errors.Wrap(errGetRepos, "Could not read repositories")
4848
}
@@ -85,12 +85,15 @@ func cloneSingleRepo(apiManager abaputils.SoftwareComponentApiManagerInterface,
8585
log.Entry().Info("Start cloning " + logString)
8686
abaputils.AddDefaultDashedLine(1)
8787

88-
alreadyCloned, activeBranch, errCheckCloned := api.GetRepository()
88+
alreadyCloned, activeBranch, errCheckCloned, isByog := api.GetRepository()
8989
if errCheckCloned != nil {
9090
return errors.Wrapf(errCheckCloned, errorString)
9191
}
9292

9393
if !alreadyCloned {
94+
if isByog {
95+
api.UpdateRepoWithBYOGCredentials(config.ByogAuthMethod, config.ByogUsername, config.ByogPassword)
96+
}
9497
errClone := api.Clone()
9598
if errClone != nil {
9699
return errors.Wrapf(errClone, errorString)
@@ -186,5 +189,8 @@ func convertCloneConfig(config *abapEnvironmentCloneGitRepoOptions) abaputils.Ab
186189
subOptions.Host = config.Host
187190
subOptions.Password = config.Password
188191
subOptions.Username = config.Username
192+
subOptions.ByogUsername = config.ByogUsername
193+
subOptions.ByogPassword = config.ByogPassword
194+
subOptions.ByogAuthMethod = config.ByogAuthMethod
189195
return subOptions
190196
}

cmd/abapEnvironmentCloneGitRepo_generated.go

+50
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

documentation/docs/steps/abapEnvironmentCloneGitRepo.md

+36
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,39 @@ abapEnvironmentCloneGitRepo (
9797
cfServiceKeyName: 'cfServiceKeyName'
9898
)
9999
```
100+
101+
## Example: Cloning a Bring Your Own Git (BYOG) repository
102+
103+
> Feature will be available in November 2024.
104+
105+
Since a ByoG repository is an external repository, you must be authenticated to clone it.
106+
For this, the corresponding credentials must be stored in Jenkins as a username and password/token.
107+
108+
<strong> Store the credentials: </strong> <br>
109+
A new credential with the type username and password must be stored.<br>
110+
`Jenkins Dashboard > Manage Jenkins > Credentials` <br>
111+
These credentials are used to clone the ByoG repository.
112+
More information on configuring the credentials can be found [here](https://www.jenkins.io/doc/book/using/using-credentials/).
113+
114+
The config.yaml should look like this:
115+
116+
```yaml
117+
steps:
118+
abapEnvironmentCloneGitRepo:
119+
repositories: 'repos.yaml'
120+
byogCredentialsId: 'byogCredentialsId'
121+
abapCredentialsId: 'abapCredentialsId'
122+
host: '1234-abcd-5678-efgh-ijk.abap.eu10.hana.ondemand.com'
123+
```
124+
125+
`byogCredentialsId: 'byogCredentialsId'` is the reference to the defined credential in Jenkins. So take care that this matches with your setup.
126+
127+
After that, the ByoG repository that is to be cloned must be specified in the repos.yaml:
128+
129+
```yaml
130+
repositories:
131+
- name: '/DMO/REPO_BYOG'
132+
branch: 'main'
133+
```
134+
135+
After the pipeline has run through, the repository has been cloned.

pkg/abaputils/abaputils.go

+3
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,9 @@ type AbapEnvironmentRunATCCheckOptions struct {
285285
type AbapEnvironmentOptions struct {
286286
Username string `json:"username,omitempty"`
287287
Password string `json:"password,omitempty"`
288+
ByogUsername string `json:"byogUsername,omitempty"`
289+
ByogPassword string `json:"byogPassword,omitempty"`
290+
ByogAuthMethod string `json:"byogAuthMethod,omitempty"`
288291
Host string `json:"host,omitempty"`
289292
CfAPIEndpoint string `json:"cfApiEndpoint,omitempty"`
290293
CfOrg string `json:"cfOrg,omitempty"`

pkg/abaputils/descriptor.go

+4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ type Repository struct {
4242
Tag string `json:"tag,omitempty"`
4343
Branch string `json:"branch,omitempty"`
4444
CommitID string `json:"commitID,omitempty"`
45+
ByogUsername string `json:"byogUsername"`
46+
ByogPassword string `json:"byogPassword"`
47+
ByogAuthMethod string `json:"byogAuthMethod"`
48+
IsByog bool `json:",omitempty"`
4549
VersionYAML string `json:"version,omitempty"`
4650
Version string `json:"versionAAK"`
4751
AdditionalPiecelist string `json:"additionalPiecelist,omitempty"`

pkg/abaputils/manageGitRepositoryUtils.go

+32-4
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ func printHeader(logEntry LogResultsV2, api SoftwareComponentApiInterface) {
163163
}
164164
}
165165

166-
// GetRepositories for parsing one or multiple branches and repositories from repositories file or branchName and repositoryName configuration
166+
// GetRepositories for parsing one or multiple branches and repositories from repositories file or branchName and repositoryName configuration
167167
func GetRepositories(config *RepositoriesConfig, branchRequired bool) ([]Repository, error) {
168168
var repositories = make([]Repository, 0)
169169
if reflect.DeepEqual(RepositoriesConfig{}, config) {
@@ -193,6 +193,7 @@ func GetRepositories(config *RepositoriesConfig, branchRequired bool) ([]Reposit
193193
if config.RepositoryName != "" && !branchRequired {
194194
repositories = append(repositories, Repository{Name: config.RepositoryName, CommitID: config.CommitID})
195195
}
196+
196197
if len(config.RepositoryNames) > 0 {
197198
for _, repository := range config.RepositoryNames {
198199
repositories = append(repositories, Repository{Name: repository})
@@ -210,6 +211,25 @@ func (repo *Repository) GetRequestBodyForCommitOrTag() (requestBodyString string
210211
return requestBodyString
211212
}
212213

214+
func (repo *Repository) GetRequestBodyForBYOGCredentials() (string, error) {
215+
var byogBodyString string
216+
217+
if repo.ByogAuthMethod != "" {
218+
byogBodyString += `, "auth_method":"` + repo.ByogAuthMethod + `"`
219+
}
220+
if repo.ByogUsername != "" {
221+
byogBodyString += `, "username":"` + repo.ByogUsername + `"`
222+
} else {
223+
return "", fmt.Errorf("Failed to get BYOG credentials: %w", errors.New("Username for BYOG is missing, please provide git username to authenticate"))
224+
}
225+
if repo.ByogPassword != "" {
226+
byogBodyString += `, "password":"` + repo.ByogPassword + `"`
227+
} else {
228+
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"))
229+
}
230+
return byogBodyString, nil
231+
}
232+
213233
func (repo *Repository) GetLogStringForCommitOrTag() (logString string) {
214234
if repo.CommitID != "" {
215235
logString = ", commit '" + repo.CommitID + "'"
@@ -228,13 +248,21 @@ func (repo *Repository) GetCloneRequestBodyWithSWC() (body string) {
228248
return body
229249
}
230250

231-
func (repo *Repository) GetCloneRequestBody() (body string) {
251+
func (repo *Repository) GetCloneRequestBody() (body string, err error) {
232252
if repo.CommitID != "" && repo.Tag != "" {
233253
log.Entry().WithField("Tag", repo.Tag).WithField("Commit ID", repo.CommitID).Info("The commit ID takes precedence over the tag")
234254
}
235255
requestBodyString := repo.GetRequestBodyForCommitOrTag()
236-
body = `{"branch_name":"` + repo.Branch + `"` + requestBodyString + `}`
237-
return body
256+
var byogBodyString = ""
257+
if repo.IsByog {
258+
byogBodyString, err = repo.GetRequestBodyForBYOGCredentials()
259+
if err != nil {
260+
return "", err
261+
}
262+
}
263+
264+
body = `{"branch_name":"` + repo.Branch + `"` + requestBodyString + byogBodyString + `}`
265+
return body, nil
238266
}
239267

240268
func (repo *Repository) GetCloneLogString() (logString string) {

pkg/abaputils/manageGitRepositoryUtils_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ func TestCreateRequestBodies(t *testing.T) {
268268
CommitID: "1234567",
269269
Tag: "myTag",
270270
}
271-
body := repo.GetCloneRequestBody()
271+
body, _ := repo.GetCloneRequestBody()
272272
assert.Equal(t, `{"branch_name":"main", "commit_id":"1234567"}`, body, "Expected different body")
273273
})
274274
t.Run("Clone Body Tag", func(t *testing.T) {

pkg/abaputils/sap_com_0510.go

+14-9
Original file line numberDiff line numberDiff line change
@@ -225,44 +225,44 @@ func (api *SAP_COM_0510) GetAction() (string, error) {
225225
return abapStatusCode, nil
226226
}
227227

228-
func (api *SAP_COM_0510) GetRepository() (bool, string, error) {
228+
func (api *SAP_COM_0510) GetRepository() (bool, string, error, bool) {
229229

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

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

243243
var body RepositoryEntity
244244
var abapResp map[string]*json.RawMessage
245245
bodyText, errRead := io.ReadAll(resp.Body)
246246
if errRead != nil {
247-
return false, "", err
247+
return false, "", err, false
248248
}
249249

250250
if err := json.Unmarshal(bodyText, &abapResp); err != nil {
251-
return false, "", err
251+
return false, "", err, false
252252
}
253253
if err := json.Unmarshal(*abapResp["d"], &body); err != nil {
254-
return false, "", err
254+
return false, "", err, false
255255
}
256256
if reflect.DeepEqual(RepositoryEntity{}, body) {
257257
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")
258258
err := errors.New("Request to ABAP System not successful")
259-
return false, "", err
259+
return false, "", err, false
260260
}
261261

262262
if body.AvailOnInst {
263-
return true, body.ActiveBranch, nil
263+
return true, body.ActiveBranch, nil, false
264264
}
265-
return false, "", err
265+
return false, "", err, false
266266

267267
}
268268

@@ -399,3 +399,8 @@ func (api *SAP_COM_0510) ConvertTime(logTimeStamp string) time.Time {
399399
t := time.Unix(n, 0).UTC()
400400
return t
401401
}
402+
403+
// Dummy implementation of the "optional" method UpdateRepoWithBYOGCredentials (only used in SAP_COM_0948)
404+
func (api *SAP_COM_0510) UpdateRepoWithBYOGCredentials(byogAuthMethod string, byogUsername string, byogPassword string) {
405+
panic("UpdateRepoWithBYOGCredentials cannot be used in SAP_COM_0510")
406+
}

pkg/abaputils/sap_com_0510_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ func TestGetRepo(t *testing.T) {
368368
assert.NoError(t, err)
369369
assert.IsType(t, &SAP_COM_0510{}, api.(*SAP_COM_0510), "API has wrong type")
370370

371-
cloned, activeBranch, errAction := api.GetRepository()
371+
cloned, activeBranch, errAction, _ := api.GetRepository()
372372
assert.True(t, cloned)
373373
assert.Equal(t, "testBranch1", activeBranch)
374374
assert.NoError(t, errAction)

0 commit comments

Comments
 (0)