Skip to content

Commit 7dc16ba

Browse files
authored
Merge pull request #286 from aquasecurity/SLK-88696-tp-add-support-for-rbac-v-3-permission-sets
feat(permission_set_saas): create resource, datasource, example, docs
2 parents f66f720 + 569d506 commit 7dc16ba

File tree

13 files changed

+983
-1
lines changed

13 files changed

+983
-1
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package aquasec
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"math/rand"
7+
8+
"github.com/aquasecurity/terraform-provider-aquasec/client"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
11+
)
12+
13+
func dataSourcePermissionsSetsSaas() *schema.Resource {
14+
return &schema.Resource{
15+
Description: "The data source `aquasec_permissions_sets_saas` provides a method to query all permissions within Aqua SaaS platform",
16+
ReadContext: dataPermissionsSetsSaasRead,
17+
Schema: map[string]*schema.Schema{
18+
"permissions_sets": {
19+
Type: schema.TypeList,
20+
Computed: true,
21+
Elem: &schema.Resource{
22+
Schema: map[string]*schema.Schema{
23+
"name": {
24+
Type: schema.TypeString,
25+
Description: "Name of the permission set",
26+
Computed: true,
27+
},
28+
"description": {
29+
Type: schema.TypeString,
30+
Description: "Description of the permission set",
31+
Computed: true,
32+
},
33+
"actions": {
34+
Type: schema.TypeList,
35+
Description: "List of allowed actions",
36+
Computed: true,
37+
Elem: &schema.Schema{
38+
Type: schema.TypeString,
39+
},
40+
},
41+
},
42+
},
43+
},
44+
},
45+
}
46+
}
47+
48+
func dataPermissionsSetsSaasRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
49+
c := m.(*client.Client)
50+
permissionsSets, err := c.GetPermissionSetsSaas()
51+
if err != nil {
52+
return diag.FromErr(err)
53+
}
54+
55+
id := ""
56+
ps := make([]interface{}, len(permissionsSets))
57+
58+
for i, permissionsSet := range permissionsSets {
59+
id = id + permissionsSet.Name
60+
p := make(map[string]interface{})
61+
p["name"] = permissionsSet.Name
62+
p["description"] = permissionsSet.Description
63+
p["actions"] = permissionsSet.Actions
64+
ps[i] = p
65+
}
66+
67+
if id == "" {
68+
id = fmt.Sprintf("no-permissions-found-%d", rand.Int())
69+
}
70+
d.SetId(id)
71+
if err := d.Set("permissions_sets", ps); err != nil {
72+
return diag.FromErr(err)
73+
}
74+
return nil
75+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package aquasec
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
9+
)
10+
11+
func TestAquasecPermissionsSetSaasDatasource(t *testing.T) {
12+
if !isSaasEnv() {
13+
t.Skip("Skipping permission set test because its not a SaaS environment")
14+
}
15+
16+
resource.Test(t, resource.TestCase{
17+
PreCheck: func() { testAccPreCheck(t) },
18+
Providers: testAccProviders,
19+
Steps: []resource.TestStep{
20+
{
21+
Config: testAccCheckAquasecPermissionsSetSaasBasicConfig(),
22+
Check: resource.ComposeTestCheckFunc(
23+
// Check that the data source was created
24+
testAccCheckAquasecPermissionsSetSaasExists("data.aquasec_permissions_sets_saas.test"),
25+
// Check list attribute is populated
26+
resource.TestCheckResourceAttrSet("data.aquasec_permissions_sets_saas.test", "permissions_sets.#"),
27+
// Custom check for data validity
28+
testAccCheckPermissionsSetSaasAttributes("data.aquasec_permissions_sets_saas.test"),
29+
),
30+
},
31+
},
32+
})
33+
}
34+
35+
func TestAquasecPermissionsSetSaasDatasource_Structure(t *testing.T) {
36+
if !isSaasEnv() {
37+
t.Skip("Skipping permission set test because its not a SaaS environment")
38+
}
39+
40+
resource.Test(t, resource.TestCase{
41+
PreCheck: func() { testAccPreCheck(t) },
42+
Providers: testAccProviders,
43+
Steps: []resource.TestStep{
44+
{
45+
Config: testAccCheckAquasecPermissionsSetSaasBasicConfig(),
46+
Check: resource.ComposeTestCheckFunc(
47+
// Verify ID exists
48+
resource.TestCheckResourceAttrSet(
49+
"data.aquasec_permissions_sets_saas.test",
50+
"id",
51+
),
52+
// Verify permissions_sets list exists
53+
resource.TestCheckResourceAttrSet(
54+
"data.aquasec_permissions_sets_saas.test",
55+
"permissions_sets.#",
56+
),
57+
),
58+
},
59+
},
60+
})
61+
}
62+
63+
// Basic Config
64+
func testAccCheckAquasecPermissionsSetSaasBasicConfig() string {
65+
return `
66+
data "aquasec_permissions_sets_saas" "test" {
67+
}
68+
`
69+
}
70+
71+
// Check data source exists
72+
func testAccCheckAquasecPermissionsSetSaasExists(n string) resource.TestCheckFunc {
73+
return func(s *terraform.State) error {
74+
rs, ok := s.RootModule().Resources[n]
75+
if !ok {
76+
return fmt.Errorf("Not found: %s", n)
77+
}
78+
79+
if rs.Primary.ID == "" {
80+
return fmt.Errorf("No ID is set")
81+
}
82+
83+
return nil
84+
}
85+
}
86+
87+
// Check attributes match schema
88+
func testAccCheckPermissionsSetSaasAttributes(resourceName string) resource.TestCheckFunc {
89+
return func(s *terraform.State) error {
90+
rs, ok := s.RootModule().Resources[resourceName]
91+
if !ok {
92+
return fmt.Errorf("Not found: %s", resourceName)
93+
}
94+
95+
numSets, ok := rs.Primary.Attributes["permissions_sets.#"]
96+
if !ok {
97+
return fmt.Errorf("No permissions_sets found")
98+
}
99+
100+
// If we have permission sets, verify their structure
101+
if numSets != "0" {
102+
// Get the first permission set and verify required attributes
103+
if name, ok := rs.Primary.Attributes["permissions_sets.0.name"]; !ok || name == "" {
104+
return fmt.Errorf("permissions_sets.0.name is empty or missing")
105+
}
106+
107+
if desc, exists := rs.Primary.Attributes["permissions_sets.0.description"]; exists {
108+
if desc == "" {
109+
return fmt.Errorf("permissions_sets.0.description is empty")
110+
}
111+
}
112+
113+
if _, ok := rs.Primary.Attributes["permissions_sets.0.actions.#"]; !ok {
114+
return fmt.Errorf("permissions_sets.0.actions is missing")
115+
}
116+
}
117+
118+
return nil
119+
}
120+
}

