Skip to content

Commit 41db6e7

Browse files
authored
Add repo options to attest and artifact commands (#708)
* Move connecting to k8s cluster later in snapshot command This means config is validated before connecting to cluster and allows us to run config validation tests without a k8s cluster being available. * Add repo-id, repo-url and repo-provider options to attest artifact * Infer repo provider from provided environment variables * Ensure repository flag can be set and overrides the repoName This applies to all attest commands * Ensure GitRepoInfo is only sent if repoId and repoName are present They might be inferred from environment variables or set directly in options * Add repo options to begin trail command * Add tests for new attest flags in each attest command * Kosli API needs repo id, name AND url Ensure that all 3 pieces of information are present before adding GitRepoInfo to API call * Update docs for snyk attestation to include repo options * Remove circleci as a repo provider. It does not provide git repos * Add warning if repo information is not sent Must have repo ID, URL and Name present to send repo info * Only validate repo-url if it is explicitly provided. Don't want to break CI flows if repoURL is inferred from CI environment variables
1 parent 480badd commit 41db6e7

30 files changed

Lines changed: 417 additions & 47 deletions

cmd/kosli/attestArtifact.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ type attestArtifactOptions struct {
2323
externalFingerprints map[string]string
2424
externalURLs map[string]string
2525
annotations map[string]string
26+
repoID string
27+
repoName string
28+
repoURL string
29+
repoProvider string
2630
}
2731

2832
type AttestArtifactPayload struct {
@@ -118,6 +122,11 @@ func newAttestArtifactCmd(out io.Writer) *cobra.Command {
118122
if err != nil {
119123
return ErrorBeforePrintingUsage(cmd, err.Error())
120124
}
125+
126+
if err := validateRepoFlags(o.repoURL, o.repoProvider, cmd.Flags().Changed("repo-url")); err != nil {
127+
return err
128+
}
129+
121130
return ValidateRegistryFlags(cmd, o.fingerprintOptions)
122131
},
123132
RunE: func(cmd *cobra.Command, args []string) error {
@@ -139,6 +148,10 @@ func newAttestArtifactCmd(out io.Writer) *cobra.Command {
139148
cmd.Flags().StringToStringVar(&o.externalFingerprints, "external-fingerprint", map[string]string{}, externalFingerprintFlag)
140149
cmd.Flags().StringToStringVar(&o.externalURLs, "external-url", map[string]string{}, externalURLFlag)
141150
cmd.Flags().StringToStringVar(&o.annotations, "annotate", map[string]string{}, annotationFlag)
151+
cmd.Flags().StringVar(&o.repoID, "repo-id", DefaultValue(ci, "repo-id"), repoIDFlag)
152+
cmd.Flags().StringVar(&o.repoName, "repository", DefaultValue(ci, "repository"), repoNameFlag)
153+
cmd.Flags().StringVar(&o.repoURL, "repo-url", DefaultValue(ci, "repo-url"), repoURLFlag)
154+
cmd.Flags().StringVar(&o.repoProvider, "repo-provider", DefaultValue(ci, "repo-provider"), repoProviderFlag)
142155
addFingerprintFlags(cmd, o.fingerprintOptions)
143156

144157
addDryRunFlag(cmd)
@@ -194,6 +207,7 @@ func (o *attestArtifactOptions) run(args []string) error {
194207
if err != nil {
195208
logger.Warn("failed to get git repo info. %s", err.Error())
196209
}
210+
o.payload.GitRepoInfo = mergeGitRepoInfo(o.payload.GitRepoInfo, o.repoID, o.repoName, o.repoURL, o.repoProvider)
197211
o.payload.GitCommit = commitInfo.Sha1
198212
o.payload.GitCommitInfo = &commitInfo.BasicCommitInfo
199213

cmd/kosli/attestArtifact_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,28 @@ func (suite *AttestArtifactCommandTestSuite) TestAttestArtifactCmd() {
111111
cmd: fmt.Sprintf("attest artifact testdata/file1 --artifact-type file --redact-commit-info author,bar --name cli --commit HEAD --build-url http://www.example.com --commit-url http://www.example.com %s", suite.defaultKosliArguments),
112112
golden: "Error: bar is not an allowed value for --redact-commit-info\n",
113113
},
114+
{
115+
wantError: true,
116+
name: "fails when --repo-url is not a valid URL",
117+
cmd: fmt.Sprintf("attest artifact testdata/file1 --fingerprint 7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 --name cli --commit HEAD --build-url http://www.example.com --commit-url http://www.example.com --repo-url not-a-url %s", suite.defaultKosliArguments),
118+
golden: "Error: --repo-url 'not-a-url' is not a valid URL\n",
119+
},
120+
{
121+
wantError: true,
122+
name: "fails when --repo-provider is not an allowed value",
123+
cmd: fmt.Sprintf("attest artifact testdata/file1 --fingerprint 7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 --name cli --commit HEAD --build-url http://www.example.com --commit-url http://www.example.com --repo-provider jenkins %s", suite.defaultKosliArguments),
124+
golden: "Error: --repo-provider 'jenkins' is not allowed. Must be one of: github, gitlab, bitbucket, azure-devops\n",
125+
},
126+
{
127+
name: "can attest with all repo flags",
128+
cmd: fmt.Sprintf("attest artifact testdata/file1 --fingerprint 7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 --name cli --commit HEAD --build-url http://www.example.com --commit-url http://www.example.com --repo-id test-repo-id --repository test-repo-name --repo-url https://github.com/org/repo --repo-provider github %s", suite.defaultKosliArguments),
129+
golden: "artifact testdata/file1 was attested with fingerprint: 7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9\n",
130+
},
131+
{
132+
name: "can attest without repo-id and repository",
133+
cmd: fmt.Sprintf("attest artifact testdata/file1 --fingerprint 7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 --name cli --commit HEAD --build-url http://www.example.com --commit-url http://www.example.com %s", suite.defaultKosliArguments),
134+
golden: "artifact testdata/file1 was attested with fingerprint: 7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9\n",
135+
},
114136
}
115137

116138
runTestCmd(suite.T(), tests)

cmd/kosli/attestCustom.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ func newAttestCustomCmd(out io.Writer) *cobra.Command {
135135
},
136136

137137
RunE: func(cmd *cobra.Command, args []string) error {
138+
o.repoURLExplicit = cmd.Flags().Changed("repo-url")
138139
return o.run(args)
139140
},
140141
}

cmd/kosli/attestGeneric.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ func newAttestGenericCmd(out io.Writer) *cobra.Command {
129129
},
130130

131131
RunE: func(cmd *cobra.Command, args []string) error {
132+
o.repoURLExplicit = cmd.Flags().Changed("repo-url")
132133
return o.run(args)
133134
},
134135
}

cmd/kosli/attestGeneric_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,23 @@ func (suite *AttestGenericCommandTestSuite) TestAttestGenericCmd() {
173173
cmd: fmt.Sprintf("attest generic --name bar --annotate foo.baz=bar %s", suite.defaultKosliArguments),
174174
golden: "Error: --annotate flag should be in the format key=value. Invalid key: 'foo.baz'. Key can only contain [A-Za-z0-9_]\n",
175175
},
176+
{
177+
wantError: true,
178+
name: "fails when --repo-url is not a valid URL",
179+
cmd: fmt.Sprintf("attest generic --name foo --fingerprint 7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 --repo-url not-a-url %s", suite.defaultKosliArguments),
180+
golden: "Error: --repo-url 'not-a-url' is not a valid URL\n",
181+
},
182+
{
183+
wantError: true,
184+
name: "fails when --repo-provider is not an allowed value",
185+
cmd: fmt.Sprintf("attest generic --name foo --fingerprint 7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 --repo-provider jenkins %s", suite.defaultKosliArguments),
186+
golden: "Error: --repo-provider 'jenkins' is not allowed. Must be one of: github, gitlab, bitbucket, azure-devops\n",
187+
},
188+
{
189+
name: "can attest with all repo flags",
190+
cmd: fmt.Sprintf("attest generic --name foo --fingerprint 7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 --repo-id test-repo-id --repository test-repo-name --repo-url https://github.com/org/repo --repo-provider github %s", suite.defaultKosliArguments),
191+
golden: "generic attestation 'foo' is reported to trail: test-123\n",
192+
},
176193
}
177194

178195
runTestCmd(suite.T(), tests)

cmd/kosli/attestJira.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ func newAttestJiraCmd(out io.Writer) *cobra.Command {
226226

227227
},
228228
RunE: func(cmd *cobra.Command, args []string) error {
229+
o.repoURLExplicit = cmd.Flags().Changed("repo-url")
229230
return o.run(args)
230231
},
231232
}

