diff --git a/docs/data-sources/clusterrolebinding.md b/docs/data-sources/clusterrolebinding.md index 8d8a57e..d544229 100644 --- a/docs/data-sources/clusterrolebinding.md +++ b/docs/data-sources/clusterrolebinding.md @@ -64,27 +64,15 @@ Optional: Read-Only: -- `policy_inline` (List of Object) (see [below for nested schema](#nestedobjatt--spec--policy_inline)) -- `policy_ref` (String) +- `role_ref` (List of Object) (see [below for nested schema](#nestedobjatt--spec--role_ref)) - `subject_ref` (List of Object) (see [below for nested schema](#nestedobjatt--spec--subject_ref)) - -### Nested Schema for `spec.policy_inline` + +### Nested Schema for `spec.role_ref` Read-Only: -- `actions` (Set of String) -- `paths` (Set of String) -- `resources` (List of Object) (see [below for nested schema](#nestedobjatt--spec--policy_inline--resources)) - - -### Nested Schema for `spec.policy_inline.resources` - -Read-Only: - -- `api_group` (String) -- `kind` (String) - +- `name` (String) diff --git a/docs/data-sources/clusterrolebindings.md b/docs/data-sources/clusterrolebindings.md index f5d5bd7..48627e4 100644 --- a/docs/data-sources/clusterrolebindings.md +++ b/docs/data-sources/clusterrolebindings.md @@ -73,27 +73,15 @@ Read-Only: Read-Only: -- `policy_inline` (List of Object) (see [below for nested schema](#nestedobjatt--items--spec--policy_inline)) -- `policy_ref` (String) +- `role_ref` (List of Object) (see [below for nested schema](#nestedobjatt--items--spec--role_ref)) - `subject_ref` (List of Object) (see [below for nested schema](#nestedobjatt--items--spec--subject_ref)) - -### Nested Schema for `items.spec.policy_inline` + +### Nested Schema for `items.spec.role_ref` Read-Only: -- `actions` (Set of String) -- `paths` (Set of String) -- `resources` (List of Object) (see [below for nested schema](#nestedobjatt--items--spec--policy_inline--resources)) - - -### Nested Schema for `items.spec.policy_inline.resources` - -Read-Only: - -- `api_group` (String) -- `kind` (String) - +- `name` (String) diff --git a/docs/data-sources/role.md b/docs/data-sources/role.md new file mode 100644 index 0000000..d99c5fb --- /dev/null +++ b/docs/data-sources/role.md @@ -0,0 +1,84 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "bluechip_role Data Source - terraform-provider-bluechip" +subcategory: "" +description: |- + +--- + +# bluechip_role (Data Source) + + + +## Example Usage + +```terraform +data "bluechip_role" "current" { + metadata { + name = "my-test" + } +} +``` + + +## Schema + +### Optional + +- `metadata` (Block List) (see [below for nested schema](#nestedblock--metadata)) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `spec` (List of Object) (see [below for nested schema](#nestedatt--spec)) + + +### Nested Schema for `metadata` + +Required: + +- `name` (String) Name is the name of the resource. + +Optional: + +- `annotations` (Map of String) Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. +- `labels` (Map of String) Labels are key value pairs that may be used to scope and select individual resources. They are not queryable and should be preserved when modifying objects. + +Read-Only: + +- `creation_timestamp` (String) CreationTimestamp is a timestamp representing the server time when this object was created. +- `update_timestamp` (String) UpdateTimestamp is a timestamp representing the server time when this object was last updated. + + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) + + + +### Nested Schema for `spec` + +Read-Only: + +- `statements` (List of Object) (see [below for nested schema](#nestedobjatt--spec--statements)) + + +### Nested Schema for `spec.statements` + +Read-Only: + +- `actions` (Set of String) +- `paths` (Set of String) +- `resources` (List of Object) (see [below for nested schema](#nestedobjatt--spec--statements--resources)) + + +### Nested Schema for `spec.statements.resources` + +Read-Only: + +- `api_group` (String) +- `kind` (String) diff --git a/docs/data-sources/rolebinding.md b/docs/data-sources/rolebinding.md index 694b828..8ca87f6 100644 --- a/docs/data-sources/rolebinding.md +++ b/docs/data-sources/rolebinding.md @@ -66,27 +66,15 @@ Optional: Read-Only: -- `policy_inline` (List of Object) (see [below for nested schema](#nestedobjatt--spec--policy_inline)) -- `policy_ref` (String) +- `role_ref` (List of Object) (see [below for nested schema](#nestedobjatt--spec--role_ref)) - `subject_ref` (List of Object) (see [below for nested schema](#nestedobjatt--spec--subject_ref)) - -### Nested Schema for `spec.policy_inline` + +### Nested Schema for `spec.role_ref` Read-Only: -- `actions` (Set of String) -- `paths` (Set of String) -- `resources` (List of Object) (see [below for nested schema](#nestedobjatt--spec--policy_inline--resources)) - - -### Nested Schema for `spec.policy_inline.resources` - -Read-Only: - -- `api_group` (String) -- `kind` (String) - +- `name` (String) diff --git a/docs/data-sources/rolebindings.md b/docs/data-sources/rolebindings.md index 9efa9a3..370d72f 100644 --- a/docs/data-sources/rolebindings.md +++ b/docs/data-sources/rolebindings.md @@ -84,27 +84,15 @@ Read-Only: Read-Only: -- `policy_inline` (List of Object) (see [below for nested schema](#nestedobjatt--items--spec--policy_inline)) -- `policy_ref` (String) +- `role_ref` (List of Object) (see [below for nested schema](#nestedobjatt--items--spec--role_ref)) - `subject_ref` (List of Object) (see [below for nested schema](#nestedobjatt--items--spec--subject_ref)) - -### Nested Schema for `items.spec.policy_inline` + +### Nested Schema for `items.spec.role_ref` Read-Only: -- `actions` (Set of String) -- `paths` (Set of String) -- `resources` (List of Object) (see [below for nested schema](#nestedobjatt--items--spec--policy_inline--resources)) - - -### Nested Schema for `items.spec.policy_inline.resources` - -Read-Only: - -- `api_group` (String) -- `kind` (String) - +- `name` (String) diff --git a/docs/data-sources/roles.md b/docs/data-sources/roles.md new file mode 100644 index 0000000..c770f77 --- /dev/null +++ b/docs/data-sources/roles.md @@ -0,0 +1,93 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "bluechip_roles Data Source - terraform-provider-bluechip" +subcategory: "" +description: |- + +--- + +# bluechip_roles (Data Source) + + + +## Example Usage + +```terraform +data "bluechip_roles" "current" { +} +``` + + +## Schema + +### Optional + +- `filter` (Block List) Filter is a list of query terms to filter the results by. (see [below for nested schema](#nestedblock--filter)) +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `items` (List of Object) Filter is a list of query terms to filter the results by. (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `filter` + +Required: + +- `field` (String) Field to use for the query term. +- `operator` (String) Operator to use for the query term. One of ['equals', 'notEquals', 'fuzzy', 'wildcard', 'regex', 'matchPhrase', 'prefix']. +- `value` (String) Value to use for the query term. + + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) + + + +### Nested Schema for `items` + +Read-Only: + +- `metadata` (List of Object) (see [below for nested schema](#nestedobjatt--items--metadata)) +- `spec` (List of Object) (see [below for nested schema](#nestedobjatt--items--spec)) + + +### Nested Schema for `items.metadata` + +Read-Only: + +- `annotations` (Map of String) +- `creation_timestamp` (String) +- `labels` (Map of String) +- `name` (String) +- `update_timestamp` (String) + + + +### Nested Schema for `items.spec` + +Read-Only: + +- `statements` (List of Object) (see [below for nested schema](#nestedobjatt--items--spec--statements)) + + +### Nested Schema for `items.spec.statements` + +Read-Only: + +- `actions` (Set of String) +- `paths` (Set of String) +- `resources` (List of Object) (see [below for nested schema](#nestedobjatt--items--spec--statements--resources)) + + +### Nested Schema for `items.spec.statements.resources` + +Read-Only: + +- `api_group` (String) +- `kind` (String) diff --git a/docs/resources/clusterrolebinding.md b/docs/resources/clusterrolebinding.md index 3bbf222..c63d5b1 100644 --- a/docs/resources/clusterrolebinding.md +++ b/docs/resources/clusterrolebinding.md @@ -66,42 +66,24 @@ Read-Only: Required: +- `role_ref` (Block List, Min: 1) (see [below for nested schema](#nestedblock--spec--role_ref)) - `subject_ref` (Block List, Min: 1) (see [below for nested schema](#nestedblock--spec--subject_ref)) -Optional: - -- `policy_inline` (Block List) (see [below for nested schema](#nestedblock--spec--policy_inline)) -- `policy_ref` (String) - - -### Nested Schema for `spec.subject_ref` + +### Nested Schema for `spec.role_ref` Required: -- `kind` (String) Kind of the referent. Valid kinds are 'User', 'Group'. - `name` (String) Name of the referent. - -### Nested Schema for `spec.policy_inline` - -Required: - -- `actions` (Set of String) Actions is a list of actions this role binding grants access to. - -Optional: - -- `paths` (Set of String) Paths is a list of paths this role binding grants access to. -- `resources` (Block List) Resources is a list of resources this role binding grants access to. (see [below for nested schema](#nestedblock--spec--policy_inline--resources)) - - -### Nested Schema for `spec.policy_inline.resources` + +### Nested Schema for `spec.subject_ref` Required: -- `api_group` (String) APIGroup is the group for the resource being referenced. -- `kind` (String) Kind is the type of resource being referenced. - +- `kind` (String) Kind of the referent. Valid kinds are 'User', 'Group'. +- `name` (String) Name of the referent. diff --git a/docs/resources/role.md b/docs/resources/role.md new file mode 100644 index 0000000..e0d7ea0 --- /dev/null +++ b/docs/resources/role.md @@ -0,0 +1,98 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "bluechip_role Resource - terraform-provider-bluechip" +subcategory: "" +description: |- + +--- + +# bluechip_role (Resource) + + + +## Example Usage + +```terraform +resource "bluechip_role" "current" { + metadata { + name = "my-test" + } + spec { + statements { + actions = ["read"] + paths = ["/**"] + } + } +} +``` + + +## Schema + +### Required + +- `metadata` (Block List, Min: 1) (see [below for nested schema](#nestedblock--metadata)) +- `spec` (Block List, Min: 1) (see [below for nested schema](#nestedblock--spec)) + +### Optional + +- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) + +### Read-Only + +- `id` (String) The ID of this resource. + + +### Nested Schema for `metadata` + +Required: + +- `name` (String) Name is the name of the resource. + +Optional: + +- `annotations` (Map of String) Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. +- `labels` (Map of String) Labels are key value pairs that may be used to scope and select individual resources. They are not queryable and should be preserved when modifying objects. + +Read-Only: + +- `creation_timestamp` (String) CreationTimestamp is a timestamp representing the server time when this object was created. +- `update_timestamp` (String) UpdateTimestamp is a timestamp representing the server time when this object was last updated. + + + +### Nested Schema for `spec` + +Required: + +- `statements` (Block List, Min: 1) (see [below for nested schema](#nestedblock--spec--statements)) + + +### Nested Schema for `spec.statements` + +Required: + +- `actions` (Set of String) Actions is a list of actions this role binding grants access to. + +Optional: + +- `paths` (Set of String) Paths is a list of paths this role binding grants access to. +- `resources` (Block List) Resources is a list of resources this role binding grants access to. (see [below for nested schema](#nestedblock--spec--statements--resources)) + + +### Nested Schema for `spec.statements.resources` + +Required: + +- `api_group` (String) APIGroup is the group for the resource being referenced. +- `kind` (String) Kind is the type of resource being referenced. + + + + + +### Nested Schema for `timeouts` + +Optional: + +- `default` (String) diff --git a/docs/resources/rolebinding.md b/docs/resources/rolebinding.md index e21b09a..79713b4 100644 --- a/docs/resources/rolebinding.md +++ b/docs/resources/rolebinding.md @@ -68,42 +68,24 @@ Read-Only: Required: +- `role_ref` (Block List, Min: 1) (see [below for nested schema](#nestedblock--spec--role_ref)) - `subject_ref` (Block List, Min: 1) (see [below for nested schema](#nestedblock--spec--subject_ref)) -Optional: - -- `policy_inline` (Block List) (see [below for nested schema](#nestedblock--spec--policy_inline)) -- `policy_ref` (String) - - -### Nested Schema for `spec.subject_ref` + +### Nested Schema for `spec.role_ref` Required: -- `kind` (String) Kind of the referent. Valid kinds are 'User', 'Group'. - `name` (String) Name of the referent. - -### Nested Schema for `spec.policy_inline` - -Required: - -- `actions` (Set of String) Actions is a list of actions this role binding grants access to. - -Optional: - -- `paths` (Set of String) Paths is a list of paths this role binding grants access to. -- `resources` (Block List) Resources is a list of resources this role binding grants access to. (see [below for nested schema](#nestedblock--spec--policy_inline--resources)) - - -### Nested Schema for `spec.policy_inline.resources` + +### Nested Schema for `spec.subject_ref` Required: -- `api_group` (String) APIGroup is the group for the resource being referenced. -- `kind` (String) Kind is the type of resource being referenced. - +- `kind` (String) Kind of the referent. Valid kinds are 'User', 'Group'. +- `name` (String) Name of the referent. diff --git a/docs/resources/user.md b/docs/resources/user.md index 8005ee8..f7762a9 100644 --- a/docs/resources/user.md +++ b/docs/resources/user.md @@ -63,11 +63,11 @@ Read-Only: Required: +- `attributes` (Map of String) - `password` (String) Optional: -- `attributes` (Map of String) - `groups` (Set of String) diff --git a/examples/data-sources/bluechip_role/data-source.tf b/examples/data-sources/bluechip_role/data-source.tf new file mode 100644 index 0000000..ccc5fcf --- /dev/null +++ b/examples/data-sources/bluechip_role/data-source.tf @@ -0,0 +1,5 @@ +data "bluechip_role" "current" { + metadata { + name = "my-test" + } +} diff --git a/examples/data-sources/bluechip_roles/data-source.tf b/examples/data-sources/bluechip_roles/data-source.tf new file mode 100644 index 0000000..250c16c --- /dev/null +++ b/examples/data-sources/bluechip_roles/data-source.tf @@ -0,0 +1,2 @@ +data "bluechip_roles" "current" { +} diff --git a/examples/resources/bluechip_role/resource.tf b/examples/resources/bluechip_role/resource.tf new file mode 100644 index 0000000..f87721c --- /dev/null +++ b/examples/resources/bluechip_role/resource.tf @@ -0,0 +1,11 @@ +resource "bluechip_role" "current" { + metadata { + name = "my-test" + } + spec { + statements { + actions = ["read"] + paths = ["/**"] + } + } +} diff --git a/internal/services/applications/whoami_data_source_test.go b/internal/services/applications/whoami_data_source_test.go index b85f13d..95d39b0 100644 --- a/internal/services/applications/whoami_data_source_test.go +++ b/internal/services/applications/whoami_data_source_test.go @@ -126,7 +126,7 @@ func TestProviderChain(t *testing.T) { Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr("data.bluechip_whoami.current", "id", "admin"), resource.TestCheckResourceAttr("data.bluechip_whoami.current", "name", "admin"), - resource.TestCheckResourceAttr("data.bluechip_whoami.current", "groups.0", "system-admin"), + resource.TestCheckResourceAttr("data.bluechip_whoami.current", "groups.0", "system:admin"), ), }, }, @@ -135,11 +135,11 @@ func TestProviderChain(t *testing.T) { const TestAccProviderChainConfig = ` provider "bluechip" { - address = "https://bluechip.example.io" + address = "http://localhost:3000" auth_flow { basic { - username = "aaaaa" - password = "fooooo" + username = "admin" + password = "ulizzang" } } auth_flow { diff --git a/internal/services/cidrs/data_sources_test.go b/internal/services/cidrs/data_sources_test.go index db4da17..4661d96 100644 --- a/internal/services/cidrs/data_sources_test.go +++ b/internal/services/cidrs/data_sources_test.go @@ -34,11 +34,11 @@ func TestAccDataSources(t *testing.T) { const TestAccDataSourcesConfig = ` data "bluechip_cidrs" "current" { - namespace = "office" + namespace = "default" } data "bluechip_cidrs" "current2" { - namespace = "office" + namespace = "default" filter { operator = "fuzzy" diff --git a/internal/services/clusterrolebindings/resource_test.go b/internal/services/clusterrolebindings/resource_test.go index 42a797a..5122f44 100644 --- a/internal/services/clusterrolebindings/resource_test.go +++ b/internal/services/clusterrolebindings/resource_test.go @@ -19,13 +19,13 @@ func TestAccResource(t *testing.T) { resource.TestCheckResourceAttr("bluechip_clusterrolebinding.current", "metadata.0.name", "my-test1"), resource.TestCheckResourceAttrSet("bluechip_clusterrolebinding.current", "metadata.0.creation_timestamp"), - resource.TestCheckResourceAttrSet("bluechip_clusterrolebinding.policy_inline_path", "metadata.0.creation_timestamp"), - resource.TestCheckResourceAttrSet("bluechip_clusterrolebinding.policy_inline_resource", "metadata.0.creation_timestamp"), - resource.TestCheckResourceAttrSet("bluechip_clusterrolebinding.current", "spec.0.policy_ref"), - resource.TestCheckResourceAttr("bluechip_clusterrolebinding.policy_inline_path", "spec.0.policy_inline.0.actions.0", "read"), - resource.TestCheckResourceAttr("bluechip_clusterrolebinding.policy_inline_path", "spec.0.policy_inline.0.paths.0", "/**"), - resource.TestCheckResourceAttr("bluechip_clusterrolebinding.policy_inline_resource", "spec.0.policy_inline.0.actions.0", "read"), - resource.TestCheckResourceAttr("bluechip_clusterrolebinding.policy_inline_resource", "spec.0.policy_inline.0.resources.0.api_group", "core"), + //resource.TestCheckResourceAttrSet("bluechip_clusterrolebinding.policy_inline_path", "metadata.0.creation_timestamp"), + //resource.TestCheckResourceAttrSet("bluechip_clusterrolebinding.policy_inline_resource", "metadata.0.creation_timestamp"), + //resource.TestCheckResourceAttrSet("bluechip_clusterrolebinding.current", "spec.0.policy_ref"), + //resource.TestCheckResourceAttr("bluechip_clusterrolebinding.policy_inline_path", "spec.0.policy_inline.0.actions.0", "read"), + //resource.TestCheckResourceAttr("bluechip_clusterrolebinding.policy_inline_path", "spec.0.policy_inline.0.paths.0", "/**"), + //resource.TestCheckResourceAttr("bluechip_clusterrolebinding.policy_inline_resource", "spec.0.policy_inline.0.actions.0", "read"), + //resource.TestCheckResourceAttr("bluechip_clusterrolebinding.policy_inline_resource", "spec.0.policy_inline.0.resources.0.api_group", "core"), ), }, }, @@ -35,48 +35,15 @@ func TestAccResource(t *testing.T) { const TestAccResourceConfig = ` resource "bluechip_clusterrolebinding" "current" { metadata { - name = "my-test1" + name = "my-test" } spec { subject_ref { kind = "User" name = "my-test" } - policy_ref = "admin" - } -} - -resource "bluechip_clusterrolebinding" "policy_inline_path" { - metadata { - name = "my-test2" - } - spec { - subject_ref { - kind = "User" - name = "my-test" - } - policy_inline { - actions = ["read"] - paths = ["/**"] - } - } -} - -resource "bluechip_clusterrolebinding" "policy_inline_resource" { - metadata { - name = "my-test3" - } - spec { - subject_ref { - kind = "User" - name = "my-test" - } - policy_inline { - actions = ["read"] - resources { - api_group = "core" - kind = "Namespace" - } + role_ref { + name = "admin" } } } diff --git a/internal/services/clusterrolebindings/type.go b/internal/services/clusterrolebindings/type.go index 4b63ab4..5ad0e3e 100644 --- a/internal/services/clusterrolebindings/type.go +++ b/internal/services/clusterrolebindings/type.go @@ -24,16 +24,14 @@ func (t SpecType) Expand(ctx context.Context, d *schema.ResourceData, out *bluec } out.SubjectsRef = rb.SubjectsRef - out.PolicyInline = rb.PolicyInline - out.PolicyRef = rb.PolicyRef + out.RoleRef = rb.RoleRef return nil } func (t SpecType) Flatten(in bluechip_models.ClusterRoleBindingSpec) map[string]any { var rb bluechip_models.RoleBindingSpec rb.SubjectsRef = in.SubjectsRef - rb.PolicyInline = in.PolicyInline - rb.PolicyRef = in.PolicyRef + rb.RoleRef = in.RoleRef return t.RbType.Flatten(rb) } diff --git a/internal/services/images/data_sources_test.go b/internal/services/images/data_sources_test.go index d8f455c..32bbaad 100644 --- a/internal/services/images/data_sources_test.go +++ b/internal/services/images/data_sources_test.go @@ -28,10 +28,10 @@ func TestAccDataSources(t *testing.T) { const TestAccDataSourcesConfig = ` data "bluechip_images" "current" { filter { - operator = "equal" + operator = "equals" field = "spec.commitHash" value = "6874ece755439b5b3473b5b910fb4938751d6689" } - namespace = "pubg" + namespace = "default" } ` diff --git a/internal/services/rolebindings/data_sources_test.go b/internal/services/rolebindings/data_sources_test.go index 0d58f28..a5c939c 100644 --- a/internal/services/rolebindings/data_sources_test.go +++ b/internal/services/rolebindings/data_sources_test.go @@ -28,10 +28,10 @@ func TestAccDataSources(t *testing.T) { const TestAccDataSourcesConfig = ` data "bluechip_rolebindings" "current" { filter { - operator = "equal" - key = "metadata.name" + operator = "equals" + field = "metadata.name" value = "" } - namespace = "pubg" + namespace = "default" } ` diff --git a/internal/services/rolebindings/resource_test.go b/internal/services/rolebindings/resource_test.go index 552ab09..58e83aa 100644 --- a/internal/services/rolebindings/resource_test.go +++ b/internal/services/rolebindings/resource_test.go @@ -38,7 +38,9 @@ resource "bluechip_rolebinding" "current" { kind = "User" name = "my-test" } - policy_ref = "admin" + role_ref { + name = "admin" + } } } ` diff --git a/internal/services/roles/data_source.go b/internal/services/roles/data_source.go new file mode 100644 index 0000000..c9db73e --- /dev/null +++ b/internal/services/roles/data_source.go @@ -0,0 +1,18 @@ +package roles + +import ( + "time" + + "github.com/pubg/terraform-provider-bluechip/pkg/bluechip_client/bluechip_models" + "github.com/pubg/terraform-provider-bluechip/pkg/framework/fwservices" +) + +func NewDataSource() fwservices.ResourceFactory { + return &fwservices.ClusterTerraformDataSource[bluechip_models.Role, bluechip_models.RoleSpec]{ + Gvk: bluechip_models.RoleGvk, + Timeout: 30 * time.Second, + + MetadataType: fwservices.ClusterDataSourceMetadataType, + SpecType: &SpecType{Computed: true}, + } +} diff --git a/internal/services/roles/data_source_test.go b/internal/services/roles/data_source_test.go new file mode 100644 index 0000000..8cd5956 --- /dev/null +++ b/internal/services/roles/data_source_test.go @@ -0,0 +1,37 @@ +package roles + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/pubg/terraform-provider-bluechip/internal/testacc" +) + +func TestAccDataSource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testacc.TestAccPreCheck(t) }, + ProtoV5ProviderFactories: testacc.TestAccProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testacc.CombinedConfig(TestAccResourceConfig, TestAccDataSourceConfig), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.bluechip_role.current", "id", "my-test"), + resource.TestCheckResourceAttr("data.bluechip_role.current", "metadata.0.name", "my-test"), + resource.TestCheckResourceAttrSet("data.bluechip_role.current", "metadata.0.creation_timestamp"), + resource.TestCheckResourceAttrWith("data.bluechip_role.current", "metadata.0.name", func(value string) error { + return nil + }), + ), + }, + }, + }) +} + +const TestAccDataSourceConfig = ` +data "bluechip_role" "current" { + metadata { + name = "my-test" + } + depends_on = [bluechip_role.current] +} +` diff --git a/internal/services/roles/data_sources.go b/internal/services/roles/data_sources.go new file mode 100644 index 0000000..efd2b00 --- /dev/null +++ b/internal/services/roles/data_sources.go @@ -0,0 +1,20 @@ +package roles + +import ( + "time" + + "github.com/pubg/terraform-provider-bluechip/pkg/bluechip_client/bluechip_models" + "github.com/pubg/terraform-provider-bluechip/pkg/framework/fwservices" + "github.com/pubg/terraform-provider-bluechip/pkg/framework/fwtype" +) + +func NewDataSources() fwservices.ResourceFactory { + return &fwservices.ClusterTerraformDataSources[bluechip_models.Role, bluechip_models.RoleSpec]{ + Gvk: bluechip_models.RoleGvk, + Timeout: 30 * time.Second, + + FilterType: fwtype.FilterType{}, + MetadataType: fwservices.ClusterDataSourcesMetadataType, + SpecType: &SpecType{Computed: true}, + } +} diff --git a/internal/services/roles/data_sources_test.go b/internal/services/roles/data_sources_test.go new file mode 100644 index 0000000..02b0e54 --- /dev/null +++ b/internal/services/roles/data_sources_test.go @@ -0,0 +1,31 @@ +package roles + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/pubg/terraform-provider-bluechip/internal/testacc" +) + +func TestAccDataSources(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testacc.TestAccPreCheck(t) }, + ProtoV5ProviderFactories: testacc.TestAccProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testacc.CombinedConfig(TestAccDataSourcesConfig), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.bluechip_roles.current", "id", "pubg"), + resource.TestCheckResourceAttrWith("data.bluechip_roles.current", "items.#", func(value string) error { + return nil + }), + ), + }, + }, + }) +} + +const TestAccDataSourcesConfig = ` +data "bluechip_roles" "current" { +} +` diff --git a/internal/services/roles/register.go b/internal/services/roles/register.go new file mode 100644 index 0000000..17ead5d --- /dev/null +++ b/internal/services/roles/register.go @@ -0,0 +1,9 @@ +package roles + +import "github.com/pubg/terraform-provider-bluechip/internal/provider" + +func init() { + provider.RegisterResource("bluechip_role", NewResource().Resource()) + provider.RegisterDataSource("bluechip_role", NewDataSource().Resource()) + provider.RegisterDataSource("bluechip_roles", NewDataSources().Resource()) +} diff --git a/internal/services/roles/resource.go b/internal/services/roles/resource.go new file mode 100644 index 0000000..3a69f06 --- /dev/null +++ b/internal/services/roles/resource.go @@ -0,0 +1,25 @@ +package roles + +import ( + "time" + + "github.com/pubg/terraform-provider-bluechip/pkg/bluechip_client/bluechip_models" + "github.com/pubg/terraform-provider-bluechip/pkg/framework/fwservices" +) + +func NewResource() fwservices.ResourceFactory { + return &fwservices.ClusterTerraformResource[bluechip_models.Role, bluechip_models.RoleSpec]{ + Gvk: bluechip_models.RoleGvk, + Timeout: 30 * time.Second, + Constructor: func() bluechip_models.Role { + return bluechip_models.Role{ + TypeMeta: &bluechip_models.TypeMeta{}, + MetadataContainer: &bluechip_models.MetadataContainer{}, + SpecContainer: &bluechip_models.SpecContainer[bluechip_models.RoleSpec]{}, + } + }, + + MetadataType: fwservices.ClusterResourceMetadataType, + SpecType: &SpecType{Computed: false}, + } +} diff --git a/internal/services/roles/resource_test.go b/internal/services/roles/resource_test.go new file mode 100644 index 0000000..0af5741 --- /dev/null +++ b/internal/services/roles/resource_test.go @@ -0,0 +1,42 @@ +package roles + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/pubg/terraform-provider-bluechip/internal/testacc" +) + +func TestAccResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testacc.TestAccPreCheck(t) }, + ProtoV5ProviderFactories: testacc.TestAccProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testacc.CombinedConfig(TestAccResourceConfig), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("bluechip_role.current", "id", "my-test"), + resource.TestCheckResourceAttr("bluechip_role.current", "metadata.0.name", "my-test"), + resource.TestCheckResourceAttrSet("bluechip_role.current", "metadata.0.creation_timestamp"), + resource.TestCheckResourceAttrWith("bluechip_role.current", "metadata.0.name", func(value string) error { + return nil + }), + ), + }, + }, + }) +} + +const TestAccResourceConfig = ` +resource "bluechip_role" "current" { + metadata { + name = "my-test" + } + spec { + statements { + actions = ["read"] + paths = ["/**"] + } + } +} +` diff --git a/internal/services/roles/type.go b/internal/services/roles/type.go new file mode 100644 index 0000000..4578653 --- /dev/null +++ b/internal/services/roles/type.go @@ -0,0 +1,128 @@ +package roles + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/pubg/terraform-provider-bluechip/pkg/bluechip_client/bluechip_models" + "github.com/pubg/terraform-provider-bluechip/pkg/framework/fwflex" + "github.com/pubg/terraform-provider-bluechip/pkg/framework/fwtype" +) + +type SpecType struct { + Computed bool +} + +func (t SpecType) Schema() *schema.Schema { + innerSchema := map[string]*schema.Schema{ + "statements": { + Type: schema.TypeList, + Required: !t.Computed, + Computed: t.Computed, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "actions": { + Type: schema.TypeSet, + Description: "Actions is a list of actions this role binding grants access to.", + Required: !t.Computed, + Computed: t.Computed, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "paths": { + Type: schema.TypeSet, + Description: "Paths is a list of paths this role binding grants access to.", + Optional: !t.Computed, + Computed: t.Computed, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "resources": { + Type: schema.TypeList, + Description: "Resources is a list of resources this role binding grants access to.", + Optional: !t.Computed, + Computed: t.Computed, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "api_group": { + Type: schema.TypeString, + Description: "APIGroup is the group for the resource being referenced.", + Required: !t.Computed, + Computed: t.Computed, + }, + "kind": { + Type: schema.TypeString, + Description: "Kind is the type of resource being referenced.", + Required: !t.Computed, + Computed: t.Computed, + }, + }, + }, + }, + }, + }, + }, + } + + blockSchema := fwtype.SingleNestedBlock(innerSchema, t.Computed, true) + fwtype.CleanForDataSource(blockSchema) + return blockSchema +} + +func (t SpecType) Expand(ctx context.Context, d *schema.ResourceData, out *bluechip_models.RoleSpec) diag.Diagnostics { + attr := d.Get("spec.0").(map[string]any) + + rawStatementList := fwflex.ExpandMapList(attr["statements"].([]any)) + for _, rawStatement := range rawStatementList { + statement := bluechip_models.PolicyStatement{ + Actions: fwflex.ExpandStringSet(rawStatement["actions"].(*schema.Set)), + } + + if rawStatement["paths"] != nil { + statement.Paths = fwflex.ExpandStringSet(rawStatement["paths"].(*schema.Set)) + } + + if rawStatement["resources"] != nil { + for _, rawPolicyResource := range fwflex.ExpandMapList(rawStatement["resources"].([]any)) { + policyResource := bluechip_models.PolicyResource{ + ApiGroup: rawPolicyResource["api_group"].(string), + Kind: rawPolicyResource["kind"].(string), + } + statement.Resources = append(statement.Resources, policyResource) + } + } + + out.Statements = append(out.Statements, statement) + } + + return nil +} + +func (t SpecType) Flatten(in bluechip_models.RoleSpec) map[string]any { + attr := map[string]any{ + "statements": []map[string]any{}, + } + + for _, statement := range in.Statements { + rawStatement := map[string]any{ + "actions": statement.Actions, + } + + if len(statement.Paths) != 0 { + rawStatement["paths"] = statement.Paths + } + + var policyResources []map[string]any + for _, policyResource := range statement.Resources { + rawPolicyResource := map[string]any{ + "api_group": policyResource.ApiGroup, + "kind": policyResource.Kind, + } + policyResources = append(policyResources, rawPolicyResource) + } + if len(policyResources) != 0 { + rawStatement["resources"] = policyResources + } + attr["statements"] = append(attr["statements"].([]map[string]any), rawStatement) + } + return attr +} diff --git a/internal/services/users/resource_test.go b/internal/services/users/resource_test.go index faa22d4..111369d 100644 --- a/internal/services/users/resource_test.go +++ b/internal/services/users/resource_test.go @@ -35,6 +35,7 @@ resource "bluechip_user" "current" { spec { password = "tetete" groups = ["asdf"] + attributes = {} } } ` diff --git a/internal/services/users/type.go b/internal/services/users/type.go index 2164e4a..bafd55f 100644 --- a/internal/services/users/type.go +++ b/internal/services/users/type.go @@ -29,7 +29,7 @@ func (t SpecType) Schema() *schema.Schema { }, "attributes": { Type: schema.TypeMap, - Optional: true, + Required: !t.Computed, Computed: t.Computed, Elem: &schema.Schema{Type: schema.TypeString}, }, diff --git a/main.go b/main.go index 1fe84ff..7c7440b 100644 --- a/main.go +++ b/main.go @@ -17,6 +17,7 @@ import ( _ "github.com/pubg/terraform-provider-bluechip/internal/services/namespaces" _ "github.com/pubg/terraform-provider-bluechip/internal/services/oidcauths" _ "github.com/pubg/terraform-provider-bluechip/internal/services/rolebindings" + _ "github.com/pubg/terraform-provider-bluechip/internal/services/roles" _ "github.com/pubg/terraform-provider-bluechip/internal/services/users" _ "github.com/pubg/terraform-provider-bluechip/internal/services/vendors" ) diff --git a/pkg/bluechip_client/bluechip_models/gvks.go b/pkg/bluechip_client/bluechip_models/gvks.go index a9d06fc..b6313f6 100644 --- a/pkg/bluechip_client/bluechip_models/gvks.go +++ b/pkg/bluechip_client/bluechip_models/gvks.go @@ -86,6 +86,13 @@ var OidcAuthGvk = GroupVersionKind{ KindPlural: "OidcAuths", } +var RoleGvk = GroupVersionKind{ + Group: "rbac.bluechip.pubg.io", + Version: "v1", + Kind: "Role", + KindPlural: "Roles", +} + var UsersGvk = GroupVersionKind{ Group: "auth.bluechip.pubg.io", Version: "v1", diff --git a/pkg/bluechip_client/bluechip_models/resources.go b/pkg/bluechip_client/bluechip_models/resources.go index 18761d7..7289d22 100644 --- a/pkg/bluechip_client/bluechip_models/resources.go +++ b/pkg/bluechip_client/bluechip_models/resources.go @@ -149,8 +149,8 @@ type UserSpec struct { BaseSpec `json:"-"` Password string `json:"password"` - Groups []string `json:"groups,omitempty"` - Attributes map[string]string `json:"attributes,omitempty"` + Groups []string `json:"groups"` + Attributes map[string]string `json:"attributes"` } var _ ClusterApiResource[OidcAuthSpec] = &OidcAuth{} @@ -195,9 +195,8 @@ type ClusterRoleBinding struct { type ClusterRoleBindingSpec struct { BaseSpec `json:"-"` - SubjectsRef SubjectRef `json:"subjectsRef"` - PolicyInline []PolicyStatement `json:"policyInline,omitempty"` - PolicyRef *string `json:"policyRef,omitempty"` + SubjectsRef SubjectRef `json:"subjectsRef"` + RoleRef RoleRef `json:"roleRef"` } var _ NamespacedApiResource[RoleBindingSpec] = &RoleBinding{} @@ -213,9 +212,22 @@ type RoleBinding struct { type RoleBindingSpec struct { BaseSpec `json:"-"` - SubjectsRef SubjectRef `json:"subjectsRef"` - PolicyInline []PolicyStatement `json:"policyInline,omitempty"` - PolicyRef *string `json:"policyRef,omitempty"` + SubjectsRef SubjectRef `json:"subjectsRef"` + RoleRef RoleRef `json:"roleRef"` +} + +type Role struct { + BaseResponse `json:"-"` + + *TypeMeta `json:",inline"` + *MetadataContainer `json:",inline"` + *SpecContainer[RoleSpec] `json:",inline"` +} + +type RoleSpec struct { + BaseSpec `json:"-"` + + Statements []PolicyStatement `json:"statements"` } type SubjectRef struct { @@ -223,6 +235,10 @@ type SubjectRef struct { Name string `json:"name"` } +type RoleRef struct { + Name string `json:"name"` +} + type PolicyStatement struct { Actions []string `json:"actions"` Paths []string `json:"paths,omitempty"` diff --git a/pkg/framework/fwservices/cluster_resource_tfdata_sources.go b/pkg/framework/fwservices/cluster_resource_tfdata_sources.go index ecf7b9c..079936a 100644 --- a/pkg/framework/fwservices/cluster_resource_tfdata_sources.go +++ b/pkg/framework/fwservices/cluster_resource_tfdata_sources.go @@ -65,7 +65,7 @@ func (r *ClusterTerraformDataSources[T, P]) Read(ctx context.Context, d *schema. return diag.FromErr(err) } - d.SetId("ssss") + d.SetId("pubg") if diags := r.FilterType.FlattenWithSet(ctx, d, filter); diags.HasError() { return diags @@ -76,10 +76,12 @@ func (r *ClusterTerraformDataSources[T, P]) Read(ctx context.Context, d *schema. metadataAttr := r.MetadataType.Flatten(object.GetMetadata()) specAttr := r.SpecType.Flatten(object.GetSpec()) - itemsAttr = append(itemsAttr, map[string]any{ - "metadata": []any{metadataAttr}, - "spec": []any{specAttr}, - }) + itemAttr := map[string]any{"metadata": []any{metadataAttr}} + if specAttr != nil { + itemAttr["spec"] = []any{specAttr} + } + + itemsAttr = append(itemsAttr, itemAttr) } if err := d.Set("items", itemsAttr); err != nil { diff --git a/pkg/framework/fwservices/namespaced_resource_tfdata_sources.go b/pkg/framework/fwservices/namespaced_resource_tfdata_sources.go index b996840..7aac88f 100644 --- a/pkg/framework/fwservices/namespaced_resource_tfdata_sources.go +++ b/pkg/framework/fwservices/namespaced_resource_tfdata_sources.go @@ -78,10 +78,12 @@ func (r *NamespacedTerraformDataSources[T, P]) Read(ctx context.Context, d *sche metadataAttr := r.MetadataType.Flatten(object.GetMetadata()) specAttr := r.SpecType.Flatten(object.GetSpec()) - itemsAttr = append(itemsAttr, map[string]any{ - "metadata": []any{metadataAttr}, - "spec": []any{specAttr}, - }) + itemAttr := map[string]any{"metadata": []any{metadataAttr}} + if specAttr != nil { + itemAttr["spec"] = []any{specAttr} + } + + itemsAttr = append(itemsAttr, itemAttr) } if err := d.Set("items", itemsAttr); err != nil { diff --git a/pkg/framework/fwtype/rolebinding.go b/pkg/framework/fwtype/rolebinding.go index 0eb3897..2ed2411 100644 --- a/pkg/framework/fwtype/rolebinding.go +++ b/pkg/framework/fwtype/rolebinding.go @@ -31,56 +31,14 @@ func (t RoleBindingType) Schema() *schema.Schema { Computed: t.Computed, }, }, t.Computed, true), - "policy_inline": { - Type: schema.TypeList, - Optional: !t.Computed, - Computed: t.Computed, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "actions": { - Type: schema.TypeSet, - Description: "Actions is a list of actions this role binding grants access to.", - Required: !t.Computed, - Computed: t.Computed, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "paths": { - Type: schema.TypeSet, - Description: "Paths is a list of paths this role binding grants access to.", - Optional: !t.Computed, - Computed: t.Computed, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "resources": { - Type: schema.TypeList, - Description: "Resources is a list of resources this role binding grants access to.", - Optional: !t.Computed, - Computed: t.Computed, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "api_group": { - Type: schema.TypeString, - Description: "APIGroup is the group for the resource being referenced.", - Required: !t.Computed, - Computed: t.Computed, - }, - "kind": { - Type: schema.TypeString, - Description: "Kind is the type of resource being referenced.", - Required: !t.Computed, - Computed: t.Computed, - }, - }, - }, - }, - }, + "role_ref": SingleNestedBlock(map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Description: "Name of the referent.", + Required: !t.Computed, + Computed: t.Computed, }, - }, - "policy_ref": { - Type: schema.TypeString, - Optional: !t.Computed, - Computed: t.Computed, - }, + }, t.Computed, true), } blockSchema := SingleNestedBlock(innerSchema, t.Computed, true) @@ -97,33 +55,9 @@ func (RoleBindingType) Expand(ctx context.Context, d *schema.ResourceData, out * Name: rawSubjectRef[0]["name"].(string), } - rawPolicyInlineList := fwflex.ExpandMapList(attr["policy_inline"].([]any)) - for _, rawPolicyInline := range rawPolicyInlineList { - policyInline := bluechip_models.PolicyStatement{ - Actions: fwflex.ExpandStringSet(rawPolicyInline["actions"].(*schema.Set)), - } - - if rawPolicyInline["paths"] != nil { - policyInline.Paths = fwflex.ExpandStringSet(rawPolicyInline["paths"].(*schema.Set)) - } - - if rawPolicyInline["resources"] != nil { - for _, rawPolicyResource := range fwflex.ExpandMapList(rawPolicyInline["resources"].([]any)) { - policyResource := bluechip_models.PolicyResource{ - ApiGroup: rawPolicyResource["api_group"].(string), - Kind: rawPolicyResource["kind"].(string), - } - policyInline.Resources = append(policyInline.Resources, policyResource) - } - } - - out.PolicyInline = append(out.PolicyInline, policyInline) - } - - if attr["policy_ref"] != nil { - if attr["policy_ref"].(string) != "" { - out.PolicyRef = String(attr["policy_ref"].(string)) - } + rawRoleRef := fwflex.ExpandMapList(attr["role_ref"].([]any)) + out.RoleRef = bluechip_models.RoleRef{ + Name: rawRoleRef[0]["name"].(string), } return nil } @@ -134,31 +68,9 @@ func (RoleBindingType) Flatten(in bluechip_models.RoleBindingSpec) map[string]an "kind": in.SubjectsRef.Kind, "name": in.SubjectsRef.Name, }}, - "policy_inline": []map[string]any{}, - "policy_ref": in.PolicyRef, - } - - for _, policyInline := range in.PolicyInline { - rawPolicyInline := map[string]any{ - "actions": policyInline.Actions, - } - - if len(policyInline.Paths) != 0 { - rawPolicyInline["paths"] = policyInline.Paths - } - - var policyResources []map[string]any - for _, policyResource := range policyInline.Resources { - rawPolicyResource := map[string]any{ - "api_group": policyResource.ApiGroup, - "kind": policyResource.Kind, - } - policyResources = append(policyResources, rawPolicyResource) - } - if len(policyResources) != 0 { - rawPolicyInline["resources"] = policyResources - } - attr["policy_inline"] = append(attr["policy_inline"].([]map[string]any), rawPolicyInline) + "role_ref": []map[string]any{{ + "name": in.RoleRef.Name, + }}, } return attr }