aquasec/provider.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ func Provider(v string) *schema.Provider {
9393
"aquasec_group": resourceGroup(),
9494
"aquasec_user_saas": resourceUserSaas(),
9595
"aquasec_role_mapping_saas": resourceRoleMappingSaas(),
96+
"aquasec_permission_set_saas": resourcePermissionSetSaas(),
9697
},
9798
DataSourcesMap: map[string]*schema.Resource{
9899
"aquasec_users": dataSourceUsers(),
@@ -123,6 +124,7 @@ func Provider(v string) *schema.Provider {
123124
"aquasec_groups": dataSourceGroups(),
124125
"aquasec_users_saas": dataSourceUsersSaas(),
125126
"aquasec_roles_mapping_saas": dataSourceRolesMappingSaas(),
127+
"aquasec_permissions_sets_saas": dataSourcePermissionsSetsSaas(),
126128
},
127129
ConfigureContextFunc: providerConfigure,
128130
}

aquasec/resource_permission_set.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ func resourcePermissionSet() *schema.Resource {
2828
Description: "The name of the Permission Set, comprised of alphanumeric characters and '-', '_', ' ', ':', '.', '@', '!', '^'.",
2929
Required: true,
3030
ForceNew: true,
31+
ValidateFunc: validateSaasResourceWarning("aquasec_permissions_sets", "aquasec_permission_set_saas"),
3132
},
3233
"description": {
3334
Type: schema.TypeString,
@@ -66,6 +67,7 @@ func resourcePermissionSet() *schema.Resource {
6667
}
6768
}
6869

70+
6971
func resourcePermissionSetCreate(d *schema.ResourceData, m interface{}) error {
7072
ac := m.(*client.Client)
7173
name := d.Get("name").(string)
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package aquasec
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/aquasecurity/terraform-provider-aquasec/client"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
)
10+
11+
func resourcePermissionSetSaas() *schema.Resource {
12+
return &schema.Resource{
13+
Description: "The `aquasec_permission_set_saas` resource manages your Permission Set within Aqua SaaS environment.",
14+
Create: resourcePermissionSetSaasCreate,
15+
Read: resourcePermissionSetSaasRead,
16+
Update: resourcePermissionSetSaasUpdate,
17+
Delete: resourcePermissionSetSaasDelete,
18+
Importer: &schema.ResourceImporter{
19+
StateContext: schema.ImportStatePassthroughContext,
20+
},
21+
Schema: map[string]*schema.Schema{
22+
"name": {
23+
Type: schema.TypeString,
24+
Description: "Name of the permission set",
25+
Required: true,
26+
ForceNew: true,
27+
},
28+
"description": {
29+
Type: schema.TypeString,
30+
Description: "Description of the permission set",
31+
Optional: true,
32+
},
33+
"actions": {
34+
Type: schema.TypeList,
35+
Description: "List of allowed actions for the permission set",
36+
Optional: true,
37+
Elem: &schema.Schema{
38+
Type: schema.TypeString,
39+
},
40+
},
41+
},
42+
}
43+
}
44+
45+
func resourcePermissionSetSaasCreate(d *schema.ResourceData, m interface{}) error {
46+
ac := m.(*client.Client)
47+
name := d.Get("name").(string)
48+
49+
permSet := expandPermissionSetSaas(d)
50+
err := ac.CreatePermissionSetSaas(permSet)
51+
if err != nil {
52+
return err
53+
}
54+
55+
d.SetId(name)
56+
return resourcePermissionSetSaasRead(d, m)
57+
}
58+
59+
func resourcePermissionSetSaasUpdate(d *schema.ResourceData, m interface{}) error {
60+
ac := m.(*client.Client)
61+
62+
if d.HasChanges("description", "actions") {
63+
permSet := expandPermissionSetSaas(d)
64+
err := ac.UpdatePermissionSetSaas(permSet)
65+
if err != nil {
66+
return err
67+
}
68+
}
69+
70+
return resourcePermissionSetSaasRead(d, m)
71+
}
72+
73+
func resourcePermissionSetSaasRead(d *schema.ResourceData, m interface{}) error {
74+
c := m.(*client.Client)
75+
76+
permSet, err := c.GetPermissionSetSaas(d.Id())
77+
if err != nil {
78+
if strings.Contains(fmt.Sprintf("%s", err), "404") {
79+
d.SetId("")
80+
return nil
81+
}
82+
return err
83+
}
84+
85+
d.Set("name", permSet.Name)
86+
d.Set("description", permSet.Description)
87+
d.Set("actions", permSet.Actions)
88+
89+
return nil
90+
}
91+
92+
func resourcePermissionSetSaasDelete(d *schema.ResourceData, m interface{}) error {
93+
ac := m.(*client.Client)
94+
name := d.Get("name").(string)
95+
96+
err := ac.DeletePermissionSetSaas(name)
97+
if err != nil {
98+
return err
99+
}
100+
101+
d.SetId("")
102+
return nil
103+
}
104+
105+
func expandPermissionSetSaas(d *schema.ResourceData) *client.PermissionSetSaas {
106+
permSet := client.PermissionSetSaas{
107+
Name: d.Get("name").(string),
108+
Description: d.Get("description").(string),
109+
}
110+
111+
if v, ok := d.GetOk("actions"); ok {
112+
rawActions := v.([]interface{})
113+
actions := make([]string, len(rawActions))
114+
for i, action := range rawActions {
115+
actions[i] = action.(string)
116+
}
117+
permSet.Actions = actions
118+
}
119+
120+
return &permSet
121+
}

0 commit comments

Comments
 (0)