From 5a9ce628394f4f4506538fc7999d32fabf7c43a8 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Sat, 2 Nov 2024 20:05:06 +0800 Subject: [PATCH] misc: add deprecation and finalized docs --- docs/resources/project_role.md | 40 ++++++++-- .../infisical_project_role/resource.tf | 22 ++++-- .../resource/project_role_resource.go | 76 ++++++------------- 3 files changed, 69 insertions(+), 69 deletions(-) diff --git a/docs/resources/project_role.md b/docs/resources/project_role.md index 268d3fa..ac0101e 100644 --- a/docs/resources/project_role.md +++ b/docs/resources/project_role.md @@ -38,14 +38,22 @@ resource "infisical_project_role" "biller" { name = "Tester" description = "A test role" slug = "tester" - permissions = [ + permissions_v2 = [ { - action = "read" - subject = "secrets", - conditions = { - environment = "dev" - secret_path = "/dev" - } + subject = "integrations" + action = ["read", "create"] + inverted = true + }, + { + subject = "secrets" + action = ["read", "edit"] + conditions = jsonencode({ + environment = { + "$in" = ["dev", "prod"] + "$eq" = "dev" + } + }) + inverted = false }, ] } @@ -57,13 +65,14 @@ resource "infisical_project_role" "biller" { ### Required - `name` (String) The name for the new role -- `permissions` (Attributes List) The permissions assigned to the project role (see [below for nested schema](#nestedatt--permissions)) - `project_slug` (String) The slug of the project to create role - `slug` (String) The slug for the new role ### Optional - `description` (String) The description for the new role. Defaults to an empty string. +- `permissions` (Attributes List, Deprecated) (DEPRECATED, USE permissions_v2) The permissions assigned to the project role (see [below for nested schema](#nestedatt--permissions)) +- `permissions_v2` (Attributes Set) The permissions assigned to the project role. Refer to the documentation here https://infisical.com/docs/internals/permissions for its usage. (see [below for nested schema](#nestedatt--permissions_v2)) ### Read-Only @@ -88,3 +97,18 @@ Optional: - `environment` (String) The environment slug this permission should allow. - `secret_path` (String) The secret path this permission should be scoped to + + + + +### Nested Schema for `permissions_v2` + +Required: + +- `action` (Set of String) Describe what actions an entity can take. +- `inverted` (Boolean) Whether rule forbids. Set this to true if permission forbids. +- `subject` (String) Describe the entity the permission pertains to. + +Optional: + +- `conditions` (String) When specified, only matching conditions will be allowed to access given resource. diff --git a/examples/resources/infisical_project_role/resource.tf b/examples/resources/infisical_project_role/resource.tf index a1965c3..dd91f4e 100644 --- a/examples/resources/infisical_project_role/resource.tf +++ b/examples/resources/infisical_project_role/resource.tf @@ -23,14 +23,22 @@ resource "infisical_project_role" "biller" { name = "Tester" description = "A test role" slug = "tester" - permissions = [ + permissions_v2 = [ { - action = "read" - subject = "secrets", - conditions = { - environment = "dev" - secret_path = "/dev" - } + subject = "integrations" + action = ["read", "create"] + inverted = true + }, + { + subject = "secrets" + action = ["read", "edit"] + conditions = jsonencode({ + environment = { + "$in" = ["dev", "prod"] + "$eq" = "dev" + } + }) + inverted = false }, ] } diff --git a/internal/provider/resource/project_role_resource.go b/internal/provider/resource/project_role_resource.go index b834a3b..8a44f6a 100644 --- a/internal/provider/resource/project_role_resource.go +++ b/internal/provider/resource/project_role_resource.go @@ -39,10 +39,10 @@ type projectRoleResource struct { } type PermissionV2Entry struct { - Action []string `tfsdk:"action"` - Subject string `tfsdk:"subject"` - Inverted bool `tfsdk:"inverted"` - Conditions string `tfsdk:"conditions"` + Action types.Set `tfsdk:"action"` + Subject types.String `tfsdk:"subject"` + Inverted types.Bool `tfsdk:"inverted"` + Conditions types.String `tfsdk:"conditions"` } // projectRoleResourceSourceModel describes the data source data model. @@ -67,43 +67,6 @@ type projectRoleResourcePermissionCondition struct { SecretPath types.String `tfsdk:"secret_path"` } -func validatePermissionV2Array(permissions []map[string]any) error { - for _, permission := range permissions { - subject, exists := permission["subject"] - if !exists { - return fmt.Errorf("Error parsing permissions_v2: subject property should be defined") - } - - _, ok := subject.(string) - if !ok { - return fmt.Errorf("Error parsing permissions_v2: subject property should be a string") - } - - action, exists := permission["action"] - if !exists { - return fmt.Errorf("Error parsing permissions_v2: action property should be defined") - } - - _, ok = action.([]interface{}) - if !ok { - return fmt.Errorf("Error parsing permissions_v2: action property should be an array") - } - - inverted, exists := permission["inverted"] - if !exists { - return fmt.Errorf("Error parsing permissions_v2: inverted property should be defined") - } - - _, ok = inverted.(bool) - if !ok { - return fmt.Errorf("Error parsing permissions_v2: inverted property should be a boolean") - } - - } - - return nil -} - // Metadata returns the resource type name. func (r *projectRoleResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { resp.TypeName = req.ProviderTypeName + "_project_role" @@ -155,16 +118,16 @@ func (r *projectRoleResource) Schema(_ context.Context, _ resource.SchemaRequest }, "permissions_v2": schema.SetNestedAttribute{ Optional: true, - Description: "The permissions assigned to the project role", + Description: "The permissions assigned to the project role. Refer to the documentation here https://infisical.com/docs/internals/permissions for its usage.", NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ "action": schema.SetAttribute{ ElementType: types.StringType, - Description: fmt.Sprintf("Describe what actions an entity can take. Enum: %s", strings.Join(PERMISSION_ACTIONS, ",")), + Description: fmt.Sprintf("Describe what actions an entity can take."), Required: true, }, "subject": schema.StringAttribute{ - Description: fmt.Sprintf("Describe the entity the permission pertains to. Enum: %s", strings.Join(PERMISSION_SUBJECTS, ",")), + Description: fmt.Sprintf("Describe the entity the permission pertains to."), Required: true, }, "inverted": schema.BoolAttribute{ @@ -185,8 +148,9 @@ func (r *projectRoleResource) Schema(_ context.Context, _ resource.SchemaRequest }, }, "permissions": schema.ListNestedAttribute{ - Optional: true, - Description: "The permissions assigned to the project role", + Optional: true, + DeprecationMessage: "Use permissions_v2 instead as it allows you to be more granular with access control", + Description: "(DEPRECATED, USE permissions_v2) The permissions assigned to the project role", NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ "action": schema.StringAttribute{ @@ -336,9 +300,9 @@ func (r *projectRoleResource) Create(ctx context.Context, req resource.CreateReq } // parse as object - if perm.Conditions != "" { + if !perm.Conditions.IsNull() { var conditionsMap map[string]interface{} - if err := json.Unmarshal([]byte(perm.Conditions), &conditionsMap); err != nil { + if err := json.Unmarshal([]byte(perm.Conditions.ValueString()), &conditionsMap); err != nil { resp.Diagnostics.AddError( "Error creating project role", "Error parsing conditions property: "+err.Error(), @@ -567,15 +531,19 @@ func (r *projectRoleResource) Read(ctx context.Context, req resource.ReadRequest for i, v := range actionRaw { actions[i] = v.(string) } - entry.Action = actions + entry.Action, diags = types.SetValueFrom(ctx, types.StringType, actions) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } } if subject, ok := permMap["subject"].(string); ok { - entry.Subject = subject + entry.Subject = types.StringValue(subject) } if inverted, ok := permMap["inverted"].(bool); ok { - entry.Inverted = inverted + entry.Inverted = types.BoolValue(inverted) } if conditions, ok := permMap["conditions"].(map[string]any); ok { @@ -588,7 +556,7 @@ func (r *projectRoleResource) Read(ctx context.Context, req resource.ReadRequest return } - entry.Conditions = string(conditionsBytes) + entry.Conditions = types.StringValue(string(conditionsBytes)) } permissions[i] = entry @@ -714,9 +682,9 @@ func (r *projectRoleResource) Update(ctx context.Context, req resource.UpdateReq "inverted": perm.Inverted, } - if perm.Conditions != "" { + if !perm.Conditions.IsNull() { var conditionsMap map[string]interface{} - if err := json.Unmarshal([]byte(perm.Conditions), &conditionsMap); err != nil { + if err := json.Unmarshal([]byte(perm.Conditions.ValueString()), &conditionsMap); err != nil { resp.Diagnostics.AddError( "Error updating project role", "Error parsing conditions property: "+err.Error(),