Skip to content

Commit

Permalink
feature/pr-for-ado
Browse files Browse the repository at this point in the history
  • Loading branch information
Korjen97 committed Oct 26, 2024
1 parent c45a575 commit da0dfd5
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 2 deletions.
82 changes: 81 additions & 1 deletion internal/commands/util/pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ func NewPRDecorationCommand(prWrapper wrappers.PRWrapper, policyWrapper wrappers
`,
),
}

prDecorationAzure := PRDecorationAzure(prWrapper, policyWrapper, scansWrapper)
prDecorationGithub := PRDecorationGithub(prWrapper, policyWrapper, scansWrapper)
prDecorationGitlab := PRDecorationGitlab(prWrapper, policyWrapper, scansWrapper)

cmd.AddCommand(prDecorationAzure)
cmd.AddCommand(prDecorationGithub)
cmd.AddCommand(prDecorationGitlab)
return cmd
Expand Down Expand Up @@ -73,6 +74,38 @@ func isScanRunningOrQueued(scansWrapper wrappers.ScansWrapper, scanID string) (b
return false, nil
}

func PRDecorationAzure(prWrapper wrappers.PRWrapper, policyWrapper wrappers.PolicyWrapper, scansWrapper wrappers.ScansWrapper) *cobra.Command {
prDecorationAzure := &cobra.Command{
Use: "azure",
Short: "Decorate Azure DevOps PR with vulnerabilities",
Long: "Decorate Azure DevOps PR with vulnerabilities",
Example: heredoc.Doc(
`
$ cx utils pr azure --scan-id <scan-id> --token <AAD> --namespace <organization> --project <project-name>
--pr-number <pr number> --code-repository-url <repository-url>
`,
),
RunE: runPRDecorationAzure(prWrapper, policyWrapper, scansWrapper),
}

prDecorationAzure.Flags().String(params.ScanIDFlag, "", "Scan ID to retrieve results from")
prDecorationAzure.Flags().String(params.SCMTokenFlag, "", params.AzureTokenUsage)
prDecorationAzure.Flags().String(params.NamespaceFlag, "", fmt.Sprintf(params.NamespaceFlagUsage, "Azure DevOps"))
prDecorationAzure.Flags().String(params.ProjectName, "", "Azure DevOps project name")
prDecorationAzure.Flags().Int(params.PRNumberFlag, 0, params.PRNumberFlagUsage)
prDecorationAzure.Flags().String(params.ServerURLFlag, "", params.ServerURLFlagUsage)

_ = viper.BindPFlag(params.SCMTokenFlag, prDecorationAzure.Flags().Lookup(params.SCMTokenFlag))

_ = prDecorationAzure.MarkFlagRequired(params.ScanIDFlag)
_ = prDecorationAzure.MarkFlagRequired(params.SCMTokenFlag)
_ = prDecorationAzure.MarkFlagRequired(params.NamespaceFlag)
_ = prDecorationAzure.MarkFlagRequired(params.ProjectName)
_ = prDecorationAzure.MarkFlagRequired(params.PRNumberFlag)

return prDecorationAzure
}

func PRDecorationGithub(prWrapper wrappers.PRWrapper, policyWrapper wrappers.PolicyWrapper, scansWrapper wrappers.ScansWrapper) *cobra.Command {
prDecorationGithub := &cobra.Command{
Use: "github",
Expand Down Expand Up @@ -153,6 +186,53 @@ func PRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Pol
return prDecorationGitlab
}

func runPRDecorationAzure(prWrapper wrappers.PRWrapper, policyWrapper wrappers.PolicyWrapper, scansWrapper wrappers.ScansWrapper) func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {

scanID, _ := cmd.Flags().GetString(params.ScanIDFlag)
scmTokenFlag, _ := cmd.Flags().GetString(params.SCMTokenFlag)
organizationFlag, _ := cmd.Flags().GetString(params.NamespaceFlag)
projectFlag, _ := cmd.Flags().GetString(params.ProjectName)
prNumberFlag, _ := cmd.Flags().GetInt(params.PRNumberFlag)
serverURLFlag, _ := cmd.Flags().GetString(params.ServerURLFlag)

scanRunningOrQueued, err := isScanRunningOrQueued(scansWrapper, scanID)
if err != nil {
return err
}
if scanRunningOrQueued {
log.Println(noPRDecorationCreated)
return nil
}

policies, policyError := getScanViolatedPolicies(scansWrapper, policyWrapper, scanID, cmd)
if policyError != nil {
return errors.Errorf(policyErrorFormat, failedCreatingGithubPrDecoration)
}

prModel := &wrappers.AzurePRModel{
ScanID: scanID,
ScmToken: scmTokenFlag,
Organization: organizationFlag,
ProjectName: projectFlag,
PrNumber: prNumberFlag,
Policies: policies,
ServerUrl: serverURLFlag,
}

prResponse, errorModel, err := prWrapper.PostAzurePRDecoration(prModel)
if err != nil {
return err
}
if errorModel != nil {
return errors.Errorf(errorCodeFormat, failedCreatingGithubPrDecoration, errorModel.Code, errorModel.Message)
}

logger.Print(prResponse)
return nil
}
}

func runPRDecoration(prWrapper wrappers.PRWrapper, policyWrapper wrappers.PolicyWrapper, scansWrapper wrappers.ScansWrapper) func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
scanID, _ := cmd.Flags().GetString(params.ScanIDFlag)
Expand Down
2 changes: 2 additions & 0 deletions internal/params/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ const (
PRIidFlagUsage = "Gitlab IID (internal ID) of the merge request"
PRGitlabProjectFlag = "gitlab-project-id"
PRGitlabProjectFlagUsage = "Gitlab project ID"
ServerURLFlag = "code-repository-url"
ServerURLFlagUsage = "Code repository URL (optional for self-hosted Azure DevOps)"

// Chat (General)
ChatAPIKey = "chat-apikey"
Expand Down
26 changes: 25 additions & 1 deletion internal/wrappers/pr-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,39 @@ const (
type PRHTTPWrapper struct {
githubPath string
gitlabPath string
azurePath string
}

func NewHTTPPRWrapper(githubPath, gitlabPath string) PRWrapper {
func NewHTTPPRWrapper(githubPath, gitlabPath, azurePath string) PRWrapper {
return &PRHTTPWrapper{
githubPath: githubPath,
gitlabPath: gitlabPath,
azurePath: azurePath,
}
}

func (r *PRHTTPWrapper) PostAzurePRDecoration(model *AzurePRModel) (
string,
*WebError,
error,
) {
clientTimeout := viper.GetUint(commonParams.ClientTimeoutKey)
jsonBytes, err := json.Marshal(model)
if err != nil {
return "", nil, err
}
resp, err := SendHTTPRequestWithJSONContentType(http.MethodPost, r.azurePath, bytes.NewBuffer(jsonBytes), true, clientTimeout)
if err != nil {
return "", nil, err
}
defer func() {
if err == nil {
_ = resp.Body.Close()
}
}()
return handlePRResponseWithBody(resp, err)

}
func (r *PRHTTPWrapper) PostPRDecoration(model *PRModel) (
string,
*WebError,
Expand Down
11 changes: 11 additions & 0 deletions internal/wrappers/pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,18 @@ type GitlabPRModel struct {
Policies []PrPolicy `json:"violatedPolicyList"`
}

type AzurePRModel struct {
ScanID string `json:"scanId"`
ScmToken string `json:"scmToken"`
Organization string `json:"organization"`
ProjectName string `json:"projectName"`
PrNumber int `json:"prNumber"`
Policies []PrPolicy `json:"violatedPolicyList"`
ServerUrl string `json:"serverUrl"`
}

type PRWrapper interface {
PostPRDecoration(model *PRModel) (string, *WebError, error)
PostGitlabPRDecoration(model *GitlabPRModel) (string, *WebError, error)
PostAzurePRDecoration(model *AzurePRModel) (string, *WebError, error)
}

0 comments on commit da0dfd5

Please sign in to comment.