diff --git a/athenz/provider.go b/athenz/provider.go index 56ff4b0..c9196cb 100644 --- a/athenz/provider.go +++ b/athenz/provider.go @@ -51,6 +51,18 @@ func Provider() *schema.Provider { Optional: true, DefaultFunc: schema.EnvDefaultFunc("ATHENZ_RESOURCE_OWNER", "TF"), }, + "role_meta_resource_state": { + Type: schema.TypeInt, + Description: fmt.Sprintf("Default state for athenz_role_meta resources"), + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("ATHENZ_ROLE_META_RESOURCE_STATE", client.StateCreateIfNecessary), + }, + "group_meta_resource_state": { + Type: schema.TypeInt, + Description: fmt.Sprintf("Default state for athenz_group_meta resources"), + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("ATHENZ_GROUP_META_RESOURCE_STATE", client.StateCreateIfNecessary), + }, }, DataSourcesMap: map[string]*schema.Resource{ @@ -86,10 +98,12 @@ func Provider() *schema.Provider { func configProvider(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { zms := client.ZmsConfig{ - Url: d.Get("zms_url").(string), - Cert: d.Get("cert").(string), - Key: d.Get("key").(string), - CaCert: d.Get("cacert").(string), + Url: d.Get("zms_url").(string), + Cert: d.Get("cert").(string), + Key: d.Get("key").(string), + CaCert: d.Get("cacert").(string), + RoleMetaResourceState: d.Get("role_meta_resource_state").(int), + GroupMetaResourceState: d.Get("group_meta_resource_state").(int), } // if resource ownership is not disabled, then load the resource owner if !d.Get("disable_resource_ownership").(bool) { diff --git a/athenz/resource_group_meta.go b/athenz/resource_group_meta.go index 687307d..4b4670d 100644 --- a/athenz/resource_group_meta.go +++ b/athenz/resource_group_meta.go @@ -106,6 +106,11 @@ func ResourceGroupMeta() *schema.Resource { Type: schema.TypeString, }, }, + "resource_state": { + Type: schema.TypeInt, + Optional: true, + Default: -1, + }, }, } } @@ -137,9 +142,12 @@ func resourceGroupMetaCreate(ctx context.Context, d *schema.ResourceData, meta i gn := d.Get("name").(string) // if the group doesn't exist, we need to create it first - err := createNewGroupIfNecessary(zmsClient, dn, gn) - if err != nil { - return diag.FromErr(err) + // but only if the object_state is set to create if necessary + if zmsClient.GetGroupMetaResourceState(d.Get("resource_state").(int), client.StateCreateIfNecessary) { + err := createNewGroupIfNecessary(zmsClient, dn, gn) + if err != nil { + return diag.FromErr(err) + } } // update our group meta data @@ -297,30 +305,34 @@ func resourceGroupMetaDelete(_ context.Context, d *schema.ResourceData, meta int return diag.FromErr(err) } auditRef := d.Get("audit_ref").(string) - var zero int32 - zero = 0 - disabled := false - groupMeta := zms.GroupMeta{ - SelfServe: &disabled, - MemberExpiryDays: &zero, - ServiceExpiryDays: &zero, - ReviewEnabled: &disabled, - NotifyRoles: "", - UserAuthorityFilter: "", - UserAuthorityExpiration: "", - Tags: make(map[zms.TagKey]*zms.TagValueList), - DeleteProtection: &disabled, - SelfRenew: &disabled, - SelfRenewMins: &zero, - MaxMembers: &zero, - AuditEnabled: &disabled, - } - if v, ok := d.GetOk("tags"); ok { - for key := range v.(map[string]interface{}) { - groupMeta.Tags[zms.TagKey(key)] = &zms.TagValueList{List: []zms.TagCompoundValue{}} + if zmsClient.GetGroupMetaResourceState(d.Get("resource_state").(int), client.StateAlwaysDelete) { + err = zmsClient.DeleteGroup(dn, gn, auditRef) + } else { + var zero int32 + zero = 0 + disabled := false + groupMeta := zms.GroupMeta{ + SelfServe: &disabled, + MemberExpiryDays: &zero, + ServiceExpiryDays: &zero, + ReviewEnabled: &disabled, + NotifyRoles: "", + UserAuthorityFilter: "", + UserAuthorityExpiration: "", + Tags: make(map[zms.TagKey]*zms.TagValueList), + DeleteProtection: &disabled, + SelfRenew: &disabled, + SelfRenewMins: &zero, + MaxMembers: &zero, + AuditEnabled: &disabled, } + if v, ok := d.GetOk("tags"); ok { + for key := range v.(map[string]interface{}) { + groupMeta.Tags[zms.TagKey(key)] = &zms.TagValueList{List: []zms.TagCompoundValue{}} + } + } + err = zmsClient.PutGroupMeta(dn, gn, auditRef, &groupMeta) } - err = zmsClient.PutGroupMeta(dn, gn, auditRef, &groupMeta) if err != nil { return diag.FromErr(err) } diff --git a/athenz/resource_group_meta_test.go b/athenz/resource_group_meta_test.go index c9e4f8b..b6f8da6 100644 --- a/athenz/resource_group_meta_test.go +++ b/athenz/resource_group_meta_test.go @@ -1,8 +1,10 @@ package athenz import ( + "errors" "fmt" "github.com/AthenZ/athenz/clients/go/zms" + "github.com/ardielle/ardielle-go/rdl" "log" "os" "testing" @@ -152,3 +154,97 @@ resource "athenz_group_meta" "test_group_meta" { } `, domainName, groupName) } + +func TestAccGroupMetaResourceStateDelete(t *testing.T) { + if v := os.Getenv("TF_ACC"); v != "1" && v != "true" { + log.Print("TF_ACC must be set for acceptance tests") + return + } + if v := os.Getenv("DOMAIN"); v == "" { + t.Fatal("DOMAIN must be set for acceptance tests") + } + domainName := os.Getenv("DOMAIN") + groupName := "test-group-meta-delete" + resourceName := "athenz_group_meta.test_group_meta_delete" + t.Cleanup(func() { + cleanAccTestGroupMeta(domainName, groupName) + }) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviders, + CheckDestroy: testAccCheckGroupMetaResourceStateDeleteDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGroupMetaConfigResourceStateDelete(domainName, groupName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGroupMetaExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "domain", domainName), + resource.TestCheckResourceAttr(resourceName, "user_expiry_days", "30"), + resource.TestCheckResourceAttr(resourceName, "service_expiry_days", "70"), + resource.TestCheckResourceAttr(resourceName, "max_members", "90"), + resource.TestCheckResourceAttr(resourceName, "self_serve", "true"), + resource.TestCheckResourceAttr(resourceName, "self_renew", "true"), + resource.TestCheckResourceAttr(resourceName, "self_renew_mins", "100"), + resource.TestCheckResourceAttr(resourceName, "delete_protection", "true"), + resource.TestCheckResourceAttr(resourceName, "review_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "notify_roles", "admin,security"), + resource.TestCheckResourceAttr(resourceName, "tags.zms.DisableExpirationNotifications", "4"), + resource.TestCheckResourceAttr(resourceName, "audit_ref", "test audit ref"), + ), + }, + }, + }) +} + +func testAccCheckGroupMetaResourceStateDeleteDestroy(s *terraform.State) error { + zmsClient := testAccProvider.Meta().(client.ZmsClient) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "athenz_group_meta" { + continue + } + dn, gn, err := splitGroupId(rs.Primary.ID) + if err != nil { + return err + } + // make sure our group is deleted and 404 is returned + _, err = zmsClient.GetGroup(dn, gn) + if err == nil { + _ = zmsClient.DeleteGroup(dn, gn, AUDIT_REF) + return fmt.Errorf("athenz group still exists") + } + var v rdl.ResourceError + switch { + case errors.As(err, &v): + if v.Code == 404 { + return nil + } + } + return fmt.Errorf("unexpected error: %v", err) + } + + return nil +} + +func testAccGroupMetaConfigResourceStateDelete(domainName, groupName string) string { + return fmt.Sprintf(` +resource "athenz_group_meta" "test_group_meta_delete" { + domain = "%s" + name = "%s" + user_expiry_days = 30 + service_expiry_days = 70 + max_members = 90 + self_serve = true + self_renew = true + self_renew_mins = 100 + delete_protection = true + review_enabled = true + notify_roles = "admin,security" + tags = { + "zms.DisableExpirationNotifications" = "4" + } + resource_state = 3 + audit_ref = "test audit ref" +} +`, domainName, groupName) +} diff --git a/athenz/resource_role_meta.go b/athenz/resource_role_meta.go index c2f35c1..75bce09 100644 --- a/athenz/resource_role_meta.go +++ b/athenz/resource_role_meta.go @@ -144,6 +144,11 @@ func ResourceRoleMeta() *schema.Resource { Type: schema.TypeString, }, }, + "resource_state": { + Type: schema.TypeInt, + Optional: true, + Default: -1, + }, }, } } @@ -175,9 +180,12 @@ func resourceRoleMetaCreate(ctx context.Context, d *schema.ResourceData, meta in rn := d.Get("name").(string) // if the role doesn't exist, we need to create it first - err := createNewRoleIfNecessary(zmsClient, dn, rn) - if err != nil { - return diag.FromErr(err) + // but only if the object_state is set to create if necessary + if zmsClient.GetRoleMetaResourceState(d.Get("resource_state").(int), client.StateCreateIfNecessary) { + err := createNewRoleIfNecessary(zmsClient, dn, rn) + if err != nil { + return diag.FromErr(err) + } } // update our role meta data @@ -405,38 +413,42 @@ func resourceRoleMetaDelete(_ context.Context, d *schema.ResourceData, meta inte return diag.FromErr(err) } auditRef := d.Get("audit_ref").(string) - var zero int32 - zero = 0 - disabled := false - roleMeta := zms.RoleMeta{ - SelfServe: &disabled, - MemberExpiryDays: &zero, - TokenExpiryMins: &zero, - CertExpiryMins: &zero, - SignAlgorithm: "", - ServiceExpiryDays: &zero, - MemberReviewDays: &zero, - ServiceReviewDays: &zero, - ReviewEnabled: &disabled, - NotifyRoles: "", - UserAuthorityFilter: "", - UserAuthorityExpiration: "", - GroupExpiryDays: &zero, - GroupReviewDays: &zero, - Tags: make(map[zms.TagKey]*zms.TagValueList), - Description: "", - DeleteProtection: &disabled, - SelfRenew: &disabled, - SelfRenewMins: &zero, - MaxMembers: &zero, - AuditEnabled: &disabled, - } - if v, ok := d.GetOk("tags"); ok { - for key := range v.(map[string]interface{}) { - roleMeta.Tags[zms.TagKey(key)] = &zms.TagValueList{List: []zms.TagCompoundValue{}} + if zmsClient.GetRoleMetaResourceState(d.Get("resource_state").(int), client.StateAlwaysDelete) { + err = zmsClient.DeleteRole(dn, rn, auditRef) + } else { + var zero int32 + zero = 0 + disabled := false + roleMeta := zms.RoleMeta{ + SelfServe: &disabled, + MemberExpiryDays: &zero, + TokenExpiryMins: &zero, + CertExpiryMins: &zero, + SignAlgorithm: "", + ServiceExpiryDays: &zero, + MemberReviewDays: &zero, + ServiceReviewDays: &zero, + ReviewEnabled: &disabled, + NotifyRoles: "", + UserAuthorityFilter: "", + UserAuthorityExpiration: "", + GroupExpiryDays: &zero, + GroupReviewDays: &zero, + Tags: make(map[zms.TagKey]*zms.TagValueList), + Description: "", + DeleteProtection: &disabled, + SelfRenew: &disabled, + SelfRenewMins: &zero, + MaxMembers: &zero, + AuditEnabled: &disabled, } + if v, ok := d.GetOk("tags"); ok { + for key := range v.(map[string]interface{}) { + roleMeta.Tags[zms.TagKey(key)] = &zms.TagValueList{List: []zms.TagCompoundValue{}} + } + } + err = zmsClient.PutRoleMeta(dn, rn, auditRef, &roleMeta) } - err = zmsClient.PutRoleMeta(dn, rn, auditRef, &roleMeta) if err != nil { return diag.FromErr(err) } diff --git a/athenz/resource_role_meta_test.go b/athenz/resource_role_meta_test.go index 758d0a3..b6717c8 100644 --- a/athenz/resource_role_meta_test.go +++ b/athenz/resource_role_meta_test.go @@ -1,8 +1,10 @@ package athenz import ( + "errors" "fmt" "github.com/AthenZ/athenz/clients/go/zms" + "github.com/ardielle/ardielle-go/rdl" "log" "os" "testing" @@ -174,3 +176,111 @@ resource "athenz_role_meta" "test_role_meta" { } `, domainName, roleName) } + +func TestAccRoleMetaResourceStateDelete(t *testing.T) { + if v := os.Getenv("TF_ACC"); v != "1" && v != "true" { + log.Print("TF_ACC must be set for acceptance tests") + return + } + if v := os.Getenv("DOMAIN"); v == "" { + t.Fatal("DOMAIN must be set for acceptance tests") + } + domainName := os.Getenv("DOMAIN") + roleName := "test-role-meta-delete" + resourceName := "athenz_role_meta.test_role_meta_delete" + t.Cleanup(func() { + cleanAccTestRoleMeta(domainName, roleName) + }) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviders, + CheckDestroy: testAccCheckRoleMetaResourceStateDeleteDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRoleMetaConfigResourceStateDelete(domainName, roleName), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoleMetaExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "domain", domainName), + resource.TestCheckResourceAttr(resourceName, "description", "test role"), + resource.TestCheckResourceAttr(resourceName, "token_expiry_mins", "10"), + resource.TestCheckResourceAttr(resourceName, "cert_expiry_mins", "20"), + resource.TestCheckResourceAttr(resourceName, "user_expiry_days", "30"), + resource.TestCheckResourceAttr(resourceName, "user_review_days", "40"), + resource.TestCheckResourceAttr(resourceName, "group_expiry_days", "50"), + resource.TestCheckResourceAttr(resourceName, "group_review_days", "60"), + resource.TestCheckResourceAttr(resourceName, "service_expiry_days", "70"), + resource.TestCheckResourceAttr(resourceName, "service_review_days", "80"), + resource.TestCheckResourceAttr(resourceName, "max_members", "90"), + resource.TestCheckResourceAttr(resourceName, "self_serve", "true"), + resource.TestCheckResourceAttr(resourceName, "self_renew", "true"), + resource.TestCheckResourceAttr(resourceName, "self_renew_mins", "100"), + resource.TestCheckResourceAttr(resourceName, "delete_protection", "true"), + resource.TestCheckResourceAttr(resourceName, "review_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "notify_roles", "admin,security"), + resource.TestCheckResourceAttr(resourceName, "tags.zms.DisableExpirationNotifications", "4"), + resource.TestCheckResourceAttr(resourceName, "audit_ref", "test audit ref"), + ), + }, + }, + }) +} + +func testAccCheckRoleMetaResourceStateDeleteDestroy(s *terraform.State) error { + zmsClient := testAccProvider.Meta().(client.ZmsClient) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "athenz_role_meta" { + continue + } + dn, rn, err := splitRoleId(rs.Primary.ID) + if err != nil { + return err + } + // make sure our role is deleted and 404 is returned + _, err = zmsClient.GetRole(dn, rn) + if err == nil { + _ = zmsClient.DeleteRole(dn, rn, AUDIT_REF) + return fmt.Errorf("athenz role still exists") + } + var v rdl.ResourceError + switch { + case errors.As(err, &v): + if v.Code == 404 { + return nil + } + } + return fmt.Errorf("unexpected error: %v", err) + } + + return nil +} + +func testAccRoleMetaConfigResourceStateDelete(domainName, roleName string) string { + return fmt.Sprintf(` +resource "athenz_role_meta" "test_role_meta_delete" { + domain = "%s" + name = "%s" + description = "test role" + token_expiry_mins = 10 + cert_expiry_mins = 20 + user_expiry_days = 30 + user_review_days = 40 + group_expiry_days = 50 + group_review_days = 60 + service_expiry_days = 70 + service_review_days = 80 + max_members = 90 + self_serve = true + self_renew = true + self_renew_mins = 100 + delete_protection = true + review_enabled = true + notify_roles = "admin,security" + tags = { + "zms.DisableExpirationNotifications" = "4" + } + resource_state = 3 + audit_ref = "test audit ref" +} +`, domainName, roleName) +} diff --git a/client/client.go b/client/client.go index 4e7c661..72843fd 100644 --- a/client/client.go +++ b/client/client.go @@ -10,6 +10,9 @@ import ( "github.com/AthenZ/athenz/clients/go/zms" ) +const StateCreateIfNecessary = 0x01 +const StateAlwaysDelete = 0x02 + type ZmsClient interface { GetRole(domain string, roleName string) (*zms.Role, error) DeleteRole(domain string, roleName string, auditRef string) error @@ -51,20 +54,26 @@ type ZmsClient interface { GetPolicies(domainName string, assertions bool, includeNonActive bool) (*zms.Policies, error) PutGroupMeta(domain string, groupName string, auditRef string, group *zms.GroupMeta) error PutRoleMeta(domain string, roleName string, auditRef string, group *zms.RoleMeta) error + GetRoleMetaResourceState(roleMetaResourceState, requestedState int) bool + GetGroupMetaResourceState(groupMetaResourceState, requestedState int) bool } type Client struct { - Url string - Transport *http.Transport - ResourceOwner string + Url string + Transport *http.Transport + ResourceOwner string + RoleMetaResourceState int + GroupMetaResourceState int } type ZmsConfig struct { - Url string - Cert string - Key string - CaCert string - ResourceOwner string + Url string + Cert string + Key string + CaCert string + ResourceOwner string + RoleMetaResourceState int + GroupMetaResourceState int } func (c Client) GetPolicies(domainName string, assertions bool, includeNonActive bool) (*zms.Policies, error) { @@ -283,6 +292,24 @@ func (c Client) PutRoleMeta(domain string, roleName string, auditRef string, rol return err } +func (c Client) GetRoleMetaResourceState(roleMetaResourceState, requestedState int) bool { + return getResourceState(roleMetaResourceState, c.RoleMetaResourceState, requestedState) +} + +func (c Client) GetGroupMetaResourceState(groupMetaResourceState, requestedState int) bool { + return getResourceState(groupMetaResourceState, c.GroupMetaResourceState, requestedState) +} + +func getResourceState(resourceState, clientState, requestedState int) bool { + if resourceState == -1 { + resourceState = clientState + } + if resourceState == -1 { + return false + } + return (resourceState & requestedState) != 0 +} + func NewClient(zmsConfig *ZmsConfig) (*Client, error) { tlsConfig, err := getTLSConfigFromFiles(zmsConfig.Cert, zmsConfig.Key, zmsConfig.CaCert) if err != nil { @@ -292,9 +319,11 @@ func NewClient(zmsConfig *ZmsConfig) (*Client, error) { TLSClientConfig: tlsConfig, } client := &Client{ - Url: zmsConfig.Url, - Transport: &transport, - ResourceOwner: zmsConfig.ResourceOwner, + Url: zmsConfig.Url, + Transport: &transport, + ResourceOwner: zmsConfig.ResourceOwner, + RoleMetaResourceState: zmsConfig.RoleMetaResourceState, + GroupMetaResourceState: zmsConfig.GroupMetaResourceState, } return client, err } diff --git a/client/client_test.go b/client/client_test.go new file mode 100644 index 0000000..aa435d1 --- /dev/null +++ b/client/client_test.go @@ -0,0 +1,73 @@ +package client + +import ( + "testing" +) + +func TestGetResourceState(t *testing.T) { + tests := []struct { + name string + resourceState int + clientState int + requestedState int + want bool + }{ + { + name: "resourceState is -1, clientState is -1, requestedState is 1", + resourceState: -1, + clientState: -1, + requestedState: StateCreateIfNecessary, + want: false, + }, + { + name: "resourceState is 1, clientState is -1, requestedState is 1", + resourceState: 1, + clientState: -1, + requestedState: StateCreateIfNecessary, + want: true, + }, + { + name: "resourceState is -1, clientState is 1, requestedState is 1", + resourceState: -1, + clientState: 1, + requestedState: StateCreateIfNecessary, + want: true, + }, + { + name: "resourceState is 1, clientState is 0, requestedState is 1", + resourceState: 1, + clientState: 1, + requestedState: StateCreateIfNecessary, + want: true, + }, + { + name: "resourceState is 3, clientState is 0, requestedState is 2", + resourceState: 3, + clientState: 0, + requestedState: StateAlwaysDelete, + want: true, + }, + { + name: "resourceState is 1, clientState is 1, requestedState is 2", + resourceState: 1, + clientState: 1, + requestedState: StateAlwaysDelete, + want: false, + }, + { + name: "resourceState is -1, clientState is 3, requestedState is 2", + resourceState: -1, + clientState: 3, + requestedState: StateAlwaysDelete, + want: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := getResourceState(tt.resourceState, tt.clientState, tt.requestedState); got != tt.want { + t.Errorf("getResourceState() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/client/test_client.go b/client/test_client.go deleted file mode 100644 index 12f4cc5..0000000 --- a/client/test_client.go +++ /dev/null @@ -1,31 +0,0 @@ -package client - -import ( - "testing" - - "github.com/AthenZ/athenz/clients/go/zms" - "github.com/golang/mock/gomock" -) - -var ( - t *testing.T - domainName = "user.mshneorson" -) - -func PrepareMockClient(_t *testing.T) { - t = _t -} - -func AccTestZmsClient() (*MockZmsClient, error) { - mockCtrl := gomock.NewController(t) - clientMock := NewMockZmsClient(mockCtrl) - clientMock.EXPECT().GetRole(domainName, "foo123").Return(simpleRole(), nil).AnyTimes() - clientMock.EXPECT().GetRole(domainName, "foo123").Return(nil, nil) - clientMock.EXPECT().PutRole(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() - - return clientMock, nil -} - -func simpleRole() *zms.Role { - return &zms.Role{Name: "test"} -} diff --git a/docs/index.md b/docs/index.md index ae650ed..e43abcc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -75,8 +75,10 @@ provider "athenz" { ### Optional -- `cacert` (String) CA Certificate file path -- `cert` (String) Athenz client x.509 certificate - `key` (String) Athenz client private key -- `disable_resource_ownership` (Bool) Disable resource ownership. Default is false. -- `resource_owner` (String) Resource owner. Default is "TF". +- `cert` (String) Athenz client x.509 certificate +- `cacert` (String) CA Certificate file path +- `disable_resource_ownership` (Bool) Disable resource ownership. Default is false +- `resource_owner` (String) Resource owner. Default is "TF" +- `role_meta_resource_state` (Number) Bitmask of object state flags controlling role behavior when creating or destroying role_meta resources. 0x01: create the role if not already present, 0x02: always delete the role when destroying the resource. Default value is 1. The value is used when the resource_state attribute at the athenz_role_meta level is set to -1 +- `group_meta_resource_state` (Number) Bitmask of object state flags controlling group behavior when creating or destroying group_meta resources. 0x01: create the group if not already present, 0x02: always delete the group when destroying the resource. Default value is 1. The value is used when the resource_state attribute at the athenz_group_meta level is set to -1 diff --git a/docs/resources/group_meta.md b/docs/resources/group_meta.md index 9eeb6f9..d125149 100644 --- a/docs/resources/group_meta.md +++ b/docs/resources/group_meta.md @@ -53,6 +53,7 @@ resource "athenz_group_meta" "group_meta" { - `delete_protection` (Bool) If true, ask for delete confirmation in audit and review enabled groups - `max_members` (Number) maximum number of members allowed in the group - `notify_roles` (String) comma seperated list of roles whose members should be notified for member review/approval +- `resource_state` (Number) Bitmask of resource state flags controlling group behavior when creating or destroying the resource. 0x01: create the group if not already present, 0x02: always delete the group when destroying the resource. Default value is -1 indicating to inherit the value defined at the provider configuration level. - `review_enabled` (Bool) Flag indicates whether group updates require another review and approval - `self_renew` (Bool) Flag indicates whether to allow expired members to renew their membership - `self_renew_mins` (Number) Number of minutes members can renew their membership if self review option is enabled diff --git a/docs/resources/role_meta.md b/docs/resources/role_meta.md index 39ed82e..96de419 100644 --- a/docs/resources/role_meta.md +++ b/docs/resources/role_meta.md @@ -65,6 +65,7 @@ resource "athenz_role_meta" "role_meta" { - `group_review_days` (Number) all groups in the role will have specified review reminder days - `max_members` (Number) maximum number of members allowed in the role - `notify_roles` (String) comma seperated list of roles whose members should be notified for member review/approval +- `resource_state` (Number) Bitmask of resource state flags controlling role behavior when creating or destroying the resource. 0x01: create the role if not already present, 0x02: always delete the role when destroying the resource. Default value is -1 indicating to inherit the value defined at the provider configuration level - `review_enabled` (Bool) Flag indicates whether role updates require another review and approval - `self_renew` (Bool) Flag indicates whether to allow expired members to renew their membership - `self_renew_mins` (Number) Number of minutes members can renew their membership if self review option is enabled