You've already forked sap-jenkins-library
mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-09-16 09:26:22 +02:00
Added user API key authentication method (#3748)
* changes to detectExec before master merge * changes for detectExecuteScan * self generated code added * fix syntax errors and update docu * added unit tests for fail and Group * fix failOn bug * add Groups as string array * add Groups as string array * tests and validation for groups, failOn * Updated docs and added more tests * documentation md files should not be changed * Handle merge conflicts from PR 1845 * fix merge errors * remove duplicate groups, merge error * adding buildCode and buildTool as params * switching build options * building maven modules * parameter correction * parameter correction * gnerate with new build parameter * adding comments * removing piper lib master and modifying goUtils to download 1.5.7 release * first cleaning then installing * multi module maven built * multi module maven built removing unwanted code * multi module maven built moving inside switch * testing * modifying the default use case to also call maven build * modifying the default use case to also call maven build wih -- * corrected maven build command * corrected maven build command with %v * skipping test runs * testing for MTA project with single pom * adding absolute path to m2 path * clean up * adding switch for mta and maven and removing env from containers * commiting changes for new detect step * correting log message * code clean up * unit tests changes to detectExecute * basic tests for new change * restoring piperGoUtils to download correct piper binary * code clean up * code clean up * protecodeExecuteScan -> Added authentication with user API key * protecodeExecuteScan -> updating .yml file * protecodeExecuteScan -> go generate fixed * protecodeExecuteScan -> naming convention applied for UserAPIKey parameter * protecodeExecuteScan -> extending groovy code for mapping jenkins credentials Co-authored-by: D072410 <giridhar.shenoy@sap.com> Co-authored-by: Keshav <anil.keshav@sap.com> Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com>
This commit is contained in:
@@ -100,7 +100,7 @@ func runProtecodeScan(config *protecodeExecuteScanOptions, influx *protecodeExec
|
||||
} else if len(config.FetchURL) > 0 {
|
||||
// Get filename from a fetch URL
|
||||
fileName = filepath.Base(config.FetchURL)
|
||||
log.Entry().Debugf("[DEBUG] ===> Filepath from fetch URL: %v", fileName)
|
||||
log.Entry().Debugf("[DEBUG] ===> Filename from fetch URL: %v", fileName)
|
||||
}
|
||||
|
||||
log.Entry().Debug("Execute protecode scan")
|
||||
@@ -156,12 +156,10 @@ func executeProtecodeScan(influx *protecodeExecuteScanInflux, client protecode.P
|
||||
if config.ReplaceProductID > 0 {
|
||||
|
||||
log.Entry().Infof("replaceProductID has been provided (%v) and checking ...", config.ReplaceProductID)
|
||||
// log.Entry().Debugf("[DEBUG] ===> ReplaceProductID has been provided and required to verify it: %v", config.ReplaceProductID)
|
||||
|
||||
// Validate provided product id, if not valid id then throw an error
|
||||
if client.VerifyProductID(config.ReplaceProductID) {
|
||||
log.Entry().Infof("replaceProductID has been checked and it's valid")
|
||||
// log.Entry().Debugf("[DEBUG] ===> ReplaceProductID exists")
|
||||
productID = config.ReplaceProductID
|
||||
} else {
|
||||
log.Entry().Debugf("[DEBUG] ===> ReplaceProductID doesn't exist")
|
||||
@@ -171,12 +169,10 @@ func executeProtecodeScan(influx *protecodeExecuteScanInflux, client protecode.P
|
||||
} else {
|
||||
// Get existing product id by filename
|
||||
log.Entry().Infof("replaceProductID is not provided and automatic search starts from group: %v ... ", config.Group)
|
||||
// log.Entry().Debugf("[DEBUG] ===> ReplaceProductID hasn't provided and automatic search starts... ")
|
||||
productID = client.LoadExistingProduct(config.Group, fileName)
|
||||
|
||||
if productID > 0 {
|
||||
log.Entry().Infof("Automatic search completed and found following product id: %v", productID)
|
||||
// log.Entry().Debugf("[DEBUG] ===> Returned productID: %v", productID)
|
||||
} else {
|
||||
log.Entry().Infof("Automatic search completed but not found any similar product scan, now starts new scan creation")
|
||||
}
|
||||
@@ -185,8 +181,6 @@ func executeProtecodeScan(influx *protecodeExecuteScanInflux, client protecode.P
|
||||
// check if no existing is found
|
||||
productID = uploadScanOrDeclareFetch(utils, *config, productID, client, fileName)
|
||||
|
||||
log.Entry().Debugf("[DEBUG] ===> After 'uploadScanOrDeclareFetch' returned productID: %v", productID)
|
||||
|
||||
if productID <= 0 {
|
||||
return fmt.Errorf("the product id is not valid '%d'", productID)
|
||||
}
|
||||
@@ -311,11 +305,12 @@ func createProtecodeClient(config *protecodeExecuteScanOptions) protecode.Protec
|
||||
pc := protecode.Protecode{}
|
||||
|
||||
protecodeOptions := protecode.Options{
|
||||
ServerURL: config.ServerURL,
|
||||
Logger: log.Entry().WithField("package", "SAP/jenkins-library/pkg/protecode"),
|
||||
Duration: duration,
|
||||
Username: config.Username,
|
||||
Password: config.Password,
|
||||
ServerURL: config.ServerURL,
|
||||
Logger: log.Entry().WithField("package", "SAP/jenkins-library/pkg/protecode"),
|
||||
Duration: duration,
|
||||
Username: config.Username,
|
||||
Password: config.Password,
|
||||
UserAPIKey: config.UserAPIKey,
|
||||
}
|
||||
|
||||
pc.SetOptions(protecodeOptions)
|
||||
@@ -324,34 +319,25 @@ func createProtecodeClient(config *protecodeExecuteScanOptions) protecode.Protec
|
||||
}
|
||||
|
||||
func uploadScanOrDeclareFetch(utils protecodeUtils, config protecodeExecuteScanOptions, productID int, client protecode.Protecode, fileName string) int {
|
||||
//check if the LoadExistingProduct) before returns an valid product id, than skip this
|
||||
//if !hasExisting(productID, config.VerifyOnly) {
|
||||
|
||||
log.Entry().Debugf("[DEBUG] ===> In uploadScanOrDeclareFetch: %v", productID)
|
||||
|
||||
// check if product doesn't exist then create a new one.
|
||||
if productID <= 0 {
|
||||
log.Entry().Infof("New product creation started ... ")
|
||||
// log.Entry().Debugf("[DEBUG] ===> New product creation started: %v", productID)
|
||||
productID = uploadFile(utils, config, productID, client, fileName, false)
|
||||
|
||||
log.Entry().Infof("New product has been successfully created: %v", productID)
|
||||
// log.Entry().Debugf("[DEBUG] ===> After uploading [productID < 0] file returned productID: %v", productID)
|
||||
return productID
|
||||
|
||||
// In case product already exists and "VerifyOnly (reuseExisting)" is false then we replace binary without creating a new product.
|
||||
} else if (productID > 0) && !config.VerifyOnly {
|
||||
log.Entry().Infof("Product already exists and 'VerifyOnly (reuseExisting)' is false then product (%v) binary and scan result will be replaced without creating a new product.", productID)
|
||||
// log.Entry().Debugf("[DEBUG] ===> Replace binary entry point started %v", productID)
|
||||
productID = uploadFile(utils, config, productID, client, fileName, true)
|
||||
|
||||
// log.Entry().Debugf("[DEBUG] ===> After uploading file [(productID > 0) && !config.VerifyOnly] returned productID: %v", productID)
|
||||
return productID
|
||||
|
||||
// If product already exists and "reuseExisting" option is enabled then return the latest similar scan result.
|
||||
} else {
|
||||
log.Entry().Infof("VerifyOnly (reuseExisting) option is enabled and returned productID: %v", productID)
|
||||
// log.Entry().Debugf("[DEBUG] ===> VerifyOnly (reuseExisting) option is enabled and returned productID: %v", productID)
|
||||
return productID
|
||||
}
|
||||
}
|
||||
@@ -382,7 +368,6 @@ func uploadFile(utils protecodeUtils, config protecodeExecuteScanOptions, produc
|
||||
|
||||
resultData := client.UploadScanFile(config.CleanupMode, config.Group, pathToFile, combinedFileName, version, productID, replaceBinary)
|
||||
productID = resultData.Result.ProductID
|
||||
log.Entry().Debugf("[DEBUG] ===> uploadFile return FINAL product id: %v", productID)
|
||||
}
|
||||
return productID
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@ type protecodeExecuteScanOptions struct {
|
||||
ReplaceProductID int `json:"replaceProductId,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
UserAPIKey string `json:"userAPIKey,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
CustomScanVersion string `json:"customScanVersion,omitempty"`
|
||||
VersioningModel string `json:"versioningModel,omitempty" validate:"possible-values=major major-minor semantic full"`
|
||||
@@ -174,6 +175,7 @@ BDBA (Protecode) uses a combination of static binary analysis techniques to X-ra
|
||||
log.RegisterSecret(stepConfig.DockerConfigJSON)
|
||||
log.RegisterSecret(stepConfig.Username)
|
||||
log.RegisterSecret(stepConfig.Password)
|
||||
log.RegisterSecret(stepConfig.UserAPIKey)
|
||||
|
||||
if len(GeneralConfig.HookConfig.SentryConfig.Dsn) > 0 {
|
||||
sentryHook := log.NewSentryHook(GeneralConfig.HookConfig.SentryConfig.Dsn, GeneralConfig.CorrelationID)
|
||||
@@ -254,6 +256,7 @@ func addProtecodeExecuteScanFlags(cmd *cobra.Command, stepConfig *protecodeExecu
|
||||
cmd.Flags().IntVar(&stepConfig.ReplaceProductID, "replaceProductId", 0, "Specify <replaceProductId> which application binary will be replaced and rescanned and product id remains unchanged. By using this parameter, Protecode avoids creating multiple same products. Note this will affect results and feeds. If product id is not specified, then Piper starts auto detection mechanism, more precisely it searches a product id with scanned product name in that specified group, if there are several scans have been done with the same product name then the latest scan id will be fetched from BDBA backend. After obtaining product id, Piper re-uploads / replaces new binary without affecting already existing product id.")
|
||||
cmd.Flags().StringVar(&stepConfig.Username, "username", os.Getenv("PIPER_username"), "User which is used for the protecode scan")
|
||||
cmd.Flags().StringVar(&stepConfig.Password, "password", os.Getenv("PIPER_password"), "Password which is used for the user")
|
||||
cmd.Flags().StringVar(&stepConfig.UserAPIKey, "userAPIKey", os.Getenv("PIPER_userAPIKey"), "User API key which is used for API calls. Replacement for username and password / basic authentication.")
|
||||
cmd.Flags().StringVar(&stepConfig.Version, "version", os.Getenv("PIPER_version"), "The version of the artifact to allow identification in protecode backend")
|
||||
cmd.Flags().StringVar(&stepConfig.CustomScanVersion, "customScanVersion", os.Getenv("PIPER_customScanVersion"), "A custom version used along with the uploaded scan results.")
|
||||
cmd.Flags().StringVar(&stepConfig.VersioningModel, "versioningModel", `major`, "The versioning model used for result reporting (based on the artifact version). Example 1.2.3 using `major` will result in version 1")
|
||||
@@ -277,6 +280,7 @@ func protecodeExecuteScanMetadata() config.StepData {
|
||||
Inputs: config.StepInputs{
|
||||
Secrets: []config.StepSecrets{
|
||||
{Name: "protecodeCredentialsId", Description: "Jenkins 'Username with password' credentials ID containing username and password to authenticate to the Protecode system.", Type: "jenkins"},
|
||||
{Name: "protecodeApiKeyCredentialsId", Description: "Jenkins 'Secret text' credentials ID containing API Key/token to authenticate to BDBA server.", Type: "jenkins"},
|
||||
{Name: "dockerConfigJsonCredentialsId", Description: "Jenkins 'Secret file' credentials ID containing Docker config.json (with registry credential(s)). You can create it like explained in [Prerequisites](https://www.project-piper.io/steps/protecodeExecuteScan/#prerequisites).", Type: "jenkins", Aliases: []config.Alias{{Name: "dockerCredentialsId", Deprecated: true}}},
|
||||
},
|
||||
Parameters: []config.StepParameters{
|
||||
@@ -474,6 +478,27 @@ func protecodeExecuteScanMetadata() config.StepData {
|
||||
Aliases: []config.Alias{},
|
||||
Default: os.Getenv("PIPER_password"),
|
||||
},
|
||||
{
|
||||
Name: "userAPIKey",
|
||||
ResourceRef: []config.ResourceReference{
|
||||
{
|
||||
Name: "protecodeApiKeyCredentialsId",
|
||||
Param: "userAPIKey",
|
||||
Type: "secret",
|
||||
},
|
||||
|
||||
{
|
||||
Name: "protecodeApiKeyVaultSecretName",
|
||||
Type: "vaultSecret",
|
||||
Default: "protecode",
|
||||
},
|
||||
},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: os.Getenv("PIPER_userAPIKey"),
|
||||
},
|
||||
{
|
||||
Name: "version",
|
||||
ResourceRef: []config.ResourceReference{
|
||||
|
@@ -380,7 +380,12 @@ func handleAuthentication(req *http.Request, username, password, token string) {
|
||||
// Handle authentication if not done already
|
||||
if (len(username) > 0 || len(password) > 0) && len(req.Header.Get(authHeaderKey)) == 0 {
|
||||
req.SetBasicAuth(username, password)
|
||||
log.Entry().Debug("Using Basic Authentication ****/****")
|
||||
log.Entry().Debug("Using Basic Authentication ****/****\n")
|
||||
log.Entry().Warning("------------------")
|
||||
log.Entry().Warning("*** [WARNING] *** : Basic authentication is used, recommended method is API key/token authentication")
|
||||
log.Entry().Warning("*** [WARNING] *** : Basic authentication will be deprecated in the near future, please use API key/token authentication.")
|
||||
log.Entry().Warning("*** [WARNING] *** : For more details, please refer to BDBA documentation.")
|
||||
log.Entry().Warning("------------------\n")
|
||||
}
|
||||
if len(token) > 0 && len(req.Header.Get(authHeaderKey)) == 0 {
|
||||
req.Header.Add(authHeaderKey, token)
|
||||
|
@@ -122,6 +122,7 @@ func TestSendRequest(t *testing.T) {
|
||||
passedCookies := []*http.Cookie{}
|
||||
var passedUsername string
|
||||
var passedPassword string
|
||||
|
||||
// Start a local HTTP server
|
||||
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
passedHeaders = map[string][]string{}
|
||||
@@ -154,6 +155,7 @@ func TestSendRequest(t *testing.T) {
|
||||
{client: Client{logger: log.Entry().WithField("package", "SAP/jenkins-library/pkg/http")}, method: "GET", header: map[string][]string{"Testheader": {"Test1", "Test2"}}, expected: "OK"},
|
||||
{client: Client{logger: log.Entry().WithField("package", "SAP/jenkins-library/pkg/http")}, cookies: []*http.Cookie{{Name: "TestCookie1", Value: "TestValue1"}, {Name: "TestCookie2", Value: "TestValue2"}}, method: "GET", expected: "OK"},
|
||||
{client: Client{logger: log.Entry().WithField("package", "SAP/jenkins-library/pkg/http"), username: "TestUser", password: "TestPwd"}, method: "GET", expected: "OK"},
|
||||
{client: Client{logger: log.Entry().WithField("package", "SAP/jenkins-library/pkg/http"), token: "api-token-string"}, method: "GET", expected: "OK"},
|
||||
}
|
||||
|
||||
for key, test := range tt {
|
||||
@@ -191,6 +193,14 @@ func TestSendRequest(t *testing.T) {
|
||||
assert.NotContains(t, log, fmt.Sprintf("Authorization:[Basic %s]", credentialsEncoded))
|
||||
assert.Contains(t, log, "Authorization:[<set>]")
|
||||
}
|
||||
|
||||
// Token authentication
|
||||
if len(test.client.token) > 0 {
|
||||
assert.Equal(t, test.client.token, "api-token-string")
|
||||
log := fmt.Sprintf("%s", logBuffer)
|
||||
assert.Contains(t, log, fmt.Sprintf("Using Token Authentication ****"))
|
||||
assert.Contains(t, log, "Authorization:[<set>]")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -81,7 +81,7 @@ type Triage struct {
|
||||
type User struct {
|
||||
ID int `json:"id,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Girstname string `json:"firstname,omitempty"`
|
||||
Firstname string `json:"firstname,omitempty"`
|
||||
Lastname string `json:"lastname,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
}
|
||||
@@ -107,11 +107,12 @@ func makeProtecode(opts Options) Protecode {
|
||||
|
||||
//Options struct which can be used to configure the Protecode struct
|
||||
type Options struct {
|
||||
ServerURL string
|
||||
Duration time.Duration
|
||||
Username string
|
||||
Password string
|
||||
Logger *logrus.Entry
|
||||
ServerURL string
|
||||
Duration time.Duration
|
||||
Username string
|
||||
Password string
|
||||
UserAPIKey string
|
||||
Logger *logrus.Entry
|
||||
}
|
||||
|
||||
//SetOptions setter function to set the internal properties of the protecode
|
||||
@@ -126,7 +127,15 @@ func (pc *Protecode) SetOptions(options Options) {
|
||||
pc.logger = log.Entry().WithField("package", "SAP/jenkins-library/pkg/protecode")
|
||||
}
|
||||
|
||||
httpOptions := piperHttp.ClientOptions{MaxRequestDuration: options.Duration, Username: options.Username, Password: options.Password, Logger: options.Logger}
|
||||
httpOptions := piperHttp.ClientOptions{MaxRequestDuration: options.Duration, Logger: options.Logger}
|
||||
|
||||
// If userAPIKey is not empty then we will use it for user authentication, instead of username & password
|
||||
if options.UserAPIKey != "" {
|
||||
httpOptions.Token = "Bearer " + options.UserAPIKey
|
||||
} else {
|
||||
httpOptions.Username = options.Username
|
||||
httpOptions.Password = options.Password
|
||||
}
|
||||
pc.client.SetOptions(httpOptions)
|
||||
}
|
||||
|
||||
@@ -321,28 +330,20 @@ func (pc *Protecode) LoadReport(reportFileName string, productID int) *io.ReadCl
|
||||
|
||||
// UploadScanFile upload the scan file to the protecode server
|
||||
func (pc *Protecode) UploadScanFile(cleanupMode, group, filePath, fileName, version string, productID int, replaceBinary bool) *ResultData {
|
||||
log.Entry().Debugf("[DEBUG] ===> UploadScanFile started.....")
|
||||
|
||||
deleteBinary := (cleanupMode == "binary" || cleanupMode == "complete")
|
||||
|
||||
var headers = make(map[string][]string)
|
||||
|
||||
if (replaceBinary) && (version != "") {
|
||||
log.Entry().Debugf("[DEBUG] ===> replaceBinary && version != empty ")
|
||||
headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Replace": {fmt.Sprintf("%v", productID)}, "Version": {version}}
|
||||
} else if replaceBinary {
|
||||
log.Entry().Debugf("[DEBUG] ===> replaceBinary")
|
||||
headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Replace": {fmt.Sprintf("%v", productID)}}
|
||||
} else if version != "" {
|
||||
log.Entry().Debugf("[DEBUG] ===> version != empty ")
|
||||
headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Version": {version}}
|
||||
} else {
|
||||
log.Entry().Debugf("[DEBUG] ===> replaceBinary is false and version == empty")
|
||||
headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}}
|
||||
}
|
||||
|
||||
// log.Entry().Debugf("[DEBUG] ===> Headers for UploadScanFile upload: %v", headers)
|
||||
|
||||
uploadURL := fmt.Sprintf("%v/api/upload/%v", pc.serverURL, fileName)
|
||||
|
||||
r, err := pc.client.UploadRequest(http.MethodPut, uploadURL, filePath, "file", headers, nil, "binary")
|
||||
@@ -353,20 +354,15 @@ func (pc *Protecode) UploadScanFile(cleanupMode, group, filePath, fileName, vers
|
||||
pc.logger.Info("Upload successful")
|
||||
}
|
||||
|
||||
// log.Entry().Debugf("[DEBUG] ===> Upload request r: %v", r)
|
||||
// log.Entry().Debugf("[DEBUG] ===> Upload request r.StatusCode: %v", r.StatusCode)
|
||||
|
||||
// For replaceBinary option response doesn't contain any result but just a message saying that product successfully replaced.
|
||||
if replaceBinary && r.StatusCode == 201 {
|
||||
result := new(ResultData)
|
||||
result.Result.ProductID = productID
|
||||
// log.Entry().Debugf("[DEBUG] ===> Return 'replaceBinary && r.StatusCode == 201' from 'UploadScanFile' : %v", result)
|
||||
return result
|
||||
|
||||
} else {
|
||||
result := new(ResultData)
|
||||
pc.mapResponse(r.Body, result)
|
||||
// log.Entry().Debugf("[DEBUG] ===> Return '!replaceBinary' from 'UploadScanFile' : %v", result)
|
||||
return result
|
||||
|
||||
}
|
||||
@@ -381,22 +377,15 @@ func (pc *Protecode) DeclareFetchURL(cleanupMode, group, fetchURL, version strin
|
||||
var headers = make(map[string][]string)
|
||||
|
||||
if (replaceBinary) && (version != "") {
|
||||
log.Entry().Debugf("[DEBUG][FETCH_URL] ===> replaceBinary && version != empty ")
|
||||
headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Replace": {fmt.Sprintf("%v", productID)}, "Version": {version}, "Url": {fetchURL}, "Content-Type": {"application/json"}}
|
||||
} else if replaceBinary {
|
||||
log.Entry().Debugf("[DEBUG][FETCH_URL] ===> replaceBinary")
|
||||
headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Replace": {fmt.Sprintf("%v", productID)}, "Url": {fetchURL}, "Content-Type": {"application/json"}}
|
||||
} else if version != "" {
|
||||
log.Entry().Debugf("[DEBUG][FETCH_URL] ===> version != empty ")
|
||||
headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Version": {version}, "Url": {fetchURL}, "Content-Type": {"application/json"}}
|
||||
} else {
|
||||
log.Entry().Debugf("[DEBUG][FETCH_URL] ===> replaceBinary is false and version == empty")
|
||||
headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Url": {fetchURL}, "Content-Type": {"application/json"}}
|
||||
}
|
||||
|
||||
// log.Entry().Debugf("[DEBUG] ===> Headers for fetch upload: %v", headers)
|
||||
//headers := map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Url": {fetchURL}, "Content-Type": {"application/json"}}
|
||||
|
||||
protecodeURL := fmt.Sprintf("%v/api/fetch/", pc.serverURL)
|
||||
r, statusCode, err := pc.sendAPIRequest(http.MethodPost, protecodeURL, headers)
|
||||
if err != nil {
|
||||
@@ -404,20 +393,15 @@ func (pc *Protecode) DeclareFetchURL(cleanupMode, group, fetchURL, version strin
|
||||
pc.logger.WithError(err).Fatalf("Error during declare fetch url: %v", protecodeURL)
|
||||
}
|
||||
|
||||
// log.Entry().Debugf("[DEBUG] ===> Fetch request r: %v", r)
|
||||
// log.Entry().Debugf("[DEBUG] ===> Fetch request r.StatusCode: %v", statusCode)
|
||||
|
||||
// For replaceBinary option response doesn't contain any result but just a message saying that product successfully replaced.
|
||||
if replaceBinary && statusCode == 201 {
|
||||
result := new(ResultData)
|
||||
result.Result.ProductID = productID
|
||||
// log.Entry().Debugf("[DEBUG] ===> Fetch Return 'replaceBinary && statusCode == 201' from 'DeclareFetchURL' : %v", result)
|
||||
return result
|
||||
|
||||
} else {
|
||||
result := new(ResultData)
|
||||
pc.mapResponse(*r, result)
|
||||
// log.Entry().Debugf("[DEBUG] ===> Fetch Return '!replaceBinary' from 'DeclareFetchURL' : %v", result)
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -511,8 +495,6 @@ func (pc *Protecode) pullResult(productID int) (ResultData, error) {
|
||||
|
||||
// verify provided product id
|
||||
func (pc *Protecode) VerifyProductID(ProductID int) bool {
|
||||
|
||||
// pc.logger.Debugf("[DEBUG] ===> Verification of product id started ..... : %v", ProductID)
|
||||
pc.logger.Infof("Verification of product id (%v) started ... ", ProductID)
|
||||
|
||||
// TODO: Optimise product id verification
|
||||
@@ -537,17 +519,9 @@ func (pc *Protecode) LoadExistingProduct(group string, fileName string) int {
|
||||
"acceptType": {"application/json"},
|
||||
}
|
||||
|
||||
pc.logger.Debugf("[DEBUG] ===> LoadExistingProduct searching a product (%v) with URL: %v", fileName, protecodeURL)
|
||||
// pc.logger.Infof("[DEBUG] ===> LoadExistingProduct searching a product (%v) with URL: %v", fileName, protecodeURL)
|
||||
|
||||
response := pc.loadExisting(protecodeURL, headers)
|
||||
|
||||
// pc.logger.Debugf("[DEBUG] ===> LoadExistingProduct response obj: %v", response)
|
||||
|
||||
if len(response.Products) > 0 {
|
||||
|
||||
// pc.logger.Debugf("[DEBUG] ===> LoadExistingProduct: response.Product obj: %v", response.Products)
|
||||
|
||||
// Highest product id means the latest scan for this particular product, therefore we take a product id with the highest number
|
||||
for i := 0; i < len(response.Products); i++ {
|
||||
// Check filename, it should be the same as we searched
|
||||
@@ -559,11 +533,6 @@ func (pc *Protecode) LoadExistingProduct(group string, fileName string) int {
|
||||
}
|
||||
}
|
||||
|
||||
//productID = response.Products[0].ProductID
|
||||
|
||||
pc.logger.Debugf("[DEBUG] ===> Re-use existing Protecode scan - group: %v, productID: %v", group, productID)
|
||||
|
||||
// pc.logger.Infof("Automatic product id detection completed: %v", productID)
|
||||
return productID
|
||||
}
|
||||
|
||||
|
@@ -13,6 +13,9 @@ spec:
|
||||
- name: protecodeCredentialsId
|
||||
description: Jenkins 'Username with password' credentials ID containing username and password to authenticate to the Protecode system.
|
||||
type: jenkins
|
||||
- name: protecodeApiKeyCredentialsId
|
||||
description: Jenkins 'Secret text' credentials ID containing API Key/token to authenticate to BDBA server.
|
||||
type: jenkins
|
||||
- name: dockerConfigJsonCredentialsId
|
||||
description: Jenkins 'Secret file' credentials ID containing Docker config.json (with registry credential(s)). You can create it like explained in [Prerequisites](https://www.project-piper.io/steps/protecodeExecuteScan/#prerequisites).
|
||||
type: jenkins
|
||||
@@ -199,6 +202,21 @@ spec:
|
||||
- type: vaultSecret
|
||||
name: protecodeVaultSecretName
|
||||
default: protecode
|
||||
- name: userAPIKey
|
||||
type: string
|
||||
description: User API key which is used for API calls. Replacement for username and password / basic authentication.
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
secret: true
|
||||
resourceRef:
|
||||
- name: protecodeApiKeyCredentialsId
|
||||
type: secret
|
||||
param: userAPIKey
|
||||
- type: vaultSecret
|
||||
name: protecodeApiKeyVaultSecretName
|
||||
default: protecode
|
||||
- name: version
|
||||
aliases:
|
||||
- name: artifactVersion
|
||||
|
@@ -13,6 +13,7 @@ void call(Map parameters = [:]) {
|
||||
List credentials = [
|
||||
[type: 'usernamePassword', id: 'protecodeCredentialsId', env: ['PIPER_username', 'PIPER_password']],
|
||||
[type: 'file', id: 'dockerConfigJsonCredentialsId', env: ['PIPER_dockerConfigJSON']],
|
||||
[type: 'token', id: 'protecodeApiKeyCredentialsId', env: ['PIPER_userAPIKey']],
|
||||
]
|
||||
piperExecuteBin(parameters, STEP_NAME, METADATA_FILE, credentials)
|
||||
}
|
||||
|
Reference in New Issue
Block a user