Skip to content

Commit 7f74f69

Browse files
authored
feat: add association for product domain (#14)
* feat: add association for product domain * try domain association * improve formatting * format before exiting * improve formatting * add more tests * use continue on error * adjust gh test * adjust the test * adjust the logging
1 parent 2613d5f commit 7f74f69

File tree

3 files changed

+112
-2
lines changed

3 files changed

+112
-2
lines changed

.github/workflows/test-upload-file.yml

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,48 @@ jobs:
2323
}
2424
EOF
2525
26-
- name: Test Upload File Action
26+
- name: Test basic upload
2727
uses: ./upload-file
2828
with:
2929
file_path: test-upload.json
3030
security_agent_api_key: ${{ secrets.SECURITY_AGENT_API_KEY }}
3131
tags: |
3232
scanner=trivy
3333
image_name=test-image
34+
35+
- name: Test image name association
36+
uses: ./upload-file
37+
with:
38+
file_path: test-upload.json
39+
security_agent_api_key: ${{ secrets.SECURITY_AGENT_API_KEY }}
40+
tags: |
41+
image_name=test-image
42+
43+
- name: Test domain association (invalid)
44+
id: invalid-domain-test
45+
uses: ./upload-file
46+
continue-on-error: true
47+
with:
48+
file_path: test-upload.json
49+
security_agent_api_key: ${{ secrets.SECURITY_AGENT_API_KEY }}
50+
tags: |
51+
product_domain=invalid-domain
52+
53+
- name: Assert invalid domain association
54+
env:
55+
OUTCOME: ${{ steps.invalid-domain-test.outcome }}
56+
run: |
57+
if [ "$OUTCOME" == "failure" ]; then
58+
echo "✅ Invalid domain test correctly failed as expected"
59+
else
60+
echo "❌ Invalid domain test should have failed but succeeded"
61+
exit 1
62+
fi
63+
64+
- name: Test domain association (valid)
65+
uses: ./upload-file
66+
with:
67+
file_path: test-upload.json
68+
security_agent_api_key: ${{ secrets.SECURITY_AGENT_API_KEY }}
69+
tags: |
70+
product_domain=security-agent-test

upload-file/main.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"context"
55
"log"
6+
"strings"
67

78
"github.com/hasura/security-agent-tools/upload-file/input"
89
"github.com/hasura/security-agent-tools/upload-file/metadata"
@@ -41,7 +42,21 @@ func main() {
4142
if err != nil {
4243
log.Fatalf("Failed to associate image name with scan: %v", err)
4344
}
44-
log.Printf("Associated image name %s with scan %s\n", imageName, scan.ID)
45+
log.Printf("Associated image name: %s\n", imageName)
46+
}
47+
48+
domain := input.Tags["product_domain"]
49+
if domain != "" {
50+
err = metadata.AssociateProductDomainWithScan(context.Background(), c, scan.ID, domain)
51+
if err != nil {
52+
pd, _ := metadata.ProductDomains(context.Background(), c)
53+
var pds strings.Builder
54+
for _, p := range pd {
55+
pds.WriteString(" - " + p + "\n")
56+
}
57+
log.Fatalf("Failed to associate product domain with scan: %v. Please check `product_domain` value is one of the following:\n%s", err, pds.String())
58+
}
59+
log.Printf("Associated product domain: %s\n", domain)
4560
}
4661

4762
err = upload.ServiceMetadata(context.Background(), c, input)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package metadata
2+
3+
import (
4+
"context"
5+
6+
"github.com/hasura/security-agent-tools/upload-file/upload"
7+
"github.com/machinebox/graphql"
8+
)
9+
10+
func AssociateProductDomainWithScan(ctx context.Context, c *upload.Client, scanID, productDomain string) error {
11+
req := graphql.NewRequest(`mutation AssociateProductDomain($scan_id: uuid!, $product_domain: string!) {
12+
insert_vulnerability_reports_by_product_domains(
13+
objects: {scan_id: $scan_id, product_domain: $product_domain}
14+
) {
15+
returning {
16+
id
17+
}
18+
}
19+
}`)
20+
req.Var("scan_id", scanID)
21+
req.Var("product_domain", productDomain)
22+
23+
var response struct {
24+
InsertVulnerabilityReportsByProductDomains struct {
25+
Returning []struct {
26+
ID string `json:"id"`
27+
} `json:"returning"`
28+
} `json:"insert_vulnerability_reports_by_product_domains"`
29+
}
30+
31+
return c.Do(ctx, req, &response)
32+
}
33+
34+
func ProductDomains(ctx context.Context, c *upload.Client) ([]string, error) {
35+
req := graphql.NewRequest(`query GetProductDomains {
36+
vulnerability_reports_product_domains {
37+
code
38+
}
39+
}`)
40+
41+
var response struct {
42+
VulnerabilityReportsProductDomains []struct {
43+
Code string `json:"code"`
44+
} `json:"vulnerability_reports_product_domains"`
45+
}
46+
47+
err := c.Do(ctx, req, &response)
48+
if err != nil {
49+
return nil, err
50+
}
51+
52+
var productDomains []string
53+
for _, pd := range response.VulnerabilityReportsProductDomains {
54+
productDomains = append(productDomains, pd.Code)
55+
}
56+
57+
return productDomains, nil
58+
}

0 commit comments

Comments
 (0)