From 33fc0494c50265a23c15ff91e8b11a1c78b47c5a Mon Sep 17 00:00:00 2001 From: Florian Blampey Date: Tue, 6 Aug 2024 11:12:26 +0200 Subject: [PATCH] [harbor_config_system] - add audit_log_forward_endpoint, skip_audit_log_database and banner_message (fixes #462) (#463) Signed-off-by: flbla Co-authored-by: github-actions[bot] --- client/config.go | 16 +++++ docs/resources/config_system.md | 16 +++++ models/config.go | 23 +++++++ provider/resource_config_system.go | 81 ++++++++++++++++++++++- templates/resources/config_system.md.tmpl | 16 +++++ 5 files changed, 150 insertions(+), 2 deletions(-) diff --git a/client/config.go b/client/config.go index fcab541..486a6aa 100644 --- a/client/config.go +++ b/client/config.go @@ -2,6 +2,7 @@ package client import ( "encoding/json" + "fmt" "log" "github.com/goharbor/terraform-provider-harbor/models" @@ -14,6 +15,18 @@ func GetConfigSystem(d *schema.ResourceData) models.ConfigBodySystemPost { if storage > 0 { storage *= 1073741824 // GB to Byte } + + bannerMessage := "" + if v, ok := d.GetOk("banner_message"); ok { + bannerMessageList := v.([]interface{}) + bannerMessageMap := bannerMessageList[0].(map[string]interface{}) + closable := bannerMessageMap["closable"].(bool) + message := bannerMessageMap["message"].(string) + messageType := bannerMessageMap["type"].(string) + fromDate := bannerMessageMap["from_date"].(string) + toDate := bannerMessageMap["to_date"].(string) + bannerMessage = fmt.Sprintf("{\"closable\":%t,\"message\":\"%s\",\"type\":\"%s\",\"fromDate\":\"%s\",\"toDate\":\"%s\"}", closable, message, messageType, fromDate, toDate) + } body = models.ConfigBodySystemPost{ ProjectCreationRestriction: d.Get("project_creation_restriction").(string), ReadOnly: d.Get("read_only").(bool), @@ -22,6 +35,9 @@ func GetConfigSystem(d *schema.ResourceData) models.ConfigBodySystemPost { QuotaPerProjectEnable: true, RobotNamePrefix: d.Get("robot_name_prefix").(string), StoragePerProject: storage, + AuditLogForwardEndpoint: d.Get("audit_log_forward_endpoint").(string), + SkipAuditLogDatabase: d.Get("skip_audit_log_database").(bool), + BannerMessage: bannerMessage, } log.Printf("[DEBUG] %+v\n ", body) return body diff --git a/docs/resources/config_system.md b/docs/resources/config_system.md index f620fd9..0b69493 100644 --- a/docs/resources/config_system.md +++ b/docs/resources/config_system.md @@ -31,6 +31,22 @@ resource "harbor_config_system" "main" { - `robot_token_expiration` (Number) The amount of time in days a robot account will expire. - `scanner_skip_update_pulltime` (Boolean) Whether or not to skip update pull time for scanner. - `storage_per_project` (Number) Default quota space per project in GIB. Default is -1 (unlimited). +- `audit_log_forward_endpoint` (String) The endpoint to forward audit logs to. +- `skip_audit_log_database` (Boolean) Whether or not to skip audit log database. +- `banner_message` (Block Set) (see [below for nested schema](#nestedblock--banner_message)) + + + +### Nested Schema for `banner_message` + +### Required +- `message` (String) The message to display in the banner. + +### Optional +- `closable` (Boolean) Whether or not the banner message is closable. +- `type` (String) The type of banner message. Can be `"info"`, `"warning"`, `"success"` or `"danger"`. +- `from_date` (String) The date the banner message will start displaying. (Format: `MM/DD/YYYY`) +- `to_date` (String) The date the banner message will stop displaying. (Format: `MM/DD/YYYY`) #### Notes `scanner_skip_update_pulltime` can only be used with harbor version v2.8.0 and above diff --git a/models/config.go b/models/config.go index 5b25f28..de766f8 100644 --- a/models/config.go +++ b/models/config.go @@ -50,6 +50,9 @@ type ConfigBodySystemPost struct { RobotNamePrefix string `json:"robot_name_prefix,omitempty"` StoragePerProject int `json:"storage_per_project,omitempty"` ScannerSkipUpdatePulltime bool `json:"scanner_skip_update_pulltime"` + AuditLogForwardEndpoint string `json:"audit_log_forward_endpoint,omitempty"` + SkipAuditLogDatabase bool `json:"skip_audit_log_database"` + BannerMessage string `json:"banner_message,omitempty"` } type ConfigBodyEmailPost struct { @@ -246,4 +249,24 @@ type ConfigBodyResponse struct { Editable bool `json:"editable,omitempty"` Value bool `json:"value,omitempty"` } `json:"scanner_skip_update_pulltime,omitempty"` + AuditLogForwardEndpoint struct { + Editable bool `json:"editable,omitempty"` + Value string `json:"value,omitempty"` + } `json:"audit_log_forward_endpoint,omitempty"` + SkipAuditLogDatabase struct { + Editable bool `json:"editable,omitempty"` + Value bool `json:"value,omitempty"` + } `json:"skip_audit_log_database,omitempty"` + BannerMessage struct { + Editable bool `json:"editable,omitempty"` + Value string `json:"value,omitempty"` + } `json:"banner_message,omitempty"` +} + +type BannerMessage struct { + Closable bool `json:"closable,omitempty"` + Message string `json:"message,omitempty"` + Type string `json:"type,omitempty"` + ToDate string `json:"toDate,omitempty"` + FromDate string `json:"fromDate,omitempty"` } diff --git a/provider/resource_config_system.go b/provider/resource_config_system.go index e62f146..cae2147 100644 --- a/provider/resource_config_system.go +++ b/provider/resource_config_system.go @@ -3,6 +3,7 @@ package provider import ( "encoding/json" "fmt" + "strings" "github.com/goharbor/terraform-provider-harbor/client" "github.com/goharbor/terraform-provider-harbor/models" @@ -42,6 +43,60 @@ func resourceConfigSystem() *schema.Resource { Optional: true, Default: -1, }, + "audit_log_forward_endpoint": { + Type: schema.TypeString, + Optional: true, + Default: "", + }, + "skip_audit_log_database": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "banner_message": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "closable": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "message": { + Type: schema.TypeString, + Required: true, + }, + "type": { + Type: schema.TypeString, + Optional: true, + Default: "info", + ValidateFunc: func(val interface{}, key string) (warns []string, errs []error) { + v := val.(string) + allowedValues := []string{"success", "info", "warning", "danger"} + for _, av := range allowedValues { + if v == av { + return + } + } + errs = append(errs, fmt.Errorf("%q must be one of [%s], got %s", key, strings.Join(allowedValues, ", "), v)) + return + }, + }, + "from_date": { + Type: schema.TypeString, + Optional: true, + Default: "", + }, + "to_date": { + Type: schema.TypeString, + Optional: true, + Default: "", + }, + }, + }, + }, }, Create: resourceConfigSystemCreate, Read: resourceConfigSystemRead, @@ -75,25 +130,47 @@ func resourceConfigSystemRead(d *schema.ResourceData, m interface{}) error { resp, _, respCode, err := apiClient.SendRequest("GET", models.PathConfig, nil, 200) if respCode == 404 && err != nil { d.SetId("") - return fmt.Errorf("Error getting system configuration %s", err) + return fmt.Errorf("error getting system configuration %s", err) } var jsonData models.ConfigBodyResponse err = json.Unmarshal([]byte(resp), &jsonData) if err != nil { - return fmt.Errorf("Error getting system configuration %s", err) + return fmt.Errorf("error getting system configuration %s", err) } storage := jsonData.StoragePerProject.Value if storage > 0 { storage /= 1073741824 // Byte to GB } + // set the data for banner message + if jsonData.BannerMessage.Value != "" { + bannerMessage := jsonData.BannerMessage.Value + // bannerMessage is a json string and we need to parse it to get the values + var bannerMessageData models.BannerMessage + err = json.Unmarshal([]byte(bannerMessage), &bannerMessageData) + if err != nil { + return fmt.Errorf("error getting system configuration %s", err) + } + bannerMessageList := make([]interface{}, 1) + bannerMessageList[0] = map[string]interface{}{ + "closable": bannerMessageData.Closable, + "message": bannerMessageData.Message, + "type": bannerMessageData.Type, + "from_date": bannerMessageData.FromDate, + "to_date": bannerMessageData.ToDate, + } + d.Set("banner_message", bannerMessageList) + } + d.Set("project_creation_restriction", jsonData.ProjectCreationRestriction.Value) d.Set("read_only", jsonData.ReadOnly.Value) d.Set("robot_token_expiration", jsonData.RobotTokenDuration.Value) d.Set("robot_name_prefix", jsonData.RobotNamePrefix.Value) d.Set("scanner_skip_update_pulltime", jsonData.ScannerSkipUpdatePulltime.Value) d.Set("storage_per_project", storage) + d.Set("audit_log_forward_endpoint", jsonData.AuditLogForwardEndpoint.Value) + d.Set("skip_audit_log_database", jsonData.SkipAuditLogDatabase.Value) d.SetId("configuration/system") return nil diff --git a/templates/resources/config_system.md.tmpl b/templates/resources/config_system.md.tmpl index 81a48f6..cd71efb 100644 --- a/templates/resources/config_system.md.tmpl +++ b/templates/resources/config_system.md.tmpl @@ -28,6 +28,22 @@ For example, the {{ .SchemaMarkdown }} template can be used to replace manual sc - `robot_token_expiration` (Number) The amount of time in days a robot account will expire. - `scanner_skip_update_pulltime` (Boolean) Whether or not to skip update pull time for scanner. - `storage_per_project` (Number) Default quota space per project in GIB. Default is -1 (unlimited). +- `audit_log_forward_endpoint` (String) The endpoint to forward audit logs to. +- `skip_audit_log_database` (Boolean) Whether or not to skip audit log database. +- `banner_message` (Block Set) (see [below for nested schema](#nestedblock--banner_message)) + + + +### Nested Schema for `banner_message` + +### Required +- `message` (String) The message to display in the banner. + +### Optional +- `closable` (Boolean) Whether or not the banner message is closable. +- `type` (String) The type of banner message. Can be `"info"`, `"warning"`, `"success"` or `"danger"`. +- `from_date` (String) The date the banner message will start displaying. (Format: `MM/DD/YYYY`) +- `to_date` (String) The date the banner message will stop displaying. (Format: `MM/DD/YYYY`) #### Notes `scanner_skip_update_pulltime` can only be used with harbor version v2.8.0 and above