From d1646b3c5f61d11b950f5fdfec7f56c9aba9c773 Mon Sep 17 00:00:00 2001 From: Florian Blampey Date: Wed, 5 Feb 2025 11:57:42 +0100 Subject: [PATCH] add an optional robot_prefix to the provider configuration (#494) add an optional robot_prefix to the provider configuration `robot_prefix` (String) Without this option, the provider will try to automatically determine the robot prefix with a call to the admin api. If you don't have admin access and want to create system robot account, you'll have to set this value. and fix, permission access effect, to be able to use the provider with robot account Signed-off-by: flbla --- client/client.go | 9 +++++++- client/robot_account.go | 5 ++++- docs/index.md | 1 + provider/provider.go | 7 ++++++- provider/resource_robot_account.go | 33 +++++++++++++++++------------- templates/index.md.tmpl | 1 + 6 files changed, 39 insertions(+), 17 deletions(-) diff --git a/client/client.go b/client/client.go index c798fc00..afb65888 100644 --- a/client/client.go +++ b/client/client.go @@ -19,10 +19,11 @@ type Client struct { bearerToken string insecure bool httpClient *http.Client + robotPrefix string } // NewClient creates common settings -func NewClient(url string, username string, password string, bearerToken string, insecure bool) *Client { +func NewClient(url string, username string, password string, bearerToken string, insecure bool, robotPrefix string) *Client { return &Client{ url: url, @@ -31,6 +32,7 @@ func NewClient(url string, username string, password string, bearerToken string, bearerToken: bearerToken, insecure: insecure, httpClient: &http.Client{}, + robotPrefix: robotPrefix, } } @@ -115,3 +117,8 @@ func GetID(body string) (id string, err error) { return location, nil } + +// get robotPrefix +func (c *Client) GetRobotPrefix() string { + return c.robotPrefix +} diff --git a/client/robot_account.go b/client/robot_account.go index 10431c0e..0467fcaa 100755 --- a/client/robot_account.go +++ b/client/robot_account.go @@ -26,8 +26,11 @@ func RobotBody(d *schema.ResourceData) models.RobotBody { access := models.RobotBodyAccess{ Action: a.(map[string]interface{})["action"].(string), Resource: a.(map[string]interface{})["resource"].(string), - Effect: a.(map[string]interface{})["effect"].(string), } + if a.(map[string]interface{})["effect"] != "" { + access.Effect = a.(map[string]interface{})["effect"].(string) + } + permission.Access = append(permission.Access, access) } diff --git a/docs/index.md b/docs/index.md index 0062bdea..12886173 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,6 +23,7 @@ description: |- - `api_version` (Number) Choose which version of the api you would like to use 1 or 2 (default is 2) - `bearer_token` (String) The bearer token to be used to access harbor. Will take precedence over username and password if set - `insecure` (Boolean) Choose to ignore certificate errors +- `robot_prefix` (String) Without this option, the provider will try to automatically determine the robot prefix with a call to the admin api. If you don't have admin access and want to create system robot account, you'll have to set this value. ### Environment variables diff --git a/provider/provider.go b/provider/provider.go index e01f9732..7614ba46 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -44,6 +44,10 @@ func Provider() *schema.Provider { Optional: true, Default: 2, }, + "robot_prefix": { + Type: schema.TypeString, + Optional: true, + }, }, ResourcesMap: map[string]*schema.Resource{ @@ -100,6 +104,7 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { bearerToken := d.Get("bearer_token").(string) insecure := d.Get("insecure").(bool) apiVersion := d.Get("api_version").(int) + robotPrefix := d.Get("robot_prefix").(string) if strings.HasSuffix(url, "/") { url = strings.Trim(url, "/") @@ -111,5 +116,5 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { apiPath = "/api/v2.0" } - return client.NewClient(url+apiPath, username, password, bearerToken, insecure), nil + return client.NewClient(url+apiPath, username, password, bearerToken, insecure, robotPrefix), nil } diff --git a/provider/resource_robot_account.go b/provider/resource_robot_account.go index e1ed635c..7f4e99bd 100755 --- a/provider/resource_robot_account.go +++ b/provider/resource_robot_account.go @@ -72,7 +72,7 @@ func resourceRobotAccount() *schema.Resource { "effect": { Type: schema.TypeString, Optional: true, - Default: "allow", + //Default: "allow", }, }, }, @@ -152,28 +152,33 @@ func resourceRobotAccountRead(d *schema.ResourceData, m interface{}) error { apiClient := m.(*client.Client) robot, err := getRobot(d, apiClient) + if err != nil { d.SetId("") return nil } var shortName string - if robot.Level == "project" { - shortName = strings.Split(robot.Name, robot.Permissions[0].Namespace+"+")[1] + if m.(*client.Client).GetRobotPrefix() != "" { + // if robot_prefix is set, we use it to get the short name + shortName = strings.TrimPrefix(robot.Name, m.(*client.Client).GetRobotPrefix()) } else { - 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) - } - var systemConfig models.ConfigBodyResponse - err = json.Unmarshal([]byte(resp), &systemConfig) - if err != nil { - return fmt.Errorf("error getting system configuration %s", err) + if robot.Level == "project" { + shortName = strings.Split(robot.Name, robot.Permissions[0].Namespace+"+")[1] + } else { + resp, _, respCode, err := apiClient.SendRequest("GET", models.PathConfig, nil, 200) + if respCode == 404 && err != nil { + d.SetId("") + return fmt.Errorf("error getting system configuration (probably missing admin rights) %s, you can use robot_prefix to force the prefix", err) + } + var systemConfig models.ConfigBodyResponse + err = json.Unmarshal([]byte(resp), &systemConfig) + if err != nil { + return fmt.Errorf("error getting system configuration (probably missing admin rights) %s, you can use robot_prefix to force the prefix", err) + } + shortName = strings.TrimPrefix(robot.Name, systemConfig.RobotNamePrefix.Value) } - shortName = strings.TrimPrefix(robot.Name, systemConfig.RobotNamePrefix.Value) } - d.Set("name", shortName) d.Set("robot_id", strconv.Itoa(robot.ID)) d.Set("full_name", robot.Name) diff --git a/templates/index.md.tmpl b/templates/index.md.tmpl index 86639f68..2f981a99 100644 --- a/templates/index.md.tmpl +++ b/templates/index.md.tmpl @@ -27,6 +27,7 @@ For example, the {{ .SchemaMarkdown }} template can be used to replace manual sc - `api_version` (Number) Choose which version of the api you would like to use 1 or 2 (default is 2) - `bearer_token` (String) The bearer token to be used to access harbor. Will take precedence over username and password if set - `insecure` (Boolean) Choose to ignore certificate errors +- `robot_prefix` (String) Without this option, the provider will try to automatically determine the robot prefix with a call to the admin api. If you don't have admin access and want to create system robot account, you'll have to set this value. ### Environment variables