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 a46f6a1a..68f14334 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,8 @@ require ( github.com/aws/aws-sdk-go v1.35.4 // indirect github.com/circonus-labs/circonusllhist v0.1.4 // indirect github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe // indirect + github.com/go-openapi/loads v0.20.2 + github.com/go-openapi/spec v0.20.1 github.com/golang/snappy v0.0.2 // indirect github.com/hashicorp/boundary v0.4.0 github.com/hashicorp/boundary/api v0.0.13 @@ -27,12 +29,14 @@ require ( github.com/hashicorp/terraform-plugin-docs v0.4.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.7.0 github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/oklog/run v1.1.0 // indirect github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect github.com/prometheus/common v0.14.0 // indirect github.com/prometheus/procfs v0.2.0 // indirect + github.com/sanity-io/litter v1.5.1 github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c // indirect golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 8d5f3bd1..8c3b7e71 100644 --- a/go.sum +++ b/go.sum @@ -114,6 +114,11 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= @@ -124,6 +129,7 @@ github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -135,6 +141,7 @@ github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190620160927-9418d7b0cd0f/go.mod github.com/aliyun/alibaba-cloud-sdk-go v1.61.545 h1:JlwB4oyTQFRZ4owg+KGkA0DDHGfH1f2qdKNosqT/amg= github.com/aliyun/alibaba-cloud-sdk-go v1.61.545/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA= github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/andybalholm/crlf v0.0.0-20171020200849-670099aa064f/go.mod h1:k8feO4+kXDxro6ErPXBRTJ/ro2mf0SsFG8s7doP9kJE= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= @@ -168,6 +175,12 @@ 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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= @@ -176,6 +189,7 @@ github.com/aws/aws-sdk-go v1.25.3/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/aws/aws-sdk-go v1.35.4 h1:GG0sdhmzQSe4/UcF9iuQP9i+58bPRyU4OpujyzMlVjo= github.com/aws/aws-sdk-go v1.35.4/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= @@ -264,6 +278,7 @@ github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= github.com/danieljoos/wincred v1.1.0 h1:3RNcEpBg4IhIChZdFRSdlQt1QjCp1sMAPIrOnm7Yf8g= github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg= +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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -285,6 +300,7 @@ github.com/docker/docker v17.12.0-ce-rc1.0.20210128214336-420b1d36250f+incompati github.com/docker/docker v17.12.0-ce-rc1.0.20210128214336-420b1d36250f+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -327,6 +343,8 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= @@ -351,6 +369,91 @@ github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9p github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= +github.com/go-openapi/analysis v0.19.16 h1:Ub9e++M8sDwtHD+S587TYi+6ANBG1NRYGZDihqk0SaY= +github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk= +github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9 h1:9SnKdGhiPZHF3ttwFMiCBEb8jQ4IDdrK+5+a0oTygA4= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= +github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY= +github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4= +github.com/go-openapi/loads v0.20.2 h1:z5p5Xf5wujMxS1y8aP+vxwW5qYT2zdJBbXKmQUG3lcc= +github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= +github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= +github.com/go-openapi/runtime v0.19.24 h1:TqagMVlRAOTwllE/7hNKx6rQ10O6T8ZzeJdMjSTKaD4= +github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= +github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= +github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= +github.com/go-openapi/spec v0.20.1 h1:5WNKTzPguDN+79wbJw2UE2q+eX+gUmEFsIKSvnSQJlc= +github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ= +github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= +github.com/go-openapi/strfmt v0.20.0 h1:l2omNtmNbMc39IGptl9BuXBEKcZfS8zjrTsPKTiJiDM= +github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= +github.com/go-openapi/swag v0.19.13 h1:233UVgMy1DlmCYYfOiFpta6e2urloh+sEs5id6lyzog= +github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= +github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8= +github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= +github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI= +github.com/go-openapi/validate v0.20.1 h1:QGQ5CvK74E28t3DkegGweKR+auemUi5IdpMc4x3UW6s= +github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= @@ -359,13 +462,38 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= @@ -697,7 +825,10 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +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/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -717,6 +848,9 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8 github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/k0kubun/pp v2.3.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +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 v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= @@ -727,6 +861,7 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg= @@ -742,6 +877,7 @@ github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -764,7 +900,16 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/pkger v0.15.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= 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= @@ -820,6 +965,7 @@ github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= @@ -835,6 +981,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= @@ -907,6 +1054,8 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -922,6 +1071,7 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -970,6 +1120,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qq github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= @@ -983,6 +1135,8 @@ github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFo 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/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sanity-io/litter v1.5.1 h1:dwnrSypP6q56o3lFxTU+t2fwQ9A+U5qrXVO4Qg9KwVU= +github.com/sanity-io/litter v1.5.1/go.mod h1:5Z71SvaYy5kcGtyglXOC9rrUi3c1E8CamFWjQsazTh0= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= @@ -994,6 +1148,7 @@ github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9Nz github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= @@ -1032,6 +1187,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -1046,6 +1202,8 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/tencentcloud/tencentcloud-sdk-go v1.0.162/go.mod h1:asUz5BPXxgoPGaRgZaVm1iGcUAuHyYUo1nXqKa83cvI= github.com/tencentcloud/tencentcloud-sdk-go v3.0.171+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4= github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk= github.com/tj/go-buffer v1.1.0/go.mod h1:iyiJpfFcR2B9sXu7KvjbT9fpM4mOelRSDTbntVj52Uc= @@ -1067,6 +1225,7 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= @@ -1077,6 +1236,7 @@ github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0B github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yandex-cloud/go-genproto v0.0.0-20200722140432-762fe965ce77/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE= @@ -1100,7 +1260,15 @@ gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2 go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.mongodb.org/mongo-driver v1.4.6 h1:rh7GdYmDrb8AQSkF8yteAus8qYOgOASWDOv1BWqBXkU= +go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -1132,13 +1300,17 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1197,6 +1369,7 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1207,6 +1380,7 @@ golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190225153610-fe579d43d832/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1216,6 +1390,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1241,6 +1416,8 @@ golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201029221708-28c70e62bb1d/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= @@ -1261,6 +1438,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1281,15 +1459,19 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1347,6 +1529,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -1362,16 +1545,23 @@ golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -1601,6 +1791,7 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= 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 9b1cf27e..9f0c48b2 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -53,6 +53,23 @@ func New() *schema.Provider { Description: "The auth method password for password-style auth methods", }, }, + 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 +}