Skip to content

Commit

Permalink
Merge pull request #107 from kschu91/feature/integration-new-robots-api
Browse files Browse the repository at this point in the history
Integrate new robots api
  • Loading branch information
wrighbr authored Mar 29, 2021
2 parents 59dcfb9 + 9616cfd commit b63e722
Show file tree
Hide file tree
Showing 6 changed files with 320 additions and 105 deletions.
2 changes: 1 addition & 1 deletion client/replication.go
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func GetReplicationBody(d *schema.ResourceData) models.ReplicationBody {
Name: d.Get("name").(string),
Override: d.Get("override").(bool),
Enabled: d.Get("enabled").(bool),
Deletion: d.Get("deletion").(bool),
Deletion: d.Get("deletion").(bool),
DestNamespace: d.Get("dest_namespace").(string),
}

Expand Down
38 changes: 19 additions & 19 deletions client/robot_account.go
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
package client

import (
"strings"

"github.com/BESTSELLER/terraform-provider-harbor/models"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func RobotBody(d *schema.ResourceData, projectid string) models.RobotBody {
resource := strings.Replace(projectid, "s", "", +1)

func RobotBody(d *schema.ResourceData) models.RobotBody {
body := models.RobotBody{
Name: d.Get("name").(string),
Description: d.Get("description").(string),
Disable: d.Get("disable").(bool),
Duration: d.Get("duration").(int),
Level: d.Get("level").(string),
}

robotAccess := models.RobotBodyAccess{}
permissions := d.Get("permissions").(*schema.Set).List()
for _, p := range permissions {

access := d.Get("actions").([]interface{})
for _, v := range access {
permission := models.RobotBodyPermission{
Kind: p.(map[string]interface{})["kind"].(string),
Namespace: p.(map[string]interface{})["namespace"].(string),
}

switch v.(string) {
case "push", "pull":
robotAccess.Action = v.(string)
robotAccess.Resource = resource + "/repository"
case "read":
robotAccess.Action = v.(string)
robotAccess.Resource = resource + "/helm-chart"
case "create":
robotAccess.Action = v.(string)
robotAccess.Resource = resource + "/helm-chart-version"
for _, a := range p.(map[string]interface{})["access"].(*schema.Set).List() {
access := models.RobotBodyAccess{
Action: a.(map[string]interface{})["action"].(string),
Resource: a.(map[string]interface{})["resource"].(string),
Effect: a.(map[string]interface{})["effect"].(string),
}
permission.Access = append(permission.Access, access)
}
body.Access = append(body.Access, robotAccess)

body.Permissions = append(body.Permissions, permission)
}

return body
Expand Down
143 changes: 126 additions & 17 deletions docs/resources/robot_account.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,148 @@
# Resource: harbor_robot_account

Harbor supports different levels of robot accounts. Currently `system` and `project` level robot accounts are supported.

## Example Usage

### System Level
Introduced in harbor 2.2.0, system level robot accounts can have basically [all available permissions](https://github.com/goharbor/harbor/blob/master/src/common/rbac/const.go) in harbor and are not dependent on a single project.

```hcl
resource "harbor_project" "main" {
name = "main"
}
resource "harbor_robot_account" "account" {
name = "${harbor_project.main.name}"
description = "Robot account used to push images to harbor"
project_id = harbor_project.main.id
actions = ["push"]
resource "harbor_robot_account" "system" {
name = "example-system"
description = "system level robot account"
level = "system"
permissions {
access {
action = "create"
resource = "labels"
}
kind = "system"
namespace = "/"
}
permissions {
access {
action = "push"
resource = "repository"
}
access {
action = "read"
resource = "helm-chart"
}
access {
action = "read"
resource = "helm-chart-version"
}
kind = "project"
namespace = harbor_project.main.name
}
permissions {
access {
action = "pull"
resource = "repository"
}
kind = "project"
namespace = "*"
}
}
```

The above example, creates a system level robot account with permissions to
- permission to create labels on system level
- pull repository across all projects
- push repository to project "my-project-name"
- read helm-chart and helm-chart-version in project "my-project-name"

### Project Level

Other than system level robot accounts, project level robot accounts can interact on project level only.
The [available permissions](https://github.com/goharbor/harbor/blob/master/src/common/rbac/const.go) are mostly the same as for system level robots.


```hcl
resource "harbor_project" "main" {
name = "main"
}
resource "harbor_robot_account" "project" {
name = "example-project"
description = "project level robot account"
level = "project"
permissions {
access {
action = "pull"
resource = "repository"
}
access {
action = "push"
resource = "repository"
}
kind = "project"
namespace = harbor_project.main.name
}
}
```

The above example creates a project level robot account with permissions to
- pull repository on project "main"
- push repository on project "main"


## Argument Reference
The following arguments are supported:

* **name** - (Required) The of the project that will be created in harbor.
* **name** - (string, required) The of the project that will be created in harbor.

* **level** - (string, required) Level of the robot account, currently either `system` or `project`.

* **description** - (string, optional) The description of the robot account will be displayed in harbor.

* **duration** - (int, optional) By default, the robot account will not expire. Set it to the amount of days until the account should expire.

* **disable** - (bool, optional) Disables the robot account when set to `true`.

* **permissions** - (block, required) [Permissions](#permissions-arguments) to be applied to the robot account.
```
permissions {
access {
action = "action"
resource = "resource"
effect = "effect"
}
access {
...
}
kind = "project"
namespace = harbor_project.main.name
}
permissions {
...
}
```
**Note, that for `project` level accounts, only one `permission` block is allowed!**

### Permissions Arguments
* **access** - (block, required) Define one or multiple [access blocks](#access-arguments).

* **kind** - (string, required) Either `system` or `project`.

* **namespace** - (string, required) namespace is the name of your project.
For kind `system` permissions, always use `/` as namespace.
Use `*` to match all projects.

* **description** - (Optional) The description of the robot account will be displayed in harbor.
### Access Arguments
* **action** - (string, required) Eg. `push`, `pull`, `read`, etc. Check [available actions](https://github.com/goharbor/harbor/blob/master/src/common/rbac/const.go).

* **project_id** - (Required) The project id of the project that the robot account will be associated with.
* **resource** - (string, required) Eg. `repository`, `helm-chart`, `labels`, etc. Check [available resources](https://github.com/goharbor/harbor/blob/master/src/common/rbac/const.go).

* **actions** - (Optional) A list of actions that the robot account will be able to perform on the project. 
You to have set `["pull"]` as minimal requirement, if `["push"]` is set you don't need to set pull. Other combinations can be `["push","create","read"]` or `["push","read"]` or `["pull","read"]`
```
pull = permission to pull from docker registry
push = permission to push to docker registry
create = permission to created helm charts
read = permission to read helm charts
```
* **effect** - (string, optional) Either `allow` or `deny`. Defaults to `allow`.


## Attributes Reference
In addition to all argument, the following attributes are exported:

* **token** - The token of the robot account.
* **secret** - The secret of the robot account used for authentication
34 changes: 21 additions & 13 deletions models/robot_account.go
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
package models

type RobotBody struct {
Access []RobotBodyAccess `json:"access,omitempty"`
Name string `json:"name,omitempty"`
ExpiresAt int `json:"expires_at,omitempty"`
Description string `json:"description,omitempty"`
type RobotBodyPermission struct {
Access []RobotBodyAccess `json:"access,omitempty"`
Kind string `json:"kind,omitempty"`
Namespace string `json:"namespace,omitempty"`
}
type RobotBodyAccess struct {
Action string `json:"action,omitempty"`
Resource string `json:"resource,omitempty"`
Effect string `json:"effect,omitempty"`
}
type RobotBody struct {
ID int `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Level string `json:"level,omitempty"`
Description string `json:"description,omitempty"`
Secret string `json:"secret,omitempty"`
Duration int `json:"duration,omitempty"`
Disable bool `json:"disable,omitempty"`
Permissions []RobotBodyPermission `json:"permissions,omitempty"`
}
type RobotBodyRepones struct {
ID int `json:"id"`
Name string `json:"name"`
Token string `json:"token"`
Description string `json:"description"`
ProjectID int `json:"project_id"`
ExpiresAt int `json:"expires_at"`
Disabled bool `json:"disabled"`
type RobotBodyResponse struct {
ID int `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Secret string `json:"secret,omitempty"`
ExpiresAt int `json:"expires_at,omitempty"`
CreationTime string `json:"creation_time,omitempty"`
}
Loading

0 comments on commit b63e722

Please sign in to comment.