cmd/kosli/attestJunit.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ func newAttestJunitCmd(out io.Writer) *cobra.Command {
132132

133133
},
134134
RunE: func(cmd *cobra.Command, args []string) error {
135+
o.repoURLExplicit = cmd.Flags().Changed("repo-url")
135136
return o.run(args)
136137
},
137138
}

cmd/kosli/attestPRAzure.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,9 @@ func newAttestAzurePRCmd(out io.Writer) *cobra.Command {
146146

147147
},
148148
RunE: func(cmd *cobra.Command, args []string) error {
149+
o.repoURLExplicit = cmd.Flags().Changed("repo-url")
149150
o.retriever = azUtils.NewAzureConfig(azureFlagsValues.Token,
150-
azureFlagsValues.OrgUrl, azureFlagsValues.Project, azureFlagsValues.Repository)
151+
azureFlagsValues.OrgUrl, azureFlagsValues.Project, o.repoName)
151152
return o.run(args)
152153
},
153154
}

cmd/kosli/attestPRAzure_test.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,22 @@ func (suite *AttestAzurePRCommandTestSuite) TestAttestAzurePRCmd() {
115115
{
116116
wantError: true,
117117
name: "13 if there is a server error, this is output even when assert fails",
118-
cmd: fmt.Sprintf(`attest pullrequest azure --fingerprint 1234e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 --name foo
118+
cmd: fmt.Sprintf(`attest pullrequest azure --fingerprint 1234e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 --name foo
119119
--azure-org-url https://dev.azure.com/kosli --project kosli-azure --repository cli --commit HEAD --assert %s`, suite.defaultKosliArguments),
120120
goldenRegex: "found 0 pull request\\(s\\) for commit: .*\nError: Artifact with fingerprint 1234e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 does not exist in trail \"test-123\" of flow \"attest-azure-pr\" belonging to organization \"docs-cmd-test-user\"\nError: assert failed: no pull request found for the given commit: .*\n",
121121
},
122+
{
123+
wantError: true,
124+
name: "14 fails when --repo-url is not a valid URL",
125+
cmd: fmt.Sprintf("attest pullrequest azure --name foo --commit HEAD --azure-token fake --azure-org-url https://dev.azure.com/myorg --project myproject --repository myrepo --repo-url not-a-url %s", suite.defaultKosliArguments),
126+
golden: "Error: --repo-url 'not-a-url' is not a valid URL\n",
127+
},
128+
{
129+
wantError: true,
130+
name: "15 fails when --repo-provider is not an allowed value",
131+
cmd: fmt.Sprintf("attest pullrequest azure --name foo --commit HEAD --azure-token fake --azure-org-url https://dev.azure.com/myorg --project myproject --repository myrepo --repo-provider jenkins %s", suite.defaultKosliArguments),
132+
golden: "Error: --repo-provider 'jenkins' is not allowed. Must be one of: github, gitlab, bitbucket, azure-devops\n",
133+
},
122134
}
123135

124136
runTestCmd(suite.T(), tests)

cmd/kosli/attestPRBitbucket.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ func newAttestBitbucketPRCmd(out io.Writer) *cobra.Command {
166166

167167
},
168168
RunE: func(cmd *cobra.Command, args []string) error {
169+
o.repoURLExplicit = cmd.Flags().Changed("repo-url")
170+
o.getRetriever().(*bbUtils.Config).Repository = o.repoName
169171
return o.run(args)
170172
},
171173
}

0 commit comments

Comments
 (0)