Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions client/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,67 @@ func ProjectBody(d *schema.ResourceData) models.ProjectsBodyPost {
return body
}

// GetScannerByName lists all scanners and returns the one matching the given name.
func (client *Client) GetScannerByName(scanner string) (models.ScannerBody, error) {
resp, _, _, err := client.SendRequest("GET", models.PathScanners, nil, 0)
if err != nil {
return models.ScannerBody{}, err
}

var scanners []models.ScannerBody
err = json.Unmarshal([]byte(resp), &scanners)
if err != nil {
return models.ScannerBody{}, err
}

for _, v := range scanners {
if strings.EqualFold(v.Name, scanner) {
return v, nil
}
}

return models.ScannerBody{}, fmt.Errorf("scanner %q not found", scanner)
}

// SetProjectScanner sets the vulnerability scanner for a specific project.
func (client *Client) SetProjectScanner(d *schema.ResourceData) error {
scanner := d.Get("vulnerability_scanner").(string)
if scanner == "" {
return nil
}

scannerData, err := client.GetScannerByName(scanner)
if err != nil {
return err
}

body := models.ProjectScannerBody{
UUID: scannerData.UUID,
}

_, _, _, err = client.SendRequest("PUT", d.Id()+"/scanner", body, 200)
return err
}

// GetProjectScanner returns the name of the scanner assigned to a project.
func (client *Client) GetProjectScanner(projectPath string) (string, error) {
resp, _, respCode, err := client.SendRequest("GET", projectPath+"/scanner", nil, 200)
if err != nil {
if respCode == 404 {
return "", nil
}
return "", err
}

var scannerData models.ScannerBody
err = json.Unmarshal([]byte(resp), &scannerData)
if err != nil {
return "", err
}

return scannerData.Name, nil
}

func expandCveAllowList(cveAllowlist []interface{}) models.CveAllowlistItems {
allowlist := models.CveAllowlistItems{}

Expand Down
24 changes: 5 additions & 19 deletions client/system.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package client

import (
"encoding/json"
"log"
"strings"

"github.com/goharbor/terraform-provider-harbor/models"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand Down Expand Up @@ -77,27 +75,15 @@ func (client *Client) SetSchedule(d *schema.ResourceData, scheduleType string) (

// SetDefaultScanner set the default scanner within harbor
func (client *Client) SetDefaultScanner(scanner string) (err error) {
resp, _, _, err := client.SendRequest("GET", models.PathScanners, nil, 0)

body := models.ScannerBody{
IsDefault: true,
}

var jsonData []models.ScannerBody
err = json.Unmarshal([]byte(resp), &jsonData)
scannerData, err := client.GetScannerByName(scanner)
if err != nil {
return err
}

for _, v := range jsonData {

if v.Name == strings.Title(scanner) {
_, _, _, err = client.SendRequest("PATCH", models.PathScanners+"/"+v.UUID, body, 0)
}
if err != nil {
return err
}
body := models.ScannerBody{
IsDefault: true,
}

return nil
_, _, _, err = client.SendRequest("PATCH", models.PathScanners+"/"+scannerData.UUID, body, 0)
return err
}
1 change: 1 addition & 0 deletions docs/data-sources/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ output "project_id" {
- `public` (Boolean) If the project has public accessibility.
- `type` (String) The type of the project : Project or ProxyCache.
- `vulnerability_scanning` (Boolean) If the images is scanned for vulnerabilities when push to harbor.
- `vulnerability_scanner` (String) The name of the vulnerability scanner assigned to the project.
2 changes: 2 additions & 0 deletions docs/resources/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ resource "harbor_project" "main" {
name = "main"
public = false # (Optional) Default value is false
vulnerability_scanning = true # (Optional) Default value is true. Automatically scan images on push
vulnerability_scanner = "Trivy" # (Optional) Override the global default scanner for this project
enable_content_trust = true # (Optional) Default value is false. Deny unsigned images from being pulled (notary)
enable_content_trust_cosign = false # (Optional) Default value is false. Deny unsigned images from being pulled (cosign)
auto_sbom_generation = true # (Optional) Default value is false. Automatically generate SBOMs for images
Expand Down Expand Up @@ -56,6 +57,7 @@ resource "harbor_registry" "docker" {
- `public` (Boolean) The project will be public accessibility.(Default: `false`)
- `storage_quota` (Number) The storage quota of the project in GB's.
- `vulnerability_scanning` (Boolean) Images will be scanned for vulnerabilities when push to harbor. (Default: `true`)
- `vulnerability_scanner` (String) The name of the vulnerability scanner to use for this project, overriding the global default scanner. If not set, the project uses the global default scanner configured via `harbor_interrogation_services`.
- `auto_sbom_generation` (Boolean) Automatically generate SBOM for images pushed to this project. (Default: `false`) can only be used with Harbor version v2.11.0 and above

### Specific for Proxy Project
Expand Down
4 changes: 4 additions & 0 deletions models/projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ type ProjectsBodyResponses struct {
} `json:"metadata"`
}

type ProjectScannerBody struct {
UUID string `json:"uuid"`
}

type CveAllowlistItems []struct {
CveID string `json:"cve_id,omitempty"`
}
Expand Down
10 changes: 10 additions & 0 deletions provider/data_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ func dataProject() *schema.Resource {
Type: schema.TypeBool,
Computed: true,
},
"vulnerability_scanner": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
Expand Down Expand Up @@ -68,6 +72,12 @@ func dataProjectRead(d *schema.ResourceData, m interface{}) error {
d.Set("public", public)
d.Set("vulnerability_scanning", autoScan)
d.Set("type", project_type)

scannerName, err := apiClient.GetProjectScanner(id)
if err != nil {
return err
}
d.Set("vulnerability_scanner", scannerName)
}
}
return nil
Expand Down
24 changes: 24 additions & 0 deletions provider/resource_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ func resourceProject() *schema.Resource {
Optional: true,
Default: true,
},
"vulnerability_scanner": {
Type: schema.TypeString,
Optional: true,
},
"storage_quota": {
Type: schema.TypeInt,
Optional: true,
Expand Down Expand Up @@ -136,6 +140,11 @@ func resourceProjectCreate(d *schema.ResourceData, m interface{}) error {
}
}

err = apiClient.SetProjectScanner(d)
if err != nil {
return err
}

return resourceProjectRead(d, m)
}

Expand Down Expand Up @@ -223,6 +232,14 @@ func resourceProjectRead(d *schema.ResourceData, m interface{}) error {
}
d.Set("cve_allowlist", cveAllowlist)

if d.Get("vulnerability_scanner").(string) != "" {
scannerName, err := apiClient.GetProjectScanner(d.Id())
if err != nil {
return err
}
d.Set("vulnerability_scanner", scannerName)
}

return nil
}

Expand All @@ -241,6 +258,13 @@ func resourceProjectUpdate(d *schema.ResourceData, m interface{}) error {

apiClient.UpdateStorageQuota(d)

if d.HasChange("vulnerability_scanner") {
err = apiClient.SetProjectScanner(d)
if err != nil {
return err
}
}

return resourceProjectRead(d, m)
}

Expand Down
Loading