From dad33e478ab7e4c1ed36eb49d14739ac4ce068b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Lapeyre?= Date: Mon, 5 Jul 2021 22:57:20 +0200 Subject: [PATCH 1/2] Generate datasources based on OpenAPI specification This is an experiment to see whether generating the provider based on the OpenAPI specification at https://github.com/hashicorp/boundary/blob/main/internal/gen/controller.swagger.json could work. The schema is converted from the definitions given in the document to to map[string]*schema.Schema, with two special cases: - when there is an object in an object, I convert it to a one element list as terraform-plugin-sdk v2 does not know how to express this, - when there is an opaque attribute (`map[string]interface{}`), I skip it completely as terraform-plugin-sdk does not expose `DynamicPseudoType` that would make it possible to express this attribute in native Terraform, the workaround I use in the Consul provider is to use `schema.TypeString` and `jsonencode()` but it is not ideal. Since I only worked on the datasources here I chose to skip those attributes for now. Once the schema is converted, we create the `ReadContext` function that is needed for the datasource. As it can be a bit tricky to use the Go client for each service, I chose to use directly the global *api.Client and to manually add the query params and get the raw response. While it would not be recommended for an external project to use the client this way, it fits nicely here and keep the code simple. Finally the result is written to the state, looking at the schema we generated previously to convert it. The tests are written manually so the developper can make sure that everything is working as expected even thought the code was generated and not written manually. While the conversion of the schema could be made at runtime and only one `ReadContext` function is actually needed, I find generating the code make it quite easy to review and should make it easier for contributors already accustomed to writing Terraform providers to look for errors or fork the provider for their needs. While I only worked on datasources returning lists of elements for now, I think the same approach could be used to generate datasources returning a single element and ultimately resources. This would make it very easy to keep the Terraform provider in sync with new Boundary versions, especially as the OpenAPI spec is created from the Protobuf files and the CLI is already generated on a similar principle. The code in generate_datasource.go is not very nice, but it does get the job done. I may spin it off in its own project in the future to add more feature to it. Closes https://github.com/hashicorp/terraform-provider-boundary/issues/99 --- docs/data-sources/accounts.md | 56 +++ docs/data-sources/auth_methods.md | 57 +++ docs/data-sources/auth_tokens.md | 58 +++ docs/data-sources/credential_libraries.md | 55 +++ docs/data-sources/credential_stores.md | 56 +++ docs/data-sources/groups.md | 66 ++++ docs/data-sources/host_catalogs.md | 56 +++ docs/data-sources/host_sets.md | 56 +++ docs/data-sources/hosts.md | 56 +++ docs/data-sources/managed_groups.md | 56 +++ docs/data-sources/roles.md | 90 +++++ docs/data-sources/scopes.md | 57 +++ docs/data-sources/sessions.md | 84 ++++ docs/data-sources/targets.md | 84 ++++ docs/data-sources/users.md | 70 ++++ go.mod | 15 + go.sum | 33 ++ internal/provider/data_source.go | 90 +++++ .../provider/data_source_acccounts_test.go | 71 ++++ internal/provider/data_source_accounts.go | 163 ++++++++ internal/provider/data_source_auth_methods.go | 170 +++++++++ .../provider/data_source_auth_methods_test.go | 69 ++++ internal/provider/data_source_auth_tokens.go | 175 +++++++++ .../provider/data_source_auth_tokens_test.go | 35 ++ .../data_source_credential_libraries.go | 156 ++++++++ .../data_source_credential_libraries_test.go | 78 ++++ .../provider/data_source_credential_stores.go | 165 ++++++++ .../data_source_credential_stores_test.go | 79 ++++ internal/provider/data_source_groups.go | 187 +++++++++ internal/provider/data_source_groups_test.go | 71 ++++ .../provider/data_source_host_catalogs.go | 165 ++++++++ .../data_source_host_catalogs_test.go | 67 ++++ internal/provider/data_source_host_sets.go | 164 ++++++++ .../provider/data_source_host_sets_test.go | 71 ++++ internal/provider/data_source_hosts.go | 164 ++++++++ internal/provider/data_source_hosts_test.go | 68 ++++ .../provider/data_source_managed_groups.go | 164 ++++++++ .../data_source_managed_groups_test.go | 53 +++ internal/provider/data_source_roles.go | 250 ++++++++++++ internal/provider/data_source_roles_test.go | 78 ++++ internal/provider/data_source_scopes.go | 169 +++++++++ internal/provider/data_source_scopes_test.go | 57 +++ internal/provider/data_source_sessions.go | 243 ++++++++++++ .../provider/data_source_sessions_test.go | 34 ++ internal/provider/data_source_targets.go | 249 ++++++++++++ internal/provider/data_source_targets_test.go | 92 +++++ internal/provider/data_source_users.go | 203 ++++++++++ internal/provider/data_source_users_test.go | 76 ++++ internal/provider/provider.go | 17 + scripts/generate_datasource.go | 359 ++++++++++++++++++ 50 files changed, 5257 insertions(+) create mode 100644 docs/data-sources/accounts.md create mode 100644 docs/data-sources/auth_methods.md create mode 100644 docs/data-sources/auth_tokens.md create mode 100644 docs/data-sources/credential_libraries.md create mode 100644 docs/data-sources/credential_stores.md create mode 100644 docs/data-sources/groups.md create mode 100644 docs/data-sources/host_catalogs.md create mode 100644 docs/data-sources/host_sets.md create mode 100644 docs/data-sources/hosts.md create mode 100644 docs/data-sources/managed_groups.md create mode 100644 docs/data-sources/roles.md create mode 100644 docs/data-sources/scopes.md create mode 100644 docs/data-sources/sessions.md create mode 100644 docs/data-sources/targets.md create mode 100644 docs/data-sources/users.md create mode 100644 internal/provider/data_source.go create mode 100644 internal/provider/data_source_acccounts_test.go create mode 100644 internal/provider/data_source_accounts.go create mode 100644 internal/provider/data_source_auth_methods.go create mode 100644 internal/provider/data_source_auth_methods_test.go create mode 100644 internal/provider/data_source_auth_tokens.go create mode 100644 internal/provider/data_source_auth_tokens_test.go create mode 100644 internal/provider/data_source_credential_libraries.go create mode 100644 internal/provider/data_source_credential_libraries_test.go create mode 100644 internal/provider/data_source_credential_stores.go create mode 100644 internal/provider/data_source_credential_stores_test.go create mode 100644 internal/provider/data_source_groups.go create mode 100644 internal/provider/data_source_groups_test.go create mode 100644 internal/provider/data_source_host_catalogs.go create mode 100644 internal/provider/data_source_host_catalogs_test.go create mode 100644 internal/provider/data_source_host_sets.go create mode 100644 internal/provider/data_source_host_sets_test.go create mode 100644 internal/provider/data_source_hosts.go create mode 100644 internal/provider/data_source_hosts_test.go create mode 100644 internal/provider/data_source_managed_groups.go create mode 100644 internal/provider/data_source_managed_groups_test.go create mode 100644 internal/provider/data_source_roles.go create mode 100644 internal/provider/data_source_roles_test.go create mode 100644 internal/provider/data_source_scopes.go create mode 100644 internal/provider/data_source_scopes_test.go create mode 100644 internal/provider/data_source_sessions.go create mode 100644 internal/provider/data_source_sessions_test.go create mode 100644 internal/provider/data_source_targets.go create mode 100644 internal/provider/data_source_targets_test.go create mode 100644 internal/provider/data_source_users.go create mode 100644 internal/provider/data_source_users_test.go create mode 100644 scripts/generate_datasource.go diff --git a/docs/data-sources/accounts.md b/docs/data-sources/accounts.md new file mode 100644 index 00000000..c1225b67 --- /dev/null +++ b/docs/data-sources/accounts.md @@ -0,0 +1,56 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_accounts Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + Lists all Accounts in a specific Auth Method. +--- + +# boundary_accounts (Data Source) + +Lists all Accounts in a specific Auth Method. + + + + +## Schema + +### Optional + +- **auth_method_id** (String) +- **filter** (String) +- **id** (String) The ID of this resource. + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **auth_method_id** (String) +- **authorized_actions** (List of String) +- **created_time** (String) +- **description** (String) +- **id** (String) +- **managed_group_ids** (List of String) +- **name** (String) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **type** (String) +- **updated_time** (String) +- **version** (Number) + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + diff --git a/docs/data-sources/auth_methods.md b/docs/data-sources/auth_methods.md new file mode 100644 index 00000000..5340b6a0 --- /dev/null +++ b/docs/data-sources/auth_methods.md @@ -0,0 +1,57 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_auth_methods Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + Lists all Auth Methods. +--- + +# boundary_auth_methods (Data Source) + +Lists all Auth Methods. + + + + +## Schema + +### Optional + +- **filter** (String) +- **id** (String) The ID of this resource. +- **recursive** (Boolean) +- **scope_id** (String) + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **authorized_actions** (List of String) +- **created_time** (String) +- **description** (String) +- **id** (String) +- **is_primary** (Boolean) +- **name** (String) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **scope_id** (String) +- **type** (String) +- **updated_time** (String) +- **version** (Number) + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + diff --git a/docs/data-sources/auth_tokens.md b/docs/data-sources/auth_tokens.md new file mode 100644 index 00000000..cbc8644a --- /dev/null +++ b/docs/data-sources/auth_tokens.md @@ -0,0 +1,58 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_auth_tokens Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + Lists all Auth Tokens. +--- + +# boundary_auth_tokens (Data Source) + +Lists all Auth Tokens. + + + + +## Schema + +### Optional + +- **filter** (String) +- **id** (String) The ID of this resource. +- **recursive** (Boolean) +- **scope_id** (String) + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **account_id** (String) +- **approximate_last_used_time** (String) +- **auth_method_id** (String) +- **authorized_actions** (List of String) +- **created_time** (String) +- **expiration_time** (String) +- **id** (String) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **scope_id** (String) +- **token** (String) +- **updated_time** (String) +- **user_id** (String) + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + diff --git a/docs/data-sources/credential_libraries.md b/docs/data-sources/credential_libraries.md new file mode 100644 index 00000000..e1a05ffc --- /dev/null +++ b/docs/data-sources/credential_libraries.md @@ -0,0 +1,55 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_credential_libraries Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + Lists all Credential Library. +--- + +# boundary_credential_libraries (Data Source) + +Lists all Credential Library. + + + + +## Schema + +### Optional + +- **credential_store_id** (String) +- **filter** (String) +- **id** (String) The ID of this resource. + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **authorized_actions** (List of String) +- **created_time** (String) +- **credential_store_id** (String) +- **description** (String) +- **id** (String) +- **name** (String) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **type** (String) +- **updated_time** (String) +- **version** (Number) + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + diff --git a/docs/data-sources/credential_stores.md b/docs/data-sources/credential_stores.md new file mode 100644 index 00000000..e27dc93c --- /dev/null +++ b/docs/data-sources/credential_stores.md @@ -0,0 +1,56 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_credential_stores Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + Lists all Credential Stores. +--- + +# boundary_credential_stores (Data Source) + +Lists all Credential Stores. + + + + +## Schema + +### Optional + +- **filter** (String) +- **id** (String) The ID of this resource. +- **recursive** (Boolean) +- **scope_id** (String) + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **authorized_actions** (List of String) +- **created_time** (String) +- **description** (String) +- **id** (String) +- **name** (String) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **scope_id** (String) +- **type** (String) +- **updated_time** (String) +- **version** (Number) + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + diff --git a/docs/data-sources/groups.md b/docs/data-sources/groups.md new file mode 100644 index 00000000..930a9546 --- /dev/null +++ b/docs/data-sources/groups.md @@ -0,0 +1,66 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_groups Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + Lists all Groups. +--- + +# boundary_groups (Data Source) + +Lists all Groups. + + + + +## Schema + +### Optional + +- **filter** (String) +- **id** (String) The ID of this resource. +- **recursive** (Boolean) +- **scope_id** (String) + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **authorized_actions** (List of String) +- **created_time** (String) +- **description** (String) +- **id** (String) +- **member_ids** (List of String) +- **members** (List of Object) (see [below for nested schema](#nestedobjatt--items--members)) +- **name** (String) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **scope_id** (String) +- **updated_time** (String) +- **version** (Number) + + +### Nested Schema for `items.members` + +Read-Only: + +- **id** (String) +- **scope_id** (String) + + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + diff --git a/docs/data-sources/host_catalogs.md b/docs/data-sources/host_catalogs.md new file mode 100644 index 00000000..858f2164 --- /dev/null +++ b/docs/data-sources/host_catalogs.md @@ -0,0 +1,56 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_host_catalogs Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + Gets a list of Host Catalogs. +--- + +# boundary_host_catalogs (Data Source) + +Gets a list of Host Catalogs. + + + + +## Schema + +### Optional + +- **filter** (String) +- **id** (String) The ID of this resource. +- **recursive** (Boolean) +- **scope_id** (String) + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **authorized_actions** (List of String) +- **created_time** (String) +- **description** (String) +- **id** (String) +- **name** (String) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **scope_id** (String) +- **type** (String) +- **updated_time** (String) +- **version** (Number) + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + diff --git a/docs/data-sources/host_sets.md b/docs/data-sources/host_sets.md new file mode 100644 index 00000000..3fdb1db7 --- /dev/null +++ b/docs/data-sources/host_sets.md @@ -0,0 +1,56 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_host_sets Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + List all Host Sets under the specific Catalog. +--- + +# boundary_host_sets (Data Source) + +List all Host Sets under the specific Catalog. + + + + +## Schema + +### Optional + +- **filter** (String) +- **host_catalog_id** (String) +- **id** (String) The ID of this resource. + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **authorized_actions** (List of String) +- **created_time** (String) +- **description** (String) +- **host_catalog_id** (String) +- **host_ids** (List of String) +- **id** (String) +- **name** (String) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **type** (String) +- **updated_time** (String) +- **version** (Number) + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + diff --git a/docs/data-sources/hosts.md b/docs/data-sources/hosts.md new file mode 100644 index 00000000..91aa9773 --- /dev/null +++ b/docs/data-sources/hosts.md @@ -0,0 +1,56 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_hosts Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + List all Hosts for the specified Catalog. +--- + +# boundary_hosts (Data Source) + +List all Hosts for the specified Catalog. + + + + +## Schema + +### Optional + +- **filter** (String) +- **host_catalog_id** (String) +- **id** (String) The ID of this resource. + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **authorized_actions** (List of String) +- **created_time** (String) +- **description** (String) +- **host_catalog_id** (String) +- **host_set_ids** (List of String) +- **id** (String) +- **name** (String) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **type** (String) +- **updated_time** (String) +- **version** (Number) + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + diff --git a/docs/data-sources/managed_groups.md b/docs/data-sources/managed_groups.md new file mode 100644 index 00000000..83394944 --- /dev/null +++ b/docs/data-sources/managed_groups.md @@ -0,0 +1,56 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_managed_groups Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + Lists all ManagedGroups in a specific Auth Method. +--- + +# boundary_managed_groups (Data Source) + +Lists all ManagedGroups in a specific Auth Method. + + + + +## Schema + +### Optional + +- **auth_method_id** (String) +- **filter** (String) +- **id** (String) The ID of this resource. + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **auth_method_id** (String) +- **authorized_actions** (List of String) +- **created_time** (String) +- **description** (String) +- **id** (String) +- **member_ids** (List of String) +- **name** (String) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **type** (String) +- **updated_time** (String) +- **version** (Number) + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + diff --git a/docs/data-sources/roles.md b/docs/data-sources/roles.md new file mode 100644 index 00000000..f0417e9d --- /dev/null +++ b/docs/data-sources/roles.md @@ -0,0 +1,90 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_roles Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + Lists all Roles. +--- + +# boundary_roles (Data Source) + +Lists all Roles. + + + + +## Schema + +### Optional + +- **filter** (String) +- **id** (String) The ID of this resource. +- **recursive** (Boolean) +- **scope_id** (String) + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **authorized_actions** (List of String) +- **created_time** (String) +- **description** (String) +- **grant_scope_id** (String) +- **grant_strings** (List of String) +- **grants** (List of Object) (see [below for nested schema](#nestedobjatt--items--grants)) +- **id** (String) +- **name** (String) +- **principal_ids** (List of String) +- **principals** (List of Object) (see [below for nested schema](#nestedobjatt--items--principals)) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **scope_id** (String) +- **updated_time** (String) +- **version** (Number) + + +### Nested Schema for `items.grants` + +Read-Only: + +- **canonical** (String) +- **json** (List of Object) (see [below for nested schema](#nestedobjatt--items--grants--json)) +- **raw** (String) + + +### Nested Schema for `items.grants.json` + +Read-Only: + +- **actions** (List of String) +- **id** (String) +- **type** (String) + + + + +### Nested Schema for `items.principals` + +Read-Only: + +- **id** (String) +- **scope_id** (String) +- **type** (String) + + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + diff --git a/docs/data-sources/scopes.md b/docs/data-sources/scopes.md new file mode 100644 index 00000000..87ed32e8 --- /dev/null +++ b/docs/data-sources/scopes.md @@ -0,0 +1,57 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_scopes Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + Lists all Scopes within the Scope provided in the request. +--- + +# boundary_scopes (Data Source) + +Lists all Scopes within the Scope provided in the request. + + + + +## Schema + +### Optional + +- **filter** (String) +- **id** (String) The ID of this resource. +- **recursive** (Boolean) +- **scope_id** (String) + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **authorized_actions** (List of String) +- **created_time** (String) +- **description** (String) +- **id** (String) +- **name** (String) +- **primary_auth_method_id** (String) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **scope_id** (String) +- **type** (String) +- **updated_time** (String) +- **version** (Number) + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + diff --git a/docs/data-sources/sessions.md b/docs/data-sources/sessions.md new file mode 100644 index 00000000..645f0556 --- /dev/null +++ b/docs/data-sources/sessions.md @@ -0,0 +1,84 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_sessions Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + Lists all Sessions. +--- + +# boundary_sessions (Data Source) + +Lists all Sessions. + + + + +## Schema + +### Optional + +- **filter** (String) +- **id** (String) The ID of this resource. +- **recursive** (Boolean) +- **scope_id** (String) + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **auth_token_id** (String) +- **authorized_actions** (List of String) +- **certificate** (String) +- **created_time** (String) +- **endpoint** (String) +- **expiration_time** (String) +- **host_id** (String) +- **host_set_id** (String) +- **id** (String) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **scope_id** (String) +- **states** (List of Object) (see [below for nested schema](#nestedobjatt--items--states)) +- **status** (String) +- **target_id** (String) +- **termination_reason** (String) +- **type** (String) +- **updated_time** (String) +- **user_id** (String) +- **version** (Number) +- **worker_info** (List of Object) (see [below for nested schema](#nestedobjatt--items--worker_info)) + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + + +### Nested Schema for `items.states` + +Read-Only: + +- **end_time** (String) +- **start_time** (String) +- **status** (String) + + + +### Nested Schema for `items.worker_info` + +Read-Only: + +- **address** (String) + + diff --git a/docs/data-sources/targets.md b/docs/data-sources/targets.md new file mode 100644 index 00000000..bc165fcc --- /dev/null +++ b/docs/data-sources/targets.md @@ -0,0 +1,84 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_targets Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + Lists all Targets. +--- + +# boundary_targets (Data Source) + +Lists all Targets. + + + + +## Schema + +### Optional + +- **filter** (String) +- **id** (String) The ID of this resource. +- **recursive** (Boolean) +- **scope_id** (String) + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **application_credential_libraries** (List of Object) (see [below for nested schema](#nestedobjatt--items--application_credential_libraries)) +- **application_credential_library_ids** (List of String) +- **authorized_actions** (List of String) +- **created_time** (String) +- **description** (String) +- **host_set_ids** (List of String) +- **host_sets** (List of Object) (see [below for nested schema](#nestedobjatt--items--host_sets)) +- **id** (String) +- **name** (String) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **scope_id** (String) +- **session_connection_limit** (Number) +- **session_max_seconds** (Number) +- **type** (String) +- **updated_time** (String) +- **version** (Number) +- **worker_filter** (String) + + +### Nested Schema for `items.application_credential_libraries` + +Read-Only: + +- **credential_store_id** (String) +- **description** (String) +- **id** (String) +- **name** (String) +- **type** (String) + + + +### Nested Schema for `items.host_sets` + +Read-Only: + +- **host_catalog_id** (String) +- **id** (String) + + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + diff --git a/docs/data-sources/users.md b/docs/data-sources/users.md new file mode 100644 index 00000000..8a974f06 --- /dev/null +++ b/docs/data-sources/users.md @@ -0,0 +1,70 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "boundary_users Data Source - terraform-provider-boundary" +subcategory: "" +description: |- + Lists all Users. +--- + +# boundary_users (Data Source) + +Lists all Users. + + + + +## Schema + +### Optional + +- **filter** (String) +- **id** (String) The ID of this resource. +- **recursive** (Boolean) +- **scope_id** (String) + +### Read-Only + +- **items** (List of Object) (see [below for nested schema](#nestedatt--items)) + + +### Nested Schema for `items` + +Read-Only: + +- **account_ids** (List of String) +- **accounts** (List of Object) (see [below for nested schema](#nestedobjatt--items--accounts)) +- **authorized_actions** (List of String) +- **created_time** (String) +- **description** (String) +- **email** (String) +- **full_name** (String) +- **id** (String) +- **login_name** (String) +- **name** (String) +- **primary_account_id** (String) +- **scope** (List of Object) (see [below for nested schema](#nestedobjatt--items--scope)) +- **scope_id** (String) +- **updated_time** (String) +- **version** (Number) + + +### Nested Schema for `items.accounts` + +Read-Only: + +- **id** (String) +- **scope_id** (String) + + + +### Nested Schema for `items.scope` + +Read-Only: + +- **description** (String) +- **id** (String) +- **name** (String) +- **parent_scope_id** (String) +- **type** (String) + + diff --git a/go.mod b/go.mod index 5902d0af..fd8eb062 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,8 @@ go 1.22.2 require ( github.com/YakDriver/regexache v0.23.0 + github.com/go-openapi/loads v0.22.0 + github.com/go-openapi/spec v0.21.0 github.com/hashicorp/boundary v0.16.0 github.com/hashicorp/boundary/api v0.0.49 github.com/hashicorp/boundary/sdk v0.0.46 @@ -17,8 +19,10 @@ require ( github.com/hashicorp/terraform-plugin-docs v0.18.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 github.com/jimlambrt/gldap v0.1.11 + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/kr/pretty v0.3.1 github.com/mitchellh/go-homedir v1.1.0 + github.com/sanity-io/litter v1.5.5 github.com/stretchr/testify v1.9.0 golang.org/x/crypto v0.21.0 mvdan.cc/gofumpt v0.6.0 @@ -41,6 +45,7 @@ require ( github.com/alessio/shellescape v1.4.2 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/armon/go-radix v1.0.0 // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect @@ -65,6 +70,12 @@ require ( github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect github.com/go-jose/go-jose/v3 v3.0.3 // indirect github.com/go-ldap/ldap/v3 v3.4.6 // indirect + github.com/go-openapi/analysis v0.23.0 // indirect + github.com/go-openapi/errors v0.22.0 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/strfmt v0.23.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-migrate/migrate/v4 v4.17.0 // indirect @@ -134,8 +145,10 @@ require ( github.com/jinzhu/gorm v1.9.16 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/kr/text v0.2.0 // indirect github.com/lib/pq v1.10.9 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect @@ -155,6 +168,7 @@ require ( github.com/mtibben/percent v0.2.1 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect github.com/oklog/run v1.1.0 // indirect + github.com/oklog/ulid v1.3.1 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc6 // indirect github.com/opencontainers/runc v1.2.0-rc.1 // indirect @@ -186,6 +200,7 @@ require ( github.com/yuin/goldmark-meta v1.1.0 // indirect github.com/zalando/go-keyring v0.2.3 // indirect github.com/zclconf/go-cty v1.14.2 // indirect + go.mongodb.org/mongo-driver v1.14.0 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 // indirect golang.org/x/mod v0.15.0 // indirect diff --git a/go.sum b/go.sum index 6d14b77f..0fe1d632 100644 --- a/go.sum +++ b/go.sum @@ -43,6 +43,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmms github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -79,6 +81,7 @@ github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53E github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/danieljoos/wincred v1.2.1 h1:dl9cBrupW8+r5250DYkYxocLeZ1Y4vB1kxgtjxw8GQs= github.com/danieljoos/wincred v1.2.1/go.mod h1:uGaFL9fDn3OLTvzCGulzE+SzjEe5NGlh5FdCcyfPwps= +github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -141,6 +144,22 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU= +github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= +github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= +github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco= +github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs= +github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= +github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= +github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c= +github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -387,6 +406,10 @@ github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkr github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -412,6 +435,8 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -472,6 +497,8 @@ github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJm github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc6 h1:XDqvyKsJEbRtATzkgItUqBA7QHk58yxX1Ov9HERHNqU= @@ -489,6 +516,7 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsK github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -518,6 +546,8 @@ github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3V github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= +github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= @@ -542,6 +572,7 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -583,6 +614,8 @@ github.com/zalando/go-keyring v0.2.3/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51D github.com/zclconf/go-cty v1.14.2 h1:kTG7lqmBou0Zkx35r6HJHUQTvaRPr5bIAf3AoHS0izI= github.com/zclconf/go-cty v1.14.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= +go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0 h1:doUP+ExOpH3spVTLS0FcWGLnQrPct/hD/bCPbDRUEAU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0/go.mod h1:rdENBZMT2OE6Ne/KLwpiXudnAsbdrdBaqBvTN8M8BgA= go.opentelemetry.io/otel v1.23.1 h1:Za4UzOqJYS+MUczKI320AtqZHZb7EqxO00jAHE0jmQY= diff --git a/internal/provider/data_source.go b/internal/provider/data_source.go new file mode 100644 index 00000000..c832ad54 --- /dev/null +++ b/internal/provider/data_source.go @@ -0,0 +1,90 @@ +package provider + +import ( + "fmt" + "strings" + + "github.com/hashicorp/boundary/api" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func apiErr(err *api.Error) diag.Diagnostics { + detail := err.Message + if err.Details != nil { + var details []string + for _, field := range err.Details.RequestFields { + details = append(details, fmt.Sprintf("%s: %s", field.Name, field.Description)) + } + detail = strings.Join(details, "\n") + } + + return diag.Diagnostics{ + { + Severity: diag.Error, + Summary: "An error occured while querying the API", + Detail: detail, + }, + } +} + +func set(schema map[string]*schema.Schema, d *schema.ResourceData, val map[string]interface{}) error { + for k, v := range val { + sch := schema[k] + if sch == nil { + continue + } + v = convert(sch, v) + if err := d.Set(k, v); err != nil { + return fmt.Errorf("failed to set '%s': %w", k, err) + } + } + + return nil +} + +func convertResource(sch *schema.Resource, val map[string]interface{}) map[string]interface{} { + res := map[string]interface{}{} + for k, s := range sch.Schema { + res[k] = convert(s, val[k]) + } + return res +} + +func convert(sch *schema.Schema, val interface{}) interface{} { + switch ty := sch.Type; ty { + case schema.TypeBool, schema.TypeInt, schema.TypeFloat, schema.TypeString: + return val + case schema.TypeList: + switch val := val.(type) { + case nil: + return []interface{}{} + case []interface{}: + res := []interface{}{} + for _, v := range val { + if s, ok := sch.Elem.(*schema.Schema); ok { + res = append(res, convert(s, v)) + } else { + res = append(res, convertResource(sch.Elem.(*schema.Resource), v.(map[string]interface{}))) + } + } + return res + case map[string]interface{}: + // terraform-plugin-sdk does not know how to have an object in an + // object so we use a list with one element + if s, ok := sch.Elem.(*schema.Schema); ok { + return []interface{}{ + convert(s, val), + } + } else { + return []interface{}{ + convertResource(sch.Elem.(*schema.Resource), val), + } + } + default: + panic(fmt.Sprintf("unknown list type %T", val)) + } + default: + panic(fmt.Sprintf("unknown type %s", ty)) + } +} diff --git a/internal/provider/data_source_acccounts_test.go b/internal/provider/data_source_acccounts_test.go new file mode 100644 index 00000000..92629cba --- /dev/null +++ b/internal/provider/data_source_acccounts_test.go @@ -0,0 +1,71 @@ +package provider + +import ( + "regexp" + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooAccountDataMissingAuthMethodId = ` +data "boundary_accounts" "foo" {} +` + + fooAccountData = ` +data "boundary_accounts" "foo" { + auth_method_id = boundary_account.foo.auth_method_id +} +` +) + +func TestAccDataSourceAccounts(t *testing.T) { + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + url := tc.ApiAddrs()[0] + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories(&provider), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooAccountDataMissingAuthMethodId), + ExpectError: regexp.MustCompile("auth_method_id: Invalid formatted identifier."), + }, + { + Config: testConfig(url, fooOrg, fooAccount, fooAccountData), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("data.boundary_accounts.foo", "auth_method_id"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.#", "1"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.%", "11"), + resource.TestCheckResourceAttrSet("data.boundary_accounts.foo", "items.0.auth_method_id"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.authorized_actions.#", "6"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.authorized_actions.0", "no-op"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.authorized_actions.1", "read"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.authorized_actions.2", "update"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.authorized_actions.3", "delete"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.authorized_actions.4", "set-password"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.authorized_actions.5", "change-password"), + resource.TestCheckResourceAttrSet("data.boundary_accounts.foo", "items.0.created_time"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.description", "test account"), + resource.TestCheckResourceAttrSet("data.boundary_accounts.foo", "items.0.id"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.managed_group_ids.#", "0"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.name", "test"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.scope.#", "1"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.scope.0.%", "5"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.scope.0.description", ""), + resource.TestCheckResourceAttrSet("data.boundary_accounts.foo", "items.0.scope.0.id"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.scope.0.name", "org1"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.scope.0.parent_scope_id", "global"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.scope.0.type", "org"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.type", "password"), + resource.TestCheckResourceAttrSet("data.boundary_accounts.foo", "items.0.updated_time"), + resource.TestCheckResourceAttr("data.boundary_accounts.foo", "items.0.version", "1"), + ), + }, + }, + }) +} diff --git a/internal/provider/data_source_accounts.go b/internal/provider/data_source_accounts.go new file mode 100644 index 00000000..e91d6be9 --- /dev/null +++ b/internal/provider/data_source_accounts.go @@ -0,0 +1,163 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name Accounts -path accounts + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceAccountsSchema = map[string]*schema.Schema{ + "auth_method_id": { + Type: schema.TypeString, + Optional: true, + }, + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "auth_method_id": { + Type: schema.TypeString, + Description: "The ID of the Auth Method that is associated with this Account.", + Computed: true, + }, + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Optional user-set description for identification purposes.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Account.", + Computed: true, + }, + "managed_group_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "name": { + Type: schema.TypeString, + Description: "Optional name for identification purposes.", + Computed: true, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "type": { + Type: schema.TypeString, + Description: "The type of this Account.", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Description: "Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version.", + Computed: true, + }, + }, + }, + }, +} + +func dataSourceAccounts() *schema.Resource { + return &schema.Resource{ + Description: "Lists all Accounts in a specific Auth Method.", + Schema: dataSourceAccountsSchema, + ReadContext: dataSourceAccountsRead, + } +} + +func dataSourceAccountsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "accounts", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("auth_method_id", d.Get("auth_method_id").(string)) + q.Add("filter", d.Get("filter").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceAccountsSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-accounts") + + return nil +} diff --git a/internal/provider/data_source_auth_methods.go b/internal/provider/data_source_auth_methods.go new file mode 100644 index 00000000..a8d5888f --- /dev/null +++ b/internal/provider/data_source_auth_methods.go @@ -0,0 +1,170 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name AuthMethods -path auth-methods + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceAuthMethodsSchema = map[string]*schema.Schema{ + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Optional user-set description for identification purposes.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Auth Method.", + Computed: true, + }, + "is_primary": { + Type: schema.TypeBool, + Description: "Output only. Whether this auth method is the primary auth method for it's scope.\nTo change this value update the primary_auth_method_id field on the scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Optional name for identification purposes.", + Computed: true, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "scope_id": { + Type: schema.TypeString, + Description: "The ID of the Scope of which this Auth Method is a part.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "The Auth Method type.", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Description: "Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version.", + Computed: true, + }, + }, + }, + }, + "recursive": { + Type: schema.TypeBool, + Optional: true, + }, + "scope_id": { + Type: schema.TypeString, + Optional: true, + }, +} + +func dataSourceAuthMethods() *schema.Resource { + return &schema.Resource{ + Description: "Lists all Auth Methods.", + Schema: dataSourceAuthMethodsSchema, + ReadContext: dataSourceAuthMethodsRead, + } +} + +func dataSourceAuthMethodsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "auth-methods", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("filter", d.Get("filter").(string)) + recursive := d.Get("recursive").(bool) + if recursive { + q.Add("recursive", strconv.FormatBool(recursive)) + } + q.Add("scope_id", d.Get("scope_id").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceAuthMethodsSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-auth-methods") + + return nil +} diff --git a/internal/provider/data_source_auth_methods_test.go b/internal/provider/data_source_auth_methods_test.go new file mode 100644 index 00000000..579dddf9 --- /dev/null +++ b/internal/provider/data_source_auth_methods_test.go @@ -0,0 +1,69 @@ +package provider + +import ( + "regexp" + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooAuthMethodsDataMissingScope = ` +data "boundary_auth_methods" "foo" {} +` + fooAuthMethodsData = ` +data "boundary_auth_methods" "foo" { + scope_id = boundary_auth_method.foo.scope_id +} +` +) + +func TestAccDataSourceAuthMethods(t *testing.T) { + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + url := tc.ApiAddrs()[0] + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories((&provider)), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooAuthMethodsDataMissingScope), + ExpectError: regexp.MustCompile("scope_id: This field must be 'global' or a valid org scope id."), + }, + { + Config: testConfig(url, fooOrg, fooBaseAuthMethod, fooAuthMethodsData), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.#", "1"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.%", "11"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.authorized_actions.#", "5"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.authorized_actions.0", "no-op"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.authorized_actions.1", "read"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.authorized_actions.2", "update"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.authorized_actions.3", "delete"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.authorized_actions.4", "authenticate"), + resource.TestCheckResourceAttrSet("data.boundary_auth_methods.foo", "items.0.created_time"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.description", "test auth method"), + resource.TestCheckResourceAttrSet("data.boundary_auth_methods.foo", "items.0.id"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.is_primary", "false"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.name", "test"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.scope.#", "1"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.scope.0.%", "5"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.scope.0.description", ""), + resource.TestCheckResourceAttrSet("data.boundary_auth_methods.foo", "items.0.scope.0.id"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.scope.0.name", "org1"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.scope.0.parent_scope_id", "global"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.scope.0.type", "org"), + resource.TestCheckResourceAttrSet("data.boundary_auth_methods.foo", "items.0.scope_id"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.type", "password"), + resource.TestCheckResourceAttrSet("data.boundary_auth_methods.foo", "items.0.updated_time"), + resource.TestCheckResourceAttr("data.boundary_auth_methods.foo", "items.0.version", "1"), + resource.TestCheckResourceAttrSet("data.boundary_auth_methods.foo", "scope_id"), + ), + }, + }, + }) +} diff --git a/internal/provider/data_source_auth_tokens.go b/internal/provider/data_source_auth_tokens.go new file mode 100644 index 00000000..accd1e0d --- /dev/null +++ b/internal/provider/data_source_auth_tokens.go @@ -0,0 +1,175 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name AuthTokens -path auth-tokens + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceAuthTokensSchema = map[string]*schema.Schema{ + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Account associated with this Auth Token.", + Computed: true, + }, + "approximate_last_used_time": { + Type: schema.TypeString, + Description: "Output only. The approximate time this Auth Token was last used.", + Computed: true, + }, + "auth_method_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Auth Method associated with this Auth Token.", + Computed: true, + }, + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "expiration_time": { + Type: schema.TypeString, + Description: "Output only. The time this Auth Token expires.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Auth Token.", + Computed: true, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "scope_id": { + Type: schema.TypeString, + Description: "The Scope in which this Auth Token was generated.", + Computed: true, + }, + "token": { + Type: schema.TypeString, + Description: "Output only. The token value, which will only be populated after authentication and is only ever visible to the end user whose login request resulted in this Auth Token being created.", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "user_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the User associated with this Auth Token.", + Computed: true, + }, + }, + }, + }, + "recursive": { + Type: schema.TypeBool, + Optional: true, + }, + "scope_id": { + Type: schema.TypeString, + Optional: true, + }, +} + +func dataSourceAuthTokens() *schema.Resource { + return &schema.Resource{ + Description: "Lists all Auth Tokens.", + Schema: dataSourceAuthTokensSchema, + ReadContext: dataSourceAuthTokensRead, + } +} + +func dataSourceAuthTokensRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "auth-tokens", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("filter", d.Get("filter").(string)) + recursive := d.Get("recursive").(bool) + if recursive { + q.Add("recursive", strconv.FormatBool(recursive)) + } + q.Add("scope_id", d.Get("scope_id").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceAuthTokensSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-auth-tokens") + + return nil +} diff --git a/internal/provider/data_source_auth_tokens_test.go b/internal/provider/data_source_auth_tokens_test.go new file mode 100644 index 00000000..44bc5a93 --- /dev/null +++ b/internal/provider/data_source_auth_tokens_test.go @@ -0,0 +1,35 @@ +package provider + +import ( + "regexp" + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooAuthTokensData = ` +data "boundary_auth_tokens" "foo" {} +` +) + +func TestAccDataAuthTokens(t *testing.T) { + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + + url := tc.ApiAddrs()[0] + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories(&provider), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooAuthTokensData), + ExpectError: regexp.MustCompile("scope_id: This field must be 'global' or a valid org scope id."), + }, + }, + }) +} diff --git a/internal/provider/data_source_credential_libraries.go b/internal/provider/data_source_credential_libraries.go new file mode 100644 index 00000000..23389c64 --- /dev/null +++ b/internal/provider/data_source_credential_libraries.go @@ -0,0 +1,156 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name CredentialLibraries -path credential-libraries + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceCredentialLibrariesSchema = map[string]*schema.Schema{ + "credential_store_id": { + Type: schema.TypeString, + Optional: true, + }, + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "credential_store_id": { + Type: schema.TypeString, + Description: "The ID of the Credential Store of which this Credential Library is a part.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Optional user-set description for identification purposes.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Credential Library.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Optional name for identification purposes.", + Computed: true, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "type": { + Type: schema.TypeString, + Description: "The Credential Library type.", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Description: "Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version.", + Computed: true, + }, + }, + }, + }, +} + +func dataSourceCredentialLibraries() *schema.Resource { + return &schema.Resource{ + Description: "Lists all Credential Library.", + Schema: dataSourceCredentialLibrariesSchema, + ReadContext: dataSourceCredentialLibrariesRead, + } +} + +func dataSourceCredentialLibrariesRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "credential-libraries", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("credential_store_id", d.Get("credential_store_id").(string)) + q.Add("filter", d.Get("filter").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceCredentialLibrariesSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-credential-libraries") + + return nil +} diff --git a/internal/provider/data_source_credential_libraries_test.go b/internal/provider/data_source_credential_libraries_test.go new file mode 100644 index 00000000..609b31c8 --- /dev/null +++ b/internal/provider/data_source_credential_libraries_test.go @@ -0,0 +1,78 @@ +package provider + +import ( + "regexp" + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/boundary/testing/vault" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooCredentialLibrariesDataMissingCredentialStoreId = ` +data "boundary_credential_libraries" "foo" {} +` + fooCredentialLibrariesData = ` +data "boundary_credential_libraries" "foo" { + credential_store_id = boundary_credential_library_vault.example.credential_store_id +} +` +) + +func TestAccDataSourceCredentialLibraries(t *testing.T) { + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + url := tc.ApiAddrs()[0] + + vc := vault.NewTestVaultServer(t) + _, token := vc.CreateToken(t) + credStoreRes := vaultCredStoreResource(vc, + vaultCredStoreName, + vaultCredStoreDesc, + vaultCredStoreNamespace, + "www.original.com", + token, + true) + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories(&provider), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooCredentialLibrariesDataMissingCredentialStoreId), + ExpectError: regexp.MustCompile("credential_store_id: This field must be a valid credential store id."), + }, + { + Config: testConfig(url, fooOrg, firstProjectFoo, credStoreRes, vaultCredLibResource, fooCredentialLibrariesData), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("data.boundary_credential_libraries.foo", "credential_store_id"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.#", "1"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.%", "10"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.authorized_actions.#", "4"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.authorized_actions.0", "no-op"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.authorized_actions.1", "read"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.authorized_actions.2", "update"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.authorized_actions.3", "delete"), + resource.TestCheckResourceAttrSet("data.boundary_credential_libraries.foo", "items.0.created_time"), + resource.TestCheckResourceAttrSet("data.boundary_credential_libraries.foo", "items.0.credential_store_id"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.description", "the foo"), + resource.TestCheckResourceAttrSet("data.boundary_credential_libraries.foo", "items.0.id"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.name", "foo"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.scope.#", "1"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.scope.0.%", "5"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.scope.0.description", "foo"), + resource.TestCheckResourceAttrSet("data.boundary_credential_libraries.foo", "items.0.scope.0.id"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.scope.0.name", "proj1"), + resource.TestCheckResourceAttrSet("data.boundary_credential_libraries.foo", "items.0.scope.0.parent_scope_id"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.scope.0.type", "project"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.type", "vault"), + resource.TestCheckResourceAttrSet("data.boundary_credential_libraries.foo", "items.0.updated_time"), + resource.TestCheckResourceAttr("data.boundary_credential_libraries.foo", "items.0.version", "1"), + ), + }, + }, + }) +} diff --git a/internal/provider/data_source_credential_stores.go b/internal/provider/data_source_credential_stores.go new file mode 100644 index 00000000..5c35dec0 --- /dev/null +++ b/internal/provider/data_source_credential_stores.go @@ -0,0 +1,165 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name CredentialStores -path credential-stores + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceCredentialStoresSchema = map[string]*schema.Schema{ + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Optional user-set description for identification purposes.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Credential Store.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Optional name for identification purposes.", + Computed: true, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "scope_id": { + Type: schema.TypeString, + Description: "The ID of the Scope of which this Credential Store is a part.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "The Credential Store type.", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Description: "Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version.", + Computed: true, + }, + }, + }, + }, + "recursive": { + Type: schema.TypeBool, + Optional: true, + }, + "scope_id": { + Type: schema.TypeString, + Optional: true, + }, +} + +func dataSourceCredentialStores() *schema.Resource { + return &schema.Resource{ + Description: "Lists all Credential Stores.", + Schema: dataSourceCredentialStoresSchema, + ReadContext: dataSourceCredentialStoresRead, + } +} + +func dataSourceCredentialStoresRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "credential-stores", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("filter", d.Get("filter").(string)) + recursive := d.Get("recursive").(bool) + if recursive { + q.Add("recursive", strconv.FormatBool(recursive)) + } + q.Add("scope_id", d.Get("scope_id").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceCredentialStoresSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-credential-stores") + + return nil +} diff --git a/internal/provider/data_source_credential_stores_test.go b/internal/provider/data_source_credential_stores_test.go new file mode 100644 index 00000000..16bff1a4 --- /dev/null +++ b/internal/provider/data_source_credential_stores_test.go @@ -0,0 +1,79 @@ +package provider + +import ( + "regexp" + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/boundary/testing/vault" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooCredentialStoresDataMissingScopeId = ` +data "boundary_credential_stores" "foo" {} +` + fooCredentialStoresData = ` +data "boundary_credential_stores" "foo" { + scope_id = boundary_credential_store_vault.example.scope_id +} +` +) + +func TestAccDataSourceCredentialStores(t *testing.T) { + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + url := tc.ApiAddrs()[0] + + vc := vault.NewTestVaultServer(t) + _, token := vc.CreateToken(t) + res := vaultCredStoreResource(vc, + vaultCredStoreName, + vaultCredStoreDesc, + vaultCredStoreNamespace, + "www.original.com", + token, + true) + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories(&provider), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooCredentialStoresDataMissingScopeId), + ExpectError: regexp.MustCompile("scope_id: This field must be a valid project scope ID or the list operation.*\n.*must be recursive."), + }, + { + Config: testConfig(url, fooOrg, firstProjectFoo, res, fooCredentialStoresData), + + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.#", "1"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.%", "10"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.authorized_actions.#", "4"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.authorized_actions.0", "no-op"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.authorized_actions.1", "read"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.authorized_actions.2", "update"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.authorized_actions.3", "delete"), + resource.TestCheckResourceAttrSet("data.boundary_credential_stores.foo", "items.0.created_time"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.description", "the foo"), + resource.TestCheckResourceAttrSet("data.boundary_credential_stores.foo", "items.0.id"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.name", "foo"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.scope.#", "1"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.scope.0.%", "5"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.scope.0.description", "foo"), + resource.TestCheckResourceAttrSet("data.boundary_credential_stores.foo", "items.0.scope.0.id"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.scope.0.name", "proj1"), + resource.TestCheckResourceAttrSet("data.boundary_credential_stores.foo", "items.0.scope.0.parent_scope_id"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.scope.0.type", "project"), + resource.TestCheckResourceAttrSet("data.boundary_credential_stores.foo", "items.0.scope_id"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.type", "vault"), + resource.TestCheckResourceAttrSet("data.boundary_credential_stores.foo", "items.0.updated_time"), + resource.TestCheckResourceAttr("data.boundary_credential_stores.foo", "items.0.version", "1"), + resource.TestCheckResourceAttrSet("data.boundary_credential_stores.foo", "scope_id"), + ), + }, + }, + }) +} diff --git a/internal/provider/data_source_groups.go b/internal/provider/data_source_groups.go new file mode 100644 index 00000000..2c45e0b3 --- /dev/null +++ b/internal/provider/data_source_groups.go @@ -0,0 +1,187 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name Groups -path groups + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceGroupsSchema = map[string]*schema.Schema{ + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Optional user-set descripton for identification purposes.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Group.", + Computed: true, + }, + "member_ids": { + Type: schema.TypeList, + Description: "Output only. Contains the list of member IDs in this Group.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "members": { + Type: schema.TypeList, + Description: "Output only. The members of this Group.", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the member.", + Computed: true, + }, + "scope_id": { + Type: schema.TypeString, + Description: "Output only. The Scope ID of the member.", + Computed: true, + }, + }, + }, + }, + "name": { + Type: schema.TypeString, + Description: "Optional name for identification purposes.", + Computed: true, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "scope_id": { + Type: schema.TypeString, + Description: "The ID of the scope of which this Group is a part.", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Description: "Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version.", + Computed: true, + }, + }, + }, + }, + "recursive": { + Type: schema.TypeBool, + Optional: true, + }, + "scope_id": { + Type: schema.TypeString, + Optional: true, + }, +} + +func dataSourceGroups() *schema.Resource { + return &schema.Resource{ + Description: "Lists all Groups.", + Schema: dataSourceGroupsSchema, + ReadContext: dataSourceGroupsRead, + } +} + +func dataSourceGroupsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "groups", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("filter", d.Get("filter").(string)) + recursive := d.Get("recursive").(bool) + if recursive { + q.Add("recursive", strconv.FormatBool(recursive)) + } + q.Add("scope_id", d.Get("scope_id").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceGroupsSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-groups") + + return nil +} diff --git a/internal/provider/data_source_groups_test.go b/internal/provider/data_source_groups_test.go new file mode 100644 index 00000000..6e420be6 --- /dev/null +++ b/internal/provider/data_source_groups_test.go @@ -0,0 +1,71 @@ +package provider + +import ( + "regexp" + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooGroupsDataMissingScopeId = ` +data "boundary_groups" "foo" {} +` + fooGroupsData = ` +data "boundary_groups" "foo" { + scope_id = boundary_group.with_members.scope_id +} +` +) + +func TestAccDataSourceGroups(t *testing.T) { + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + url := tc.ApiAddrs()[0] + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories(&provider), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooGroupsDataMissingScopeId), + ExpectError: regexp.MustCompile("scope_id: Incorrectly formatted identifier."), + }, + { + Config: testConfig(url, fooOrg, orgGroupWithMembers, fooGroupsData), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.#", "1"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.%", "11"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.authorized_actions.#", "7"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.authorized_actions.0", "no-op"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.authorized_actions.1", "read"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.authorized_actions.2", "update"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.authorized_actions.3", "delete"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.authorized_actions.4", "add-members"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.authorized_actions.5", "set-members"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.authorized_actions.6", "remove-members"), + resource.TestCheckResourceAttrSet("data.boundary_groups.foo", "items.0.created_time"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.description", "with members"), + resource.TestCheckResourceAttrSet("data.boundary_groups.foo", "items.0.id"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.member_ids.#", "0"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.members.#", "0"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.name", ""), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.scope.#", "1"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.scope.0.%", "5"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.scope.0.description", ""), + resource.TestCheckResourceAttrSet("data.boundary_groups.foo", "items.0.scope.0.id"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.scope.0.name", "org1"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.scope.0.parent_scope_id", "global"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.scope.0.type", "org"), + resource.TestCheckResourceAttrSet("data.boundary_groups.foo", "items.0.scope_id"), + resource.TestCheckResourceAttrSet("data.boundary_groups.foo", "items.0.updated_time"), + resource.TestCheckResourceAttr("data.boundary_groups.foo", "items.0.version", "2"), + resource.TestCheckResourceAttrSet("data.boundary_groups.foo", "scope_id"), + ), + }, + }, + }) +} diff --git a/internal/provider/data_source_host_catalogs.go b/internal/provider/data_source_host_catalogs.go new file mode 100644 index 00000000..cd5b18b9 --- /dev/null +++ b/internal/provider/data_source_host_catalogs.go @@ -0,0 +1,165 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name HostCatalogs -path host-catalogs + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceHostCatalogsSchema = map[string]*schema.Schema{ + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Optional user-set description for identification purposes.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the host.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Optional name for identification purposes.", + Computed: true, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "scope_id": { + Type: schema.TypeString, + Description: "The ID of the Scope of which this Host Catalog is a part.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "The type of Host Catalog.", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Description: "Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version.", + Computed: true, + }, + }, + }, + }, + "recursive": { + Type: schema.TypeBool, + Optional: true, + }, + "scope_id": { + Type: schema.TypeString, + Optional: true, + }, +} + +func dataSourceHostCatalogs() *schema.Resource { + return &schema.Resource{ + Description: "Gets a list of Host Catalogs.", + Schema: dataSourceHostCatalogsSchema, + ReadContext: dataSourceHostCatalogsRead, + } +} + +func dataSourceHostCatalogsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "host-catalogs", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("filter", d.Get("filter").(string)) + recursive := d.Get("recursive").(bool) + if recursive { + q.Add("recursive", strconv.FormatBool(recursive)) + } + q.Add("scope_id", d.Get("scope_id").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceHostCatalogsSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-host-catalogs") + + return nil +} diff --git a/internal/provider/data_source_host_catalogs_test.go b/internal/provider/data_source_host_catalogs_test.go new file mode 100644 index 00000000..b39ec81d --- /dev/null +++ b/internal/provider/data_source_host_catalogs_test.go @@ -0,0 +1,67 @@ +package provider + +import ( + "regexp" + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooHostCatalogsDataMissingSopeId = ` +data "boundary_host_catalogs" "foo" {} +` + fooHostCatalogsData = ` +data "boundary_host_catalogs" "foo" { + scope_id = boundary_host_catalog.foo.scope_id +} +` +) + +func TestAccDataSourceHostCatalogs(t *testing.T) { + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + url := tc.ApiAddrs()[0] + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories(&provider), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooHostCatalogsDataMissingSopeId), + ExpectError: regexp.MustCompile("scope_id: This field must be a valid project scope ID or the list operation.*\n.*must be recursive."), + }, + { + Config: testConfig(url, fooOrg, firstProjectFoo, projHostCatalog, fooHostCatalogsData), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.#", "1"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.%", "10"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.authorized_actions.#", "4"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.authorized_actions.0", "no-op"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.authorized_actions.1", "read"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.authorized_actions.2", "update"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.authorized_actions.3", "delete"), + resource.TestCheckResourceAttrSet("data.boundary_host_catalogs.foo", "items.0.created_time"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.description", "bar"), + resource.TestCheckResourceAttrSet("data.boundary_host_catalogs.foo", "items.0.id"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.name", "foo"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.scope.#", "1"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.scope.0.%", "5"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.scope.0.description", "foo"), + resource.TestCheckResourceAttrSet("data.boundary_host_catalogs.foo", "items.0.scope.0.id"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.scope.0.name", "proj1"), + resource.TestCheckResourceAttrSet("data.boundary_host_catalogs.foo", "items.0.scope.0.parent_scope_id"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.scope.0.type", "project"), + resource.TestCheckResourceAttrSet("data.boundary_host_catalogs.foo", "items.0.scope_id"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.type", "static"), + resource.TestCheckResourceAttrSet("data.boundary_host_catalogs.foo", "items.0.updated_time"), + resource.TestCheckResourceAttr("data.boundary_host_catalogs.foo", "items.0.version", "1"), + resource.TestCheckResourceAttrSet("data.boundary_host_catalogs.foo", "scope_id"), + ), + }, + }, + }) +} diff --git a/internal/provider/data_source_host_sets.go b/internal/provider/data_source_host_sets.go new file mode 100644 index 00000000..73fbb6ed --- /dev/null +++ b/internal/provider/data_source_host_sets.go @@ -0,0 +1,164 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name HostSets -path host-sets + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceHostSetsSchema = map[string]*schema.Schema{ + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "host_catalog_id": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Optional user-set description for identification purposes.", + Computed: true, + }, + "host_catalog_id": { + Type: schema.TypeString, + Description: "The Host Catalog of which this Host Set is a part.", + Computed: true, + }, + "host_ids": { + Type: schema.TypeList, + Description: "Output only. A list of Hosts in this Host Set.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Host Set.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Optional name for identification purposes.", + Computed: true, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "type": { + Type: schema.TypeString, + Description: "The type of the Host Set.", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Description: "Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version.", + Computed: true, + }, + }, + }, + }, +} + +func dataSourceHostSets() *schema.Resource { + return &schema.Resource{ + Description: "List all Host Sets under the specific Catalog.", + Schema: dataSourceHostSetsSchema, + ReadContext: dataSourceHostSetsRead, + } +} + +func dataSourceHostSetsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "host-sets", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("filter", d.Get("filter").(string)) + q.Add("host_catalog_id", d.Get("host_catalog_id").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceHostSetsSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-host-sets") + + return nil +} diff --git a/internal/provider/data_source_host_sets_test.go b/internal/provider/data_source_host_sets_test.go new file mode 100644 index 00000000..4664a699 --- /dev/null +++ b/internal/provider/data_source_host_sets_test.go @@ -0,0 +1,71 @@ +package provider + +import ( + "regexp" + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooHostSetsDataMissingHostCatalogId = ` +data "boundary_host_sets" "foo" {} +` + fooHostSetsData = ` +data "boundary_host_sets" "foo" { + host_catalog_id = boundary_host_set.foo.host_catalog_id +} +` +) + +func TestAccDataSourceHostSets(t *testing.T) { + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + url := tc.ApiAddrs()[0] + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories(&provider), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooHostSetsDataMissingHostCatalogId), + ExpectError: regexp.MustCompile("host_catalog_id: The field is incorrectly formatted."), + }, + { + Config: testConfig(url, fooOrg, firstProjectFoo, fooHostset, fooHostSetsData), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("data.boundary_host_sets.foo", "host_catalog_id"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.#", "1"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.%", "11"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.authorized_actions.#", "7"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.authorized_actions.0", "no-op"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.authorized_actions.1", "read"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.authorized_actions.2", "update"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.authorized_actions.3", "delete"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.authorized_actions.4", "add-hosts"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.authorized_actions.5", "set-hosts"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.authorized_actions.6", "remove-hosts"), + resource.TestCheckResourceAttrSet("data.boundary_host_sets.foo", "items.0.created_time"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.description", "test hostset"), + resource.TestCheckResourceAttrSet("data.boundary_host_sets.foo", "items.0.host_catalog_id"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.host_ids.#", "0"), + resource.TestCheckResourceAttrSet("data.boundary_host_sets.foo", "items.0.id"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.name", "test"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.scope.#", "1"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.scope.0.%", "5"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.scope.0.description", "foo"), + resource.TestCheckResourceAttrSet("data.boundary_host_sets.foo", "items.0.scope.0.id"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.scope.0.name", "proj1"), + resource.TestCheckResourceAttrSet("data.boundary_host_sets.foo", "items.0.scope.0.parent_scope_id"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.scope.0.type", "project"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.type", "static"), + resource.TestCheckResourceAttrSet("data.boundary_host_sets.foo", "items.0.updated_time"), + resource.TestCheckResourceAttr("data.boundary_host_sets.foo", "items.0.version", "2"), + ), + }, + }, + }) +} diff --git a/internal/provider/data_source_hosts.go b/internal/provider/data_source_hosts.go new file mode 100644 index 00000000..3732df58 --- /dev/null +++ b/internal/provider/data_source_hosts.go @@ -0,0 +1,164 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name Hosts -path hosts + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceHostsSchema = map[string]*schema.Schema{ + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "host_catalog_id": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Optional user-set description for identification purposes.", + Computed: true, + }, + "host_catalog_id": { + Type: schema.TypeString, + Description: "The Host Catalog of which this Host is a part.", + Computed: true, + }, + "host_set_ids": { + Type: schema.TypeList, + Description: "Output only. A list of Host Sets containing this Host.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Host.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Optional name for identification purposes.", + Computed: true, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "type": { + Type: schema.TypeString, + Description: "The type of the resource.", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Description: "Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version.", + Computed: true, + }, + }, + }, + }, +} + +func dataSourceHosts() *schema.Resource { + return &schema.Resource{ + Description: "List all Hosts for the specified Catalog.", + Schema: dataSourceHostsSchema, + ReadContext: dataSourceHostsRead, + } +} + +func dataSourceHostsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "hosts", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("filter", d.Get("filter").(string)) + q.Add("host_catalog_id", d.Get("host_catalog_id").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceHostsSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-hosts") + + return nil +} diff --git a/internal/provider/data_source_hosts_test.go b/internal/provider/data_source_hosts_test.go new file mode 100644 index 00000000..66bf2103 --- /dev/null +++ b/internal/provider/data_source_hosts_test.go @@ -0,0 +1,68 @@ +package provider + +import ( + "regexp" + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooHostsDataMissingHostCatalogId = ` +data "boundary_hosts" "foo" {} +` + fooHostsData = ` +data "boundary_hosts" "foo" { + host_catalog_id = boundary_host.foo.host_catalog_id +} +` +) + +func TestAccDataSourceHosts(t *testing.T) { + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + url := tc.ApiAddrs()[0] + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories(&provider), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooHostsDataMissingHostCatalogId), + ExpectError: regexp.MustCompile("host_catalog_id: The field is incorrectly formatted."), + }, + { + Config: testConfig(url, fooOrg, firstProjectFoo, projHost, fooHostsData), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("data.boundary_hosts.foo", "host_catalog_id"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.#", "1"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.%", "11"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.authorized_actions.#", "4"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.authorized_actions.0", "no-op"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.authorized_actions.1", "read"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.authorized_actions.2", "update"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.authorized_actions.3", "delete"), + resource.TestCheckResourceAttrSet("data.boundary_hosts.foo", "items.0.created_time"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.description", "test host"), + resource.TestCheckResourceAttrSet("data.boundary_hosts.foo", "items.0.host_catalog_id"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.host_set_ids.#", "0"), + resource.TestCheckResourceAttrSet("data.boundary_hosts.foo", "items.0.id"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.name", "test"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.scope.#", "1"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.scope.0.%", "5"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.scope.0.description", "foo"), + resource.TestCheckResourceAttrSet("data.boundary_hosts.foo", "items.0.scope.0.id"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.scope.0.name", "proj1"), + resource.TestCheckResourceAttrSet("data.boundary_hosts.foo", "items.0.scope.0.parent_scope_id"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.scope.0.type", "project"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.type", "static"), + resource.TestCheckResourceAttrSet("data.boundary_hosts.foo", "items.0.updated_time"), + resource.TestCheckResourceAttr("data.boundary_hosts.foo", "items.0.version", "1"), + ), + }, + }, + }) +} diff --git a/internal/provider/data_source_managed_groups.go b/internal/provider/data_source_managed_groups.go new file mode 100644 index 00000000..73fc22d6 --- /dev/null +++ b/internal/provider/data_source_managed_groups.go @@ -0,0 +1,164 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name ManagedGroups -path managed-groups + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceManagedGroupsSchema = map[string]*schema.Schema{ + "auth_method_id": { + Type: schema.TypeString, + Optional: true, + }, + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "auth_method_id": { + Type: schema.TypeString, + Description: "The ID of the Auth Method that is associated with this ManagedGroup.", + Computed: true, + }, + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Optional user-set description for identification purposes.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the ManagedGroup.", + Computed: true, + }, + "member_ids": { + Type: schema.TypeList, + Description: "Output only. The IDs of the current set of members (accounts) that are associated with this ManagedGroup.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "name": { + Type: schema.TypeString, + Description: "Optional name for identification purposes.", + Computed: true, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "type": { + Type: schema.TypeString, + Description: "The type of this ManagedGroup.", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Description: "Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version.", + Computed: true, + }, + }, + }, + }, +} + +func dataSourceManagedGroups() *schema.Resource { + return &schema.Resource{ + Description: "Lists all ManagedGroups in a specific Auth Method.", + Schema: dataSourceManagedGroupsSchema, + ReadContext: dataSourceManagedGroupsRead, + } +} + +func dataSourceManagedGroupsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "managed-groups", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("auth_method_id", d.Get("auth_method_id").(string)) + q.Add("filter", d.Get("filter").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceManagedGroupsSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-managed-groups") + + return nil +} diff --git a/internal/provider/data_source_managed_groups_test.go b/internal/provider/data_source_managed_groups_test.go new file mode 100644 index 00000000..022e4b4b --- /dev/null +++ b/internal/provider/data_source_managed_groups_test.go @@ -0,0 +1,53 @@ +package provider + +import ( + "fmt" + "regexp" + "strings" + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/cap/oidc" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooManagedGroupsDataMissingAuthMethodId = ` +data "boundary_managed_groups" "foo" {} +` + fooManagedGroupsData = ` +data "boundary_managed_groups" "foo" { + auth_method_id = boundary_auth_method_oidc.foo.id +} +` +) + +func TestAccDataSourceManagedGroups(t *testing.T) { + tp := oidc.StartTestProvider(t) + defer tp.Stop() + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + url := tc.ApiAddrs()[0] + + tpCert := strings.TrimSpace(tp.CACert()) + createConfig := fmt.Sprintf(fooAuthMethodOidc, fooAuthMethodOidcDesc, tp.Addr(), tpCert) + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories(&provider), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooManagedGroupsDataMissingAuthMethodId), + ExpectError: regexp.MustCompile("auth_method_id: Invalid formatted identifier."), + }, + { + Config: testConfig(url, fooOrg, createConfig, fooManagedGroupsData), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("data.boundary_managed_groups.foo", "auth_method_id"), + ), + }, + }, + }) +} diff --git a/internal/provider/data_source_roles.go b/internal/provider/data_source_roles.go new file mode 100644 index 00000000..71e99864 --- /dev/null +++ b/internal/provider/data_source_roles.go @@ -0,0 +1,250 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name Roles -path roles + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceRolesSchema = map[string]*schema.Schema{ + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Optional user-set description for identification purposes.", + Computed: true, + }, + "grant_scope_id": { + Type: schema.TypeString, + Description: "The Scope the grants will apply to. If the Role is at the global scope, this can be an org or project. If the Role is at an org scope, this can be a project within the org. It is invalid for this to be anything other than the Role's scope when the Role's scope is a project.", + Computed: true, + }, + "grant_strings": { + Type: schema.TypeList, + Description: "Output only. The grants that this role provides for its principals.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "grants": { + Type: schema.TypeList, + Description: "Output only. The parsed grant information.", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "canonical": { + Type: schema.TypeString, + Description: "Output only. The canonically-formatted string.", + Computed: true, + }, + "json": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "actions": { + Type: schema.TypeList, + Description: "Output only. The actions.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID, if set.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type, if set.", + Computed: true, + }, + }, + }, + }, + "raw": { + Type: schema.TypeString, + Description: "Output only. The original user-supplied string.", + Computed: true, + }, + }, + }, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Role.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Optional name for identification purposes.", + Computed: true, + }, + "principal_ids": { + Type: schema.TypeList, + Description: "Output only. The IDs (only) of principals that are assigned to this role.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "principals": { + Type: schema.TypeList, + Description: "Output only. The principals that are assigned to this role.", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the principal.", + Computed: true, + }, + "scope_id": { + Type: schema.TypeString, + Description: "Output only. The Scope of the principal.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the principal.", + Computed: true, + }, + }, + }, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "scope_id": { + Type: schema.TypeString, + Description: "The ID of the Scope containing this Role.", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Description: "Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version.", + Computed: true, + }, + }, + }, + }, + "recursive": { + Type: schema.TypeBool, + Optional: true, + }, + "scope_id": { + Type: schema.TypeString, + Optional: true, + }, +} + +func dataSourceRoles() *schema.Resource { + return &schema.Resource{ + Description: "Lists all Roles.", + Schema: dataSourceRolesSchema, + ReadContext: dataSourceRolesRead, + } +} + +func dataSourceRolesRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "roles", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("filter", d.Get("filter").(string)) + recursive := d.Get("recursive").(bool) + if recursive { + q.Add("recursive", strconv.FormatBool(recursive)) + } + q.Add("scope_id", d.Get("scope_id").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceRolesSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-roles") + + return nil +} diff --git a/internal/provider/data_source_roles_test.go b/internal/provider/data_source_roles_test.go new file mode 100644 index 00000000..fd899697 --- /dev/null +++ b/internal/provider/data_source_roles_test.go @@ -0,0 +1,78 @@ +package provider + +import ( + "regexp" + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooRolesDataMissingScope = ` +data "boundary_roles" "foo" {} +` + + fooRolesData = ` +data "boundary_roles" "foo" { + scope_id = boundary_role.foo.scope_id +} +` +) + +func TestAccDataSourceRoles(t *testing.T) { + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + url := tc.ApiAddrs()[0] + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories(&provider), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooRolesDataMissingScope), + ExpectError: regexp.MustCompile("scope_id: Improperly formatted field."), + }, + { + Config: testConfig(url, fooOrg, orgRole, fooRolesData), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.#", "1"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.%", "14"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.authorized_actions.#", "10"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.authorized_actions.0", "no-op"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.authorized_actions.1", "read"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.authorized_actions.2", "update"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.authorized_actions.3", "delete"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.authorized_actions.4", "add-principals"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.authorized_actions.5", "set-principals"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.authorized_actions.6", "remove-principals"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.authorized_actions.7", "add-grants"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.authorized_actions.8", "set-grants"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.authorized_actions.9", "remove-grants"), + resource.TestCheckResourceAttrSet("data.boundary_roles.foo", "items.0.created_time"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.description", "bar"), + resource.TestCheckResourceAttrSet("data.boundary_roles.foo", "items.0.grant_scope_id"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.grant_strings.#", "0"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.grants.#", "0"), + resource.TestCheckResourceAttrSet("data.boundary_roles.foo", "items.0.id"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.name", "test"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.principal_ids.#", "0"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.principals.#", "0"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.scope.#", "1"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.scope.0.%", "5"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.scope.0.description", ""), + resource.TestCheckResourceAttrSet("data.boundary_roles.foo", "items.0.scope.0.id"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.scope.0.name", "org1"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.scope.0.parent_scope_id", "global"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.scope.0.type", "org"), + resource.TestCheckResourceAttrSet("data.boundary_roles.foo", "items.0.scope_id"), + resource.TestCheckResourceAttrSet("data.boundary_roles.foo", "items.0.updated_time"), + resource.TestCheckResourceAttr("data.boundary_roles.foo", "items.0.version", "1"), + resource.TestCheckResourceAttrSet("data.boundary_roles.foo", "scope_id"), + ), + }, + }, + }) +} diff --git a/internal/provider/data_source_scopes.go b/internal/provider/data_source_scopes.go new file mode 100644 index 00000000..4ee5f9c3 --- /dev/null +++ b/internal/provider/data_source_scopes.go @@ -0,0 +1,169 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name Scopes -path scopes + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceScopesSchema = map[string]*schema.Schema{ + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Optional user-set descripton for identification purposes.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Optional name for identification purposes.", + Computed: true, + }, + "primary_auth_method_id": { + Type: schema.TypeString, + Computed: true, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "scope_id": { + Type: schema.TypeString, + Description: "The ID of the Scope this resource is in. If this is the \"global\" Scope this field will be empty.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "The type of the resource.", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Description: "Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version.", + Computed: true, + }, + }, + }, + }, + "recursive": { + Type: schema.TypeBool, + Optional: true, + }, + "scope_id": { + Type: schema.TypeString, + Optional: true, + }, +} + +func dataSourceScopes() *schema.Resource { + return &schema.Resource{ + Description: "Lists all Scopes within the Scope provided in the request.", + Schema: dataSourceScopesSchema, + ReadContext: dataSourceScopesRead, + } +} + +func dataSourceScopesRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "scopes", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("filter", d.Get("filter").(string)) + recursive := d.Get("recursive").(bool) + if recursive { + q.Add("recursive", strconv.FormatBool(recursive)) + } + q.Add("scope_id", d.Get("scope_id").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceScopesSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-scopes") + + return nil +} diff --git a/internal/provider/data_source_scopes_test.go b/internal/provider/data_source_scopes_test.go new file mode 100644 index 00000000..1d2418d4 --- /dev/null +++ b/internal/provider/data_source_scopes_test.go @@ -0,0 +1,57 @@ +package provider + +import ( + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooScopesData = ` +data "boundary_scopes" "foo" {} +` +) + +func TestAccDataSourceScopes(t *testing.T) { + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + url := tc.ApiAddrs()[0] + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories(&provider), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooScopesData), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.#", "1"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.%", "11"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.authorized_actions.#", "4"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.authorized_actions.0", "no-op"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.authorized_actions.1", "read"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.authorized_actions.2", "update"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.authorized_actions.3", "delete"), + resource.TestCheckResourceAttrSet("data.boundary_scopes.foo", "items.0.created_time"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.description", "Provides an initial org scope in Boundary"), + resource.TestCheckResourceAttrSet("data.boundary_scopes.foo", "items.0.id"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.name", "Generated org scope"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.primary_auth_method_id", ""), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.scope.#", "1"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.scope.0.%", "5"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.scope.0.description", "Global Scope"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.scope.0.id", "global"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.scope.0.name", "global"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.scope.0.parent_scope_id", ""), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.scope.0.type", "global"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.scope_id", "global"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.type", "org"), + resource.TestCheckResourceAttrSet("data.boundary_scopes.foo", "items.0.updated_time"), + resource.TestCheckResourceAttr("data.boundary_scopes.foo", "items.0.version", "1"), + ), + }, + }, + }) +} diff --git a/internal/provider/data_source_sessions.go b/internal/provider/data_source_sessions.go new file mode 100644 index 00000000..6e4214f4 --- /dev/null +++ b/internal/provider/data_source_sessions.go @@ -0,0 +1,243 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name Sessions -path sessions + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceSessionsSchema = map[string]*schema.Schema{ + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "auth_token_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Auth Token used to authenticate.", + Computed: true, + }, + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "certificate": { + Type: schema.TypeString, + Description: "Output only. The certificate generated for the session. Raw DER bytes.", + Computed: true, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "endpoint": { + Type: schema.TypeString, + Description: "Output only. The endpoint of the Session; that is, the address to which the worker is proxying data.", + Computed: true, + }, + "expiration_time": { + Type: schema.TypeString, + Description: "Output only. After this time the connection will be expired, e.g. forcefully terminated.", + Computed: true, + }, + "host_id": { + Type: schema.TypeString, + Description: "Output only. The Host used by the Session.", + Computed: true, + }, + "host_set_id": { + Type: schema.TypeString, + Description: "Output only. The Host Set sourcing the Host for this Session.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Session.", + Computed: true, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "scope_id": { + Type: schema.TypeString, + Description: "Output only. The Scope of the Session.", + Computed: true, + }, + "states": { + Type: schema.TypeList, + Description: "Output only. The states of this Session in descending order from the current state to the first.", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "end_time": { + Type: schema.TypeString, + Description: "Output only. The time the Session stopped being in this state.", + Computed: true, + }, + "start_time": { + Type: schema.TypeString, + Description: "Output only. The time the Session entered this state.", + Computed: true, + }, + "status": { + Type: schema.TypeString, + Description: "The status of the Session, e.g. \"pending\", \"active\", \"canceling\", \"terminated\".", + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Description: "Output only. The current status of this Session.", + Computed: true, + }, + "target_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Target that created this Session.", + Computed: true, + }, + "termination_reason": { + Type: schema.TypeString, + Description: "Output only. If the session is terminated, this provides a short description as to why.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. Type of the Session (e.g. tcp).", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "user_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the User that requested the Session.", + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Description: "Version is used when canceling this Session to ensure that the operation is acting on a known session state.", + Computed: true, + }, + "worker_info": { + Type: schema.TypeList, + Description: "Output only. Worker information given to the client.", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Description: "The address of the worker.", + Computed: true, + }, + }, + }, + }, + }, + }, + }, + "recursive": { + Type: schema.TypeBool, + Optional: true, + }, + "scope_id": { + Type: schema.TypeString, + Optional: true, + }, +} + +func dataSourceSessions() *schema.Resource { + return &schema.Resource{ + Description: "Lists all Sessions.", + Schema: dataSourceSessionsSchema, + ReadContext: dataSourceSessionsRead, + } +} + +func dataSourceSessionsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "sessions", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("filter", d.Get("filter").(string)) + recursive := d.Get("recursive").(bool) + if recursive { + q.Add("recursive", strconv.FormatBool(recursive)) + } + q.Add("scope_id", d.Get("scope_id").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceSessionsSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-sessions") + + return nil +} diff --git a/internal/provider/data_source_sessions_test.go b/internal/provider/data_source_sessions_test.go new file mode 100644 index 00000000..6db66fc0 --- /dev/null +++ b/internal/provider/data_source_sessions_test.go @@ -0,0 +1,34 @@ +package provider + +import ( + "regexp" + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooSessionsData = ` +data "boundary_sessions" "foo" {} +` +) + +func TestAccDataSourceSessions(t *testing.T) { + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + url := tc.ApiAddrs()[0] + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories(&provider), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooSessionsData), + ExpectError: regexp.MustCompile("scope_id: This field must be a valid project scope ID or the list operation.*\n.*must be recursive."), + }, + }, + }) +} diff --git a/internal/provider/data_source_targets.go b/internal/provider/data_source_targets.go new file mode 100644 index 00000000..d7a4858c --- /dev/null +++ b/internal/provider/data_source_targets.go @@ -0,0 +1,249 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name Targets -path targets + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceTargetsSchema = map[string]*schema.Schema{ + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "application_credential_libraries": { + Type: schema.TypeList, + Description: "Output only. The application credential libraries associated with this Target.", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "credential_store_id": { + Type: schema.TypeString, + Description: "Output only. The Credential Store to which this Credential Library belongs.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Credential Library.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "The ID of the Credential Library.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Credential Library.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the credential library.", + Computed: true, + }, + }, + }, + }, + "application_credential_library_ids": { + Type: schema.TypeList, + Description: "The IDs of the application credential library ids associated with this Target.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Optional user-set description for identification purposes.", + Computed: true, + }, + "host_set_ids": { + Type: schema.TypeList, + Description: "The IDs of the Host Sets associated with this Target.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "host_sets": { + Type: schema.TypeList, + Description: "Output only. The Host Sets associated with this Target.", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "host_catalog_id": { + Type: schema.TypeString, + Description: "Output only. The Host Catalog to which this Host Set belongs.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Host Set.", + Computed: true, + }, + }, + }, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the resource.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Required name for identification purposes.", + Computed: true, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "scope_id": { + Type: schema.TypeString, + Description: "The Scope of of this resource. This must be defined for creation of this resource, but is otherwise output only.", + Computed: true, + }, + "session_connection_limit": { + Type: schema.TypeInt, + Description: "Maximum number of connections allowed in a Session. Unlimited is indicated by the value -1.", + Computed: true, + }, + "session_max_seconds": { + Type: schema.TypeInt, + Description: "Maximum total lifetime of a created Session, in seconds.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "The type of the Target.", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Description: "Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version.", + Computed: true, + }, + "worker_filter": { + Type: schema.TypeString, + Description: "Optional boolean expression to filter the workers that are allowed to satisfy this request.", + Computed: true, + }, + }, + }, + }, + "recursive": { + Type: schema.TypeBool, + Optional: true, + }, + "scope_id": { + Type: schema.TypeString, + Optional: true, + }, +} + +func dataSourceTargets() *schema.Resource { + return &schema.Resource{ + Description: "Lists all Targets.", + Schema: dataSourceTargetsSchema, + ReadContext: dataSourceTargetsRead, + } +} + +func dataSourceTargetsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "targets", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("filter", d.Get("filter").(string)) + recursive := d.Get("recursive").(bool) + if recursive { + q.Add("recursive", strconv.FormatBool(recursive)) + } + q.Add("scope_id", d.Get("scope_id").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceTargetsSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-targets") + + return nil +} diff --git a/internal/provider/data_source_targets_test.go b/internal/provider/data_source_targets_test.go new file mode 100644 index 00000000..e13688d3 --- /dev/null +++ b/internal/provider/data_source_targets_test.go @@ -0,0 +1,92 @@ +package provider + +import ( + "regexp" + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/boundary/testing/vault" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooTargetsDataMissingScope = ` +data "boundary_targets" "foo" {} +` + fooTargetsData = ` +data "boundary_targets" "foo" { + scope_id = boundary_target.foo.scope_id +} +` +) + +func TestAccDataSourceTargets(t *testing.T) { + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + url := tc.ApiAddrs()[0] + + vc := vault.NewTestVaultServer(t) + _, token := vc.CreateToken(t) + credStoreRes := vaultCredStoreResource(vc, + vaultCredStoreName, + vaultCredStoreDesc, + vaultCredStoreNamespace, + "www.original.com", + token, + true) + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories(&provider), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooTargetsDataMissingScope), + ExpectError: regexp.MustCompile("scope_id: This field must be a valid project scope ID or the list operation.*\n.*must be recursive."), + }, + { + Config: testConfig(url, fooOrg, firstProjectFoo, credStoreRes, fooBarCredLibs, fooBarHostSet, fooTarget, fooTargetsData), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.#", "1"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.%", "17"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.application_credential_libraries.#", "0"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.application_credential_library_ids.#", "0"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.#", "11"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.0", "no-op"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.1", "read"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.10", "authorize-session"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.2", "update"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.3", "delete"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.4", "add-host-sets"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.5", "set-host-sets"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.6", "remove-host-sets"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.7", "add-credential-libraries"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.8", "set-credential-libraries"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.9", "remove-credential-libraries"), + resource.TestCheckResourceAttrSet("data.boundary_targets.foo", "items.0.created_time"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.description", "bar"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.host_set_ids.#", "0"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.host_sets.#", "0"), + resource.TestCheckResourceAttrSet("data.boundary_targets.foo", "items.0.id"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.name", "test"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.scope.#", "1"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.scope.0.%", "5"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.scope.0.description", "foo"), + resource.TestCheckResourceAttrSet("data.boundary_targets.foo", "items.0.scope.0.id"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.scope.0.name", "proj1"), + resource.TestCheckResourceAttrSet("data.boundary_targets.foo", "items.0.scope.0.parent_scope_id"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.scope.0.type", "project"), + resource.TestCheckResourceAttrSet("data.boundary_targets.foo", "items.0.scope_id"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.session_connection_limit", "6"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.session_max_seconds", "6000"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.type", "tcp"), + resource.TestCheckResourceAttrSet("data.boundary_targets.foo", "items.0.updated_time"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.version", "3"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.worker_filter", "type == \"foo\""), + resource.TestCheckResourceAttrSet("data.boundary_targets.foo", "scope_id"), + ), + }, + }, + }) +} diff --git a/internal/provider/data_source_users.go b/internal/provider/data_source_users.go new file mode 100644 index 00000000..d981b3aa --- /dev/null +++ b/internal/provider/data_source_users.go @@ -0,0 +1,203 @@ +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:generate go run ../../scripts/generate_datasource.go -name Users -path users + +// This file was generated based on Boundary v0.4.0 + +package provider + +import ( + "context" + "net/url" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSourceUsersSchema = map[string]*schema.Schema{ + "filter": { + Type: schema.TypeString, + Optional: true, + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_ids": { + Type: schema.TypeList, + Description: "Output only. Contains the list of Account IDs linked to this User.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "accounts": { + Type: schema.TypeList, + Description: "Output only. The Accounts linked to this User.", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Account.", + Computed: true, + }, + "scope_id": { + Type: schema.TypeString, + Description: "Output only. The Scope containing the Account.", + Computed: true, + }, + }, + }, + }, + "authorized_actions": { + Type: schema.TypeList, + Description: "Output only. The available actions on this resource for this user.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "created_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was created.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Optional user-set description for identification purposes.", + Computed: true, + }, + "email": { + Type: schema.TypeString, + Computed: true, + }, + "full_name": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the User.", + Computed: true, + }, + "login_name": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Optional name for identification purposes.", + Computed: true, + }, + "primary_account_id": { + Type: schema.TypeString, + Computed: true, + }, + "scope": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Scope, if any.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Scope.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Scope, if any.", + Computed: true, + }, + "parent_scope_id": { + Type: schema.TypeString, + Description: "Output only. The ID of the parent Scope, if any. This field will be empty if this is the \"global\" scope.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the Scope.", + Computed: true, + }, + }, + }, + }, + "scope_id": { + Type: schema.TypeString, + Description: "The ID of the Scope this resource is in.", + Computed: true, + }, + "updated_time": { + Type: schema.TypeString, + Description: "Output only. The time this resource was last updated.", + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Description: "Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.\nThe mutation will fail if the version does not match the latest known good version.", + Computed: true, + }, + }, + }, + }, + "recursive": { + Type: schema.TypeBool, + Optional: true, + }, + "scope_id": { + Type: schema.TypeString, + Optional: true, + }, +} + +func dataSourceUsers() *schema.Resource { + return &schema.Resource{ + Description: "Lists all Users.", + Schema: dataSourceUsersSchema, + ReadContext: dataSourceUsersRead, + } +} + +func dataSourceUsersRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "users", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + q.Add("filter", d.Get("filter").(string)) + recursive := d.Get("recursive").(bool) + if recursive { + q.Add("recursive", strconv.FormatBool(recursive)) + } + q.Add("scope_id", d.Get("scope_id").(string)) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSourceUsersSchema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-users") + + return nil +} diff --git a/internal/provider/data_source_users_test.go b/internal/provider/data_source_users_test.go new file mode 100644 index 00000000..8a932fdf --- /dev/null +++ b/internal/provider/data_source_users_test.go @@ -0,0 +1,76 @@ +package provider + +import ( + "regexp" + "testing" + + "github.com/hashicorp/boundary/testing/controller" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var ( + fooUsersDataMissingScope = ` +data "boundary_users" "foo" {} +` + fooUsersData = ` +data "boundary_users" "foo" { + scope_id = boundary_user.org1.scope_id +} +` +) + +func TestAccDataSourceUsers(t *testing.T) { + tc := controller.NewTestController(t, tcConfig...) + defer tc.Shutdown() + url := tc.ApiAddrs()[0] + token := tc.Token().Token + + var provider *schema.Provider + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories(&provider), + Steps: []resource.TestStep{ + { + Config: testConfig(url, fooUsersDataMissingScope), + ExpectError: regexp.MustCompile("scope_id: Must be 'global' or a valid org scope id when listing."), + }, + { + Config: testConfigWithToken(url, token, fooOrg, orgUser, fooUsersData), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.#", "1"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.%", "15"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.account_ids.#", "0"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.accounts.#", "0"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.authorized_actions.#", "7"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.authorized_actions.0", "no-op"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.authorized_actions.1", "read"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.authorized_actions.2", "update"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.authorized_actions.3", "delete"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.authorized_actions.4", "add-accounts"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.authorized_actions.5", "set-accounts"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.authorized_actions.6", "remove-accounts"), + resource.TestCheckResourceAttrSet("data.boundary_users.foo", "items.0.created_time"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.description", "bar"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.email", ""), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.full_name", ""), + resource.TestCheckResourceAttrSet("data.boundary_users.foo", "items.0.id"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.login_name", ""), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.name", "test"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.primary_account_id", ""), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.scope.#", "1"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.scope.0.%", "5"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.scope.0.description", ""), + resource.TestCheckResourceAttrSet("data.boundary_users.foo", "items.0.scope.0.id"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.scope.0.name", "org1"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.scope.0.parent_scope_id", "global"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.scope.0.type", "org"), + resource.TestCheckResourceAttrSet("data.boundary_users.foo", "items.0.scope_id"), + resource.TestCheckResourceAttrSet("data.boundary_users.foo", "items.0.updated_time"), + resource.TestCheckResourceAttr("data.boundary_users.foo", "items.0.version", "1"), + resource.TestCheckResourceAttrSet("data.boundary_users.foo", "scope_id"), + ), + }, + }, + }) +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index a36a0b74..b903c437 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -93,6 +93,23 @@ func New() *schema.Provider { Description: `The scope ID for the default auth method.`, }, }, + DataSourcesMap: map[string]*schema.Resource{ + "boundary_accounts": dataSourceAccounts(), + "boundary_auth_methods": dataSourceAuthMethods(), + "boundary_auth_tokens": dataSourceAuthTokens(), + "boundary_credential_libraries": dataSourceCredentialLibraries(), + "boundary_credential_stores": dataSourceCredentialStores(), + "boundary_groups": dataSourceGroups(), + "boundary_host_catalogs": dataSourceHostCatalogs(), + "boundary_host_sets": dataSourceHostSets(), + "boundary_hosts": dataSourceHosts(), + "boundary_managed_groups": dataSourceManagedGroups(), + "boundary_roles": dataSourceRoles(), + "boundary_scopes": dataSourceScopes(), + "boundary_sessions": dataSourceSessions(), + "boundary_targets": dataSourceTargets(), + "boundary_users": dataSourceUsers(), + }, ResourcesMap: map[string]*schema.Resource{ "boundary_account": resourceAccount(), "boundary_account_password": resourceAccountPassword(), diff --git a/scripts/generate_datasource.go b/scripts/generate_datasource.go new file mode 100644 index 00000000..ea75cff6 --- /dev/null +++ b/scripts/generate_datasource.go @@ -0,0 +1,359 @@ +package main + +import ( + "bytes" + "flag" + "fmt" + "go/format" + "html/template" + "io" + "log" + "os" + "reflect" + "sort" + "strings" + + "github.com/go-openapi/loads" + "github.com/go-openapi/spec" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + shellquote "github.com/kballard/go-shellquote" + "github.com/sanity-io/litter" +) + +var ( + boundaryVersion = "v0.4.0" + swaggerFile = fmt.Sprintf("https://raw.githubusercontent.com/hashicorp/boundary/%s/internal/gen/controller.swagger.json", boundaryVersion) +) + +func main() { + if err := Main(); err != nil { + log.Fatal(err) + } +} + +func Main() error { + var name, path string + flag.StringVar(&name, "name", "", "") + flag.StringVar(&path, "path", "", "") + flag.Parse() + if name == "" { + return fmt.Errorf("the -name flag must be set") + } + if path == "" { + return fmt.Errorf("the -path flag must be set") + } + + resource, err := NewResourceFromSwagger(swaggerFile, name, "/v1/", path) + if err != nil { + return err + } + + source, err := resource.Render() + if err != nil { + return err + } + return write(source) +} + +type Schema map[string]*schema.Schema + +func (s Schema) String() string { + litter.Config.HideZeroValues = true + litter.Config.HidePrivateFields = true + litter.Config.DumpFunc = func(v reflect.Value, w io.Writer) bool { + switch v.Interface() { + case schema.TypeString: + w.Write([]byte("schema.TypeString")) + return true + case schema.TypeList: + w.Write([]byte("schema.TypeList")) + return true + case schema.TypeInt: + w.Write([]byte("schema.TypeInt")) + return true + case schema.TypeBool: + w.Write([]byte("schema.TypeBool")) + return true + } + return false + } + + res := litter.Sdump(map[string]*schema.Schema(s)) + res = strings.ReplaceAll(res, `": &schema.Schema{`, `": {`) + return strings.ReplaceAll(res, "schema.ValueType", "") +} + +type Resource struct { + name string + path string + description string + schema Schema +} + +func NewResourceFromSwagger(filename, resourceName, root, path string) (*Resource, error) { + document, err := loads.JSONSpec(filename) + if err != nil { + return nil, fmt.Errorf("failed to load spec: %w", err) + } + + swagger := document.Spec() + // ExpandSpec is not careful to merge the attributes so we loose some + // descriptions here + if err = spec.ExpandSpec(swagger, nil); err != nil { + return nil, fmt.Errorf("failed to expand spec") + } + + sch := Schema{} + + op := swagger.Paths.Paths[root+path].Get + for _, param := range op.Parameters { + s, err := getSchemaFromParameter(param) + if err != nil { + return nil, err + } + if s == nil { + continue + } + sch[param.Name] = s + } + for name, prop := range op.Responses.StatusCodeResponses[200].Schema.Properties { + s, err := getSchemaFromProperty(name, prop) + if err != nil { + return nil, err + } + if s == nil { + continue + } + sch[name] = s + } + return &Resource{ + name: resourceName, + path: path, + description: op.Summary, + schema: sch, + }, nil +} + +func getSchemaFromParameter(p spec.Parameter) (*schema.Schema, error) { + s := &schema.Schema{ + Description: p.Description, + Optional: !p.Required, + Required: p.Required, + } + switch ty := p.Type; ty { + case "string": + s.Type = schema.TypeString + case "boolean": + s.Type = schema.TypeBool + default: + return nil, fmt.Errorf("unknwon type %q for %s", ty, p.Name) + } + + return s, nil +} + +func getSchemaFromProperty(name string, p spec.Schema) (*schema.Schema, error) { + s := &schema.Schema{ + Description: p.Description, + Computed: true, + } + if len(p.Type) != 1 { + panic("unexpected") + } + switch ty := p.Type[0]; ty { + case "boolean": + s.Type = schema.TypeBool + case "integer": + s.Type = schema.TypeInt + case "string": + s.Type = schema.TypeString + case "object": + if len(p.Properties) == 0 { + return nil, nil + } + s.Type = schema.TypeList + r := &schema.Resource{ + Schema: map[string]*schema.Schema{}, + } + for n, p := range p.Properties { + se, err := getSchemaFromProperty(name+"."+n, p) + if err != nil { + return nil, err + } + if se == nil { + continue + } + r.Schema[n] = se + } + s.Elem = r + case "array": + s.Type = schema.TypeList + if len(p.Items.Schema.Properties) != 0 { + r := &schema.Resource{ + Schema: map[string]*schema.Schema{}, + } + for n, p := range p.Items.Schema.Properties { + se, err := getSchemaFromProperty(name+"."+n, p) + if err != nil { + return nil, err + } + if se == nil { + continue + } + r.Schema[n] = se + } + s.Elem = r + } else { + se, err := getSchemaFromProperty(name, *p.Items.Schema) + if err != nil { + return nil, err + } + se.Optional = false + se.Computed = false + s.Elem = se + } + default: + return nil, fmt.Errorf("unknwon type %q for %s", ty, name) + } + + return s, nil +} + +func (r *Resource) Render() (string, error) { + attrs := map[string]schema.ValueType{} + for name, schema := range r.schema { + if schema.Optional { + attrs[name] = schema.Type + } + } + attrs_ := []string{} + for a := range attrs { + attrs_ = append(attrs_, a) + } + sort.Strings(attrs_) + + imports := map[string]struct{}{ + "context": {}, + "net/url": {}, + } + + var queryParams []string + for _, attr := range attrs_ { + switch ty := attrs[attr]; ty { + case schema.TypeBool: + imports["strconv"] = struct{}{} + queryParams = append(queryParams, fmt.Sprintf(`%s := d.Get(%q).(bool)`, attr, attr)) + queryParams = append(queryParams, fmt.Sprintf(`if %s {`, attr)) + queryParams = append(queryParams, fmt.Sprintf(`q.Add(%q, strconv.FormatBool(%s))`, attr, attr)) + queryParams = append(queryParams, `}`) + case schema.TypeString: + queryParams = append(queryParams, fmt.Sprintf(`q.Add(%q, d.Get(%q).(string))`, attr, attr)) + default: + panic(fmt.Sprintf("unknown type %q for %q", ty, attr)) + } + + } + + imports_ := []string{} + for i := range imports { + imports_ = append(imports_, i) + } + sort.Strings(imports_) + + t := template.Must(template.New("datasource").Parse(` +// Code generated by scripts/generate_datasource.go. DO NOT EDIT. +//go:{{.GenerateLine}} + +// This file was generated based on Boundary {{.Version}} + +package provider + +import ( + {{range .Imports}}"{{.}}" + {{end}} + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var dataSource{{.Name}}Schema = {{.Schema}} + +func dataSource{{.Name}}() *schema.Resource{ + return &schema.Resource{ + Description: {{.Description}}, + Schema: dataSource{{.Name}}Schema, + ReadContext: dataSource{{.Name}}Read, + } +} + +func dataSource{{.Name}}Read(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*metaData).client + + req, err := client.NewRequest(ctx, "GET", "{{.Path}}", nil) + if err != nil { + return diag.FromErr(err) + } + + q := url.Values{} + {{.Query}} + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + diag.FromErr(err) + } + apiError, err := resp.Decode(nil) + if err != nil { + return diag.FromErr(err) + } + if apiError != nil { + return apiErr(apiError) + } + err = set(dataSource{{.Name}}Schema, d, resp.Map) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("boundary-{{.Path}}") + + return nil +} +`)) + + w := bytes.NewBuffer(nil) + data := map[string]interface{}{ + "GenerateLine": fmt.Sprintf("generate go run ../../scripts/generate_datasource.go %s", shellquote.Join("-name", r.name, "-path", r.path)), + "Version": boundaryVersion, + "Imports": imports_, + "Name": r.name, + "Schema": template.HTML(r.schema.String()), + "Description": template.HTML(fmt.Sprintf("%q", r.description)), + "Path": template.HTML(r.path), + "Query": template.HTML(strings.Join(queryParams, "\n")), + } + if err := t.Execute(w, data); err != nil { + return "", err + } + + source, err := format.Source(w.Bytes()) + if err != nil { + log.Fatalf("the generated go code is incorrect: %s", err) + } + + return string(source), nil +} + +func write(source string) error { + if filename := os.Getenv("GOFILE"); filename != "" { + f, err := os.Create(os.Getenv("GOFILE")) + if err != nil { + return err + } + defer f.Close() + f.Write([]byte(source)) + } else { + fmt.Print(source) + } + + return nil +} From fda8a0298789ab5d3bbea52a20f000bfde0e596f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Lapeyre?= Date: Sun, 19 Sep 2021 00:51:15 +0200 Subject: [PATCH 2/2] Update datasources for Boundary v0.6.1 --- internal/provider/data_source_accounts.go | 2 +- internal/provider/data_source_auth_methods.go | 2 +- internal/provider/data_source_auth_tokens.go | 2 +- .../data_source_credential_libraries.go | 2 +- .../provider/data_source_credential_stores.go | 2 +- internal/provider/data_source_groups.go | 2 +- .../provider/data_source_host_catalogs.go | 2 +- internal/provider/data_source_host_sets.go | 2 +- internal/provider/data_source_hosts.go | 2 +- .../provider/data_source_managed_groups.go | 2 +- internal/provider/data_source_roles.go | 2 +- internal/provider/data_source_scopes.go | 2 +- internal/provider/data_source_sessions.go | 2 +- internal/provider/data_source_targets.go | 75 ++++++++++++++++++- internal/provider/data_source_targets_test.go | 7 +- internal/provider/data_source_users.go | 2 +- scripts/generate_datasource.go | 2 +- 17 files changed, 93 insertions(+), 19 deletions(-) diff --git a/internal/provider/data_source_accounts.go b/internal/provider/data_source_accounts.go index e91d6be9..9d4cacfa 100644 --- a/internal/provider/data_source_accounts.go +++ b/internal/provider/data_source_accounts.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name Accounts -path accounts -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider diff --git a/internal/provider/data_source_auth_methods.go b/internal/provider/data_source_auth_methods.go index a8d5888f..f10a379b 100644 --- a/internal/provider/data_source_auth_methods.go +++ b/internal/provider/data_source_auth_methods.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name AuthMethods -path auth-methods -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider diff --git a/internal/provider/data_source_auth_tokens.go b/internal/provider/data_source_auth_tokens.go index accd1e0d..66e853bb 100644 --- a/internal/provider/data_source_auth_tokens.go +++ b/internal/provider/data_source_auth_tokens.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name AuthTokens -path auth-tokens -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider diff --git a/internal/provider/data_source_credential_libraries.go b/internal/provider/data_source_credential_libraries.go index 23389c64..ac83389a 100644 --- a/internal/provider/data_source_credential_libraries.go +++ b/internal/provider/data_source_credential_libraries.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name CredentialLibraries -path credential-libraries -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider diff --git a/internal/provider/data_source_credential_stores.go b/internal/provider/data_source_credential_stores.go index 5c35dec0..700f256d 100644 --- a/internal/provider/data_source_credential_stores.go +++ b/internal/provider/data_source_credential_stores.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name CredentialStores -path credential-stores -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider diff --git a/internal/provider/data_source_groups.go b/internal/provider/data_source_groups.go index 2c45e0b3..c142ae8e 100644 --- a/internal/provider/data_source_groups.go +++ b/internal/provider/data_source_groups.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name Groups -path groups -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider diff --git a/internal/provider/data_source_host_catalogs.go b/internal/provider/data_source_host_catalogs.go index cd5b18b9..61481e65 100644 --- a/internal/provider/data_source_host_catalogs.go +++ b/internal/provider/data_source_host_catalogs.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name HostCatalogs -path host-catalogs -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider diff --git a/internal/provider/data_source_host_sets.go b/internal/provider/data_source_host_sets.go index 73fbb6ed..e64a2e46 100644 --- a/internal/provider/data_source_host_sets.go +++ b/internal/provider/data_source_host_sets.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name HostSets -path host-sets -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider diff --git a/internal/provider/data_source_hosts.go b/internal/provider/data_source_hosts.go index 3732df58..67aab33c 100644 --- a/internal/provider/data_source_hosts.go +++ b/internal/provider/data_source_hosts.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name Hosts -path hosts -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider diff --git a/internal/provider/data_source_managed_groups.go b/internal/provider/data_source_managed_groups.go index 73fc22d6..081ba722 100644 --- a/internal/provider/data_source_managed_groups.go +++ b/internal/provider/data_source_managed_groups.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name ManagedGroups -path managed-groups -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider diff --git a/internal/provider/data_source_roles.go b/internal/provider/data_source_roles.go index 71e99864..d630ef99 100644 --- a/internal/provider/data_source_roles.go +++ b/internal/provider/data_source_roles.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name Roles -path roles -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider diff --git a/internal/provider/data_source_scopes.go b/internal/provider/data_source_scopes.go index 4ee5f9c3..418261c7 100644 --- a/internal/provider/data_source_scopes.go +++ b/internal/provider/data_source_scopes.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name Scopes -path scopes -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider diff --git a/internal/provider/data_source_sessions.go b/internal/provider/data_source_sessions.go index 6e4214f4..7d8d4662 100644 --- a/internal/provider/data_source_sessions.go +++ b/internal/provider/data_source_sessions.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name Sessions -path sessions -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider diff --git a/internal/provider/data_source_targets.go b/internal/provider/data_source_targets.go index d7a4858c..4c4fd3f5 100644 --- a/internal/provider/data_source_targets.go +++ b/internal/provider/data_source_targets.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name Targets -path targets -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider @@ -26,7 +26,7 @@ var dataSourceTargetsSchema = map[string]*schema.Schema{ Schema: map[string]*schema.Schema{ "application_credential_libraries": { Type: schema.TypeList, - Description: "Output only. The application credential libraries associated with this Target.", + Description: "Output only. The application credential libraries associated with this Target. Deprecated: use application_credential_sources instead.", Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -60,12 +60,54 @@ var dataSourceTargetsSchema = map[string]*schema.Schema{ }, "application_credential_library_ids": { Type: schema.TypeList, - Description: "The IDs of the application credential library ids associated with this Target.", + Description: "The IDs of the application credential library ids associated with this Target. Deprecated: use application_credential_source_ids instead.", Computed: true, Elem: &schema.Schema{ Type: schema.TypeString, }, }, + "application_credential_source_ids": { + Type: schema.TypeList, + Description: "The IDs of the application credential source ids associated with this Target.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "application_credential_sources": { + Type: schema.TypeList, + Description: "Output only. The application credential sources associated with this Target.", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "credential_store_id": { + Type: schema.TypeString, + Description: "Output only. The Credential Store to which this Credential source belongs.", + Computed: true, + }, + "description": { + Type: schema.TypeString, + Description: "Output only. The description of the Credential source.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "The ID of the Credential. May be empty if the credential is dynamically generated from a library.", + Computed: true, + }, + "name": { + Type: schema.TypeString, + Description: "Output only. The name of the Credential source.", + Computed: true, + }, + "type": { + Type: schema.TypeString, + Description: "Output only. The type of the credential source (e.g. \"vault\"; not the type of the credential itself).", + Computed: true, + }, + }, + }, + }, "authorized_actions": { Type: schema.TypeList, Description: "Output only. The available actions on this resource for this user.", @@ -111,6 +153,33 @@ var dataSourceTargetsSchema = map[string]*schema.Schema{ }, }, }, + "host_source_ids": { + Type: schema.TypeList, + Description: "The IDs of the Host Sources associated with this Target.", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "host_sources": { + Type: schema.TypeList, + Description: "Output only. The Host Sources associated with this Target.", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "host_catalog_id": { + Type: schema.TypeString, + Description: "Output only. The Host Catalog to which this Host Source belongs.", + Computed: true, + }, + "id": { + Type: schema.TypeString, + Description: "Output only. The ID of the Host Set.", + Computed: true, + }, + }, + }, + }, "id": { Type: schema.TypeString, Description: "Output only. The ID of the resource.", diff --git a/internal/provider/data_source_targets_test.go b/internal/provider/data_source_targets_test.go index e13688d3..134c43e4 100644 --- a/internal/provider/data_source_targets_test.go +++ b/internal/provider/data_source_targets_test.go @@ -48,10 +48,13 @@ func TestAccDataSourceTargets(t *testing.T) { { Config: testConfig(url, fooOrg, firstProjectFoo, credStoreRes, fooBarCredLibs, fooBarHostSet, fooTarget, fooTargetsData), Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.boundary_targets.foo", "id", "boundary-targets"), resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.#", "1"), - resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.%", "17"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.%", "21"), resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.application_credential_libraries.#", "0"), resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.application_credential_library_ids.#", "0"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.application_credential_source_ids.#", "0"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.application_credential_sources.#", "0"), resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.#", "11"), resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.0", "no-op"), resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.authorized_actions.1", "read"), @@ -68,6 +71,8 @@ func TestAccDataSourceTargets(t *testing.T) { resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.description", "bar"), resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.host_set_ids.#", "0"), resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.host_sets.#", "0"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.host_source_ids.#", "0"), + resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.host_sources.#", "0"), resource.TestCheckResourceAttrSet("data.boundary_targets.foo", "items.0.id"), resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.name", "test"), resource.TestCheckResourceAttr("data.boundary_targets.foo", "items.0.scope.#", "1"), diff --git a/internal/provider/data_source_users.go b/internal/provider/data_source_users.go index d981b3aa..2b4d1e90 100644 --- a/internal/provider/data_source_users.go +++ b/internal/provider/data_source_users.go @@ -1,7 +1,7 @@ // Code generated by scripts/generate_datasource.go. DO NOT EDIT. //go:generate go run ../../scripts/generate_datasource.go -name Users -path users -// This file was generated based on Boundary v0.4.0 +// This file was generated based on Boundary v0.6.1 package provider diff --git a/scripts/generate_datasource.go b/scripts/generate_datasource.go index ea75cff6..81d9a88e 100644 --- a/scripts/generate_datasource.go +++ b/scripts/generate_datasource.go @@ -21,7 +21,7 @@ import ( ) var ( - boundaryVersion = "v0.4.0" + boundaryVersion = "v0.6.1" swaggerFile = fmt.Sprintf("https://raw.githubusercontent.com/hashicorp/boundary/%s/internal/gen/controller.swagger.json", boundaryVersion) )