Compare commits

..
141 Commits
Author SHA1 Message Date
Irena Rindos f58bb092e2 Update changelog prior to release (#327)
Release / go-version (push) Successful in 8s
Release / release-notes (push) Successful in 20s
Release / Terraform Provider Release (push) Failing after 0s
* update changelog prior to release
2023-02-15 15:54:25 -05:00
Timothy Messier e891c7ef2e doc(target): Changes from running make docs
This seems to be a reordering of the attributes.
2023-02-15 10:54:21 -05:00
Timothy Messier 55d8778edf feat: Add support for vault ssh certificate credential libraries 2023-02-15 10:54:21 -05:00
Hugo bd9cc97362 feat(provider/target): Enable target with address configurations (#308) 2023-02-10 15:13:52 +00:00
Timothy Messier 340b6d29bf chore: Remove copywrites from example files (#321)
These files are uses as input for generated doc files, as such they can
be ignored by `copywrite`.
2023-02-09 10:39:09 -05:00
Irena Rindos af1b81038b Add egress and ingress worker filters (#319)
* Add egress and ingress worker filters
2023-02-09 08:40:27 -05:00
Irena Rindos 4bff2f69e9 Remove scope id as a required param for worker creation (#316)
* initial commit
2023-01-23 15:40:13 -05:00
Johan Brandhorst-Satzkorn 312b22a1a7 Remove key from CI job (#313) 2023-01-11 12:00:34 -05:00
hashicorp-copywrite[bot] f9819533db [COMPLIANCE] Add Copyright and License Headers (#312)
Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
2023-01-03 17:19:20 -05:00
dependabot[bot] fb8180fe09 build(deps): bump github.com/hashicorp/go-secure-stdlib/configutil/v2
Bumps [github.com/hashicorp/go-secure-stdlib/configutil/v2](https://github.com/hashicorp/go-secure-stdlib) from 2.0.5 to 2.0.7.
- [Release notes](https://github.com/hashicorp/go-secure-stdlib/releases)
- [Commits](https://github.com/hashicorp/go-secure-stdlib/compare/configutil/v2.0.5...configutil/v2.0.7)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/go-secure-stdlib/configutil/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-07 09:56:31 -08:00
dependabot[bot] 68c1db497f build(deps): bump atlassian/gajira-transition from 2.0.2 to 3.0.1
Bumps [atlassian/gajira-transition](https://github.com/atlassian/gajira-transition) from 2.0.2 to 3.0.1.
- [Release notes](https://github.com/atlassian/gajira-transition/releases)
- [Commits](https://github.com/atlassian/gajira-transition/compare/v2.0.2...v3.0.1)

---
updated-dependencies:
- dependency-name: atlassian/gajira-transition
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-07 09:56:16 -08:00
dependabot[bot] a162554f4f build(deps): bump atlassian/gajira-login from 2.0.0 to 3.0.1
Bumps [atlassian/gajira-login](https://github.com/atlassian/gajira-login) from 2.0.0 to 3.0.1.
- [Release notes](https://github.com/atlassian/gajira-login/releases)
- [Commits](https://github.com/atlassian/gajira-login/compare/v2.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: atlassian/gajira-login
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-07 09:56:04 -08:00
Louis Ruch 5e20d1005e chore: Prep for release
Release / go-version (push) Successful in 9s
Release / release-notes (push) Successful in 25s
Release / Terraform Provider Release (push) Failing after 0s
2022-11-29 14:03:43 -08:00
grantorchardandJohan Brandhorst-Satzkorn cfc57d5e25 Add support for boundary_self_managed_worker resource. (#293)
* add initial prototype of self managed worker resource and associated tests

* Add self managed worker resource and associated tests

* Update internal/provider/resource_self_managed_worker.go

Accept suggested schema changes for tags

Co-authored-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>

* add environment variable check for worker led auth testing

* change resource name from self_managed_worker to worker for consistency with the api

* update tag schemas, ensure all attributes have descriptions

* add generated docs for worker

* add examples for worker resource

* add examples for worker resource

* remove merge conflict

* Remove funtionality for reflecting tags in the schema

* remove unused attributes (all tags) from schema, updates tests to use 'boundary_worker' on resource checks

Co-authored-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
2022-11-24 11:28:27 -05:00
Damian Debkowski 79951499ec chore: update changelog (#291) 2022-10-18 14:43:20 -07:00
Damian Debkowski f95954c83d fix: update resource state even if a subtask fails on resource creation (#289)
Release / go-version (push) Successful in 9s
Release / release-notes (push) Successful in 32s
Release / Terraform Provider Release (push) Failing after 0s
2022-10-17 22:00:23 -07:00
Damian Debkowski 1882beff3c fix: improve error message for invalid provider credentials (#290) 2022-10-17 11:13:45 -07:00
Damian Debkowski 807db1bef1 Support Vault Credential Library Mapping Overrides (#287) 2022-10-13 09:53:42 -07:00
Louis Ruch 24bd9521f4 fix: remove plugin cleanup
Release / go-version (push) Successful in 3s
Release / release-notes (push) Successful in 4s
Release / Terraform Provider Release (push) Failing after 0s
2022-10-12 11:07:10 -07:00
dependabot[bot] ef38f78c46 build(deps): bump github.com/kr/pretty from 0.3.0 to 0.3.1
Bumps [github.com/kr/pretty](https://github.com/kr/pretty) from 0.3.0 to 0.3.1.
- [Release notes](https://github.com/kr/pretty/releases)
- [Commits](https://github.com/kr/pretty/compare/v0.3.0...v0.3.1)

---
updated-dependencies:
- dependency-name: github.com/kr/pretty
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-12 10:31:01 -07:00
CalebAlbers 6255122fba Add or update MPL 2.0 license 2022-10-12 10:30:46 -07:00
Louis Ruch 622fca1c0e chore: run go generate
Release / go-version (push) Successful in 2s
Release / release-notes (push) Successful in 4s
Release / Terraform Provider Release (push) Failing after 0s
2022-10-04 10:22:37 -07:00
Louis Ruch 8aa93ccb69 chore: update changelog 2022-10-04 10:22:37 -07:00
Louis Ruch 1b96f89728 feat(plugin): support plugin exec dir 2022-10-03 18:22:14 -07:00
Louis Ruch e90db9895c chore: Update plugin deps 2022-10-03 18:22:14 -07:00
Damian Debkowski 7ae01cc6e0 feat: add support for json credentials (#271) 2022-09-29 10:31:11 -07:00
Damian Debkowski a134747539 fix: remove deprecated field application_credential_sources_ids (#273) 2022-09-28 12:05:50 -07:00
Louis Ruch 893b150ec9 chore: Update Boundary deps 2022-09-28 11:23:48 -07:00
Louis Ruch a61a13193c bug(vault): Fix panic after token expires 2022-09-28 11:23:17 -07:00
Damian Debkowski 292204caf0 chore: generate missing docs (#274) 2022-09-21 13:45:56 -07:00
Damian Debkowski a2e04949be fix: set secret variables to senitive (#272) 2022-09-21 10:24:34 -07:00
Damian Debkowski 8fad44cc94 fix: set target credentials on update (#270) 2022-09-21 09:30:49 -07:00
Louis Ruch e0fb0a44e0 Remove default_role from role 2022-09-21 09:18:22 -07:00
Louis Ruch 767a9ce1e6 chore: Update changelog
Release / go-version (push) Successful in 3s
Release / release-notes (push) Successful in 4s
Release / Terraform Provider Release (push) Failing after 0s
2022-09-13 11:09:39 -07:00
Louis Ruch f1d8cbf6e6 chore: go fmt 2022-09-13 11:09:39 -07:00
Louis Ruch 072c046b67 chore: Update to go 1.19.1 2022-09-13 11:09:39 -07:00
Louis Ruch 82ae1e3cd7 chore: update deps 2022-09-13 11:09:39 -07:00
Louis Ruch 14bc6a4453 feat(target): Support ssh target 2022-09-13 11:09:39 -07:00
Louis Ruch dc3aa09688 chore: deprecate application_credential_source_ids (#260)
* chore: deprecate application_credential_source_ids
2022-09-07 17:57:26 -07:00
Louis Ruch d6fb6d4c16 chore: run go generate
Release / go-version (push) Successful in 2s
Release / release-notes (push) Successful in 6s
Release / Terraform Provider Release (push) Failing after 0s
2022-08-26 10:43:27 -07:00
Louis Ruch 7164883b1b chore: update changelog 2022-08-26 10:40:52 -07:00
Louis Ruch 7f600f1cd5 fixup! feat: Add support for static ssh_private_key credential 2022-08-26 10:30:52 -07:00
Louis Ruch 145c91305c chore: Add changelog 2022-08-26 10:30:52 -07:00
Louis Ruch deb02086e3 feat(vault-library): Add support for credential type 2022-08-26 10:30:52 -07:00
Louis Ruch 445398286f feat: Add support for static ssh_private_key credential 2022-08-26 10:30:52 -07:00
Louis Ruch 66aad543f6 chore: update deps 2022-08-26 10:30:52 -07:00
Louis Ruch b491b4d123 chore: update changelog
Release / go-version (push) Successful in 3s
Release / release-notes (push) Successful in 4s
Release / Terraform Provider Release (push) Failing after 0s
2022-08-10 14:42:37 -07:00
Louis Ruch bf34f12c56 chore: update docs 2022-08-10 14:42:37 -07:00
Louis Ruch 0f4126d7d0 chore: Update deps 2022-08-10 14:42:37 -07:00
Danielle 41a58f4db5 Username Password Credential Provider (#242)
* add username password resource

* fix a few bugs in the tf code as well as complete tests with copied crypto code

* address PR comments

* clean up all of the hmac testing code

* remove plan only in test and fix some descriptions per PR
2022-08-10 13:38:30 -04:00
Louis Ruch 56f858006e Fix deprecation messages (#235) 2022-08-03 13:11:51 -07:00
Danielle 48672fd050 Static Credential Store (#236)
* added static store plus single test

* revert gomod and gosum changes

* upgrade boundary version from 0.8.1 to 0.9.1

* merged 0.9.1 update and cleaned up test file

* added example for static store, cleanup store and testfile for PR

* update scope test to ignore auto_create_admin_role needed for static credential store test

* update schema function and test comment

* remove auto_create_admin_role in favor of depends_on, and remove all references to the former
2022-07-27 16:08:17 -04:00
dependabot[bot] 5859c55f43 build(deps): bump github.com/stretchr/testify from 1.7.2 to 1.8.0 (#229) 2022-07-27 18:26:59 +00:00
dependabot[bot] fe704abbfc build(deps): bump github.com/hashicorp/terraform-plugin-sdk/v2 (#237) 2022-07-27 18:11:27 +00:00
Danielle e734090217 upgrade boundary version from 0.8.1 to 0.9.1 (#238) 2022-07-25 16:53:20 -04:00
dependabot[bot] f9b5452b84 build(deps): bump github.com/hashicorp/terraform-plugin-docs
Bumps [github.com/hashicorp/terraform-plugin-docs](https://github.com/hashicorp/terraform-plugin-docs) from 0.9.0 to 0.13.0.
- [Release notes](https://github.com/hashicorp/terraform-plugin-docs/releases)
- [Changelog](https://github.com/hashicorp/terraform-plugin-docs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/terraform-plugin-docs/compare/v0.9.0...v0.13.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/terraform-plugin-docs
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-25 09:30:27 -07:00
dependabot[bot] 531dfa486a build(deps): bump github.com/hashicorp/go-secure-stdlib/parseutil
Bumps [github.com/hashicorp/go-secure-stdlib/parseutil](https://github.com/hashicorp/go-secure-stdlib) from 0.1.5 to 0.1.6.
- [Release notes](https://github.com/hashicorp/go-secure-stdlib/releases)
- [Commits](https://github.com/hashicorp/go-secure-stdlib/compare/awsutil/v0.1.5...awsutil/v0.1.6)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/go-secure-stdlib/parseutil
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-06 23:53:15 +00:00
dependabot[bot] 0bbc96fc11 build(deps): bump github.com/stretchr/testify from 1.7.1 to 1.7.2
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.7.1 to 1.7.2.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.7.1...v1.7.2)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-06 23:47:05 +00:00
Louis Ruch f88fe43c12 chore(release): Update changelog
Release / go-version (push) Successful in 2s
Release / release-notes (push) Successful in 4s
Release / Terraform Provider Release (push) Failing after 0s
2022-06-06 11:29:45 -07:00
Louis Ruch 48694a6bab bug(kms): Generate all kms plugin assets during goreleaser pre build (#216) 2022-06-06 11:28:24 -07:00
Louis Ruch d9d4941e0c chore(release): Update changelog
Release / go-version (push) Successful in 3s
Release / release-notes (push) Successful in 4s
Release / Terraform Provider Release (push) Failing after 0s
2022-06-01 13:24:31 -07:00
Louis Ruch 6a704b2505 chore(release): Update changelog 2022-06-01 13:22:31 -07:00
Louis Ruch 55089ad19b chore(go): Update to go 1.18.1 (#208)
* chore(go): Update to go 1.18.1

* chore(deps): Update dependencies
2022-06-01 13:18:01 -07:00
Louis Ruch d8ab0733e8 bug(kms): Add support for all Boundary supported KMSes (#213)
After moving to go-kms-wrapping V2, the Boundary Terraform Provider
did not load all KMS plugins resulting in an error when trying to
create a wrapper for any type other than aead:

    Error: error reading wrappers from "recovery_kms_hcl":
    Error configuring kms: plugin is nil
2022-06-01 13:17:49 -07:00
Jeanne Angeles Franco 9acb1b6f7f Add missing env: key (#207)
Release / go-version (push) Successful in 3s
Release / release-notes (push) Successful in 5s
Release / Terraform Provider Release (push) Failing after 0s
2022-05-16 15:36:54 -07:00
Louis Ruch e6c8309c17 chore(release): Update changelog 2022-05-16 14:46:50 -07:00
Louis Ruch 84bea9c333 chore(deps): Update deps 2022-05-16 14:45:48 -07:00
Louis Ruch 8422393315 chore(changelog): Update changelog 2022-05-16 14:08:27 -07:00
Louis Ruch b8c92ee913 chore(docs): Update docs 2022-05-16 14:08:27 -07:00
Louis Ruch 23c8315fcc fix(role): flaky test regex 2022-05-16 14:08:27 -07:00
Louis Ruch b17b46d3ab fix(kms): Update kms wrapper calls to v2 2022-05-16 14:08:27 -07:00
Louis Ruch 414cdff86e chore(deps): Update deps 2022-05-16 14:08:27 -07:00
Louis Ruch dfaea8e259 fix(account): Update account deprecations
resource_account has been depreacted in favor of
resource_account_password instead of deprecating the individual password
based fields.
2022-05-16 14:08:27 -07:00
dependabot[bot] 1d345d18ac build(deps): bump actions/upload-artifact from 2 to 3 (#195)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2 to 3.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-13 15:20:36 -07:00
modrakeandJeanne Angeles Franco 577b9eb017 [DO NOT MERGE] changes for releases-api launch (#196)
* changes for releases-api launch

* Update to include terraform registry manifest

Co-authored-by: Jeanne Angeles Franco <jeanne.franco@hashicorp.com>
2022-05-10 13:57:48 -04:00
Brian Flad e92a34b624 Migrate Provider Releases from TeamCity to GitHub Actions (#193)
Internal RFC References:

* ENGSRV-035
* ENGSRV-064
* SEC-036
* SEC-061
* TF-279

_Please note: This process can be adjusted to suit your needs, but it will require changes to the workflow setup._

The initial release workflow submitted here is triggered by pushing a semantic version tag prepended with a `v` to the repository. For example:

```shell
git switch main # or your release branch
git pull
git tag v1.2.3
git push origin v1.2.3
```

The most important distinction from the TeamCity release process is that the repository must be fully prepared for the release, including the `CHANGELOG.md` file. Providers can decide the most appropriate process to manage the CHANGELOG or any release notes as part of this new process. This initial workflow will automatically grab contents from the top of the CHANGELOG through the previous release tag header line. [Example provider CHANGELOG](https://github.com/hashicorp/terraform-provider-tls/blob/156ae39c7e55ee8597f859a77ae2db739527376b/CHANGELOG.md) and its [GitHub Release description](https://github.com/hashicorp/terraform-provider-tls/releases/tag/v3.3.0).

Please reach out if you have questions.
2022-04-20 13:55:23 -07:00
KeisukeYamashita 93d925fcfd Add validate func for auth method type key (#178)
* Add validate func for auth key

Signed-off-by: KeisukeYamashita <19yamashita15@gmail.com>

* Add oidc

Signed-off-by: KeisukeYamashita <19yamashita15@gmail.com>
2022-04-02 12:19:43 -07:00
Louis Ruch 214bc5224f chore(deps): Update dependencies (#189) 2022-04-01 16:04:45 -07:00
lrolaz 98a2d617f2 Map Issuer and Subject from attributes elements (#177) 2022-04-01 12:33:10 -07:00
Louis Ruch cbcbdc9955 feat(role): Support partial success in role create/update (#171)
* feat(role): Support partial success in role create/update
2022-01-31 16:03:41 -08:00
tf-release-bot 02445d2192 v1.0.6 2022-01-21 00:58:42 +00:00
Louis Ruch 123284e88f chore(release): Update changelog 2022-01-20 16:56:47 -08:00
6b28ea22a8 Add dynamic host plugin catalog/set (#159)
Co-authored-by: Todd <T.Alan.Knight@gmail.com>
Co-authored-by: Louis Ruch <louisruch@gmail.com>
2022-01-19 16:19:09 -08:00
Peter Lindsten 649b6a54f5 Update incorrect docs (#161)
Update example resource variable name
2021-12-20 07:44:49 -08:00
Louis Ruch 93471e3b28 chore: Update deps 2021-12-17 21:39:22 -08:00
Louis Ruch 452fd1c764 chore: make docs 2021-12-17 21:19:27 -08:00
Olivier Boukili cfe7d47286 Support insecure TLS communication to API endpoint (#163) 2021-12-17 20:24:09 -08:00
Louis Ruch af98aaa9b2 chore(targets): remove deprecated fields (#150) 2021-11-15 13:42:00 -05:00
Louis Ruch 10b421cec8 chore(deps): update dependancies (#149) 2021-10-13 18:10:22 -07:00
dependabot[bot] 98d768f8c8 build(deps): bump github.com/hashicorp/boundary from 0.6.0 to 0.6.1
Bumps [github.com/hashicorp/boundary](https://github.com/hashicorp/boundary) from 0.6.0 to 0.6.1.
- [Release notes](https://github.com/hashicorp/boundary/releases)
- [Changelog](https://github.com/hashicorp/boundary/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/boundary/compare/v0.6.0...v0.6.1)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/boundary
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-21 09:29:34 -04:00
Timothy Messier c869dfb367 ci: Use same docker image from boundary for acceptance tests
Boundary changes how the test harness is used in order to speed up its
tests. It now requires that a postgres docker container is started prior
to running the tests. This adds some make targets to start up the docker
image, using the same image as boundary.
2021-09-21 09:29:34 -04:00
tf-release-bot 5f4fa20ca8 v1.0.5 2021-09-09 15:26:00 +00:00
Louis Ruch 6374cb307b 1.0.5 release update dependencies (#140)
* chore: bump dependencies

* chore: update changelog for release 1.0.5
2021-09-09 08:22:25 -07:00
DevOps RobandLouis Ruch 9c054c1ac8 updating examples to use new grants_strings syntax (#132)
* updating examples to use new grants_strings syntax

* Make docs

Co-authored-by: Louis Ruch <louisruch@gmail.com>
2021-09-08 13:02:12 -07:00
Louis Ruchandgrantorchard 725f2d8fb9 Deprecate target host_set_ids and credential_library_ids (#134)
* Deprecate target host_set_ids and credential_library_ids

* Update changelog

* Include the 'type' attribute in the boundary_target documentation example. (#88)

* Include the 'type' attribute in the example.

* run tfplugindocs to generate the new markdown with type attribute change included

Co-authored-by: grantorchard <go@hashicorp.com>
2021-09-08 11:15:10 -07:00
Louis Ruch 7372487f84 Fix white space 2021-09-01 14:37:22 -07:00
Edgaras f202fbc06d docs: fix examples (#96) 2021-09-01 14:36:33 -07:00
grantorchard 8bb1490ebd Include the 'type' attribute in the boundary_target documentation example. (#88)
* Include the 'type' attribute in the example.

* run tfplugindocs to generate the new markdown with type attribute change included
2021-09-01 14:15:36 -07:00
Louis Ruch 45c1a8c5cc Make docs 2021-08-19 21:13:33 +02:00
tf-release-bot a611a2bcbd v1.0.4 2021-08-19 18:40:46 +00:00
Louis Ruch d3cfbee0be Fix go.sum dependancy 2021-08-19 20:10:29 +02:00
Louis Ruch cf1538c56a Update boundary verisons 2021-08-19 20:02:10 +02:00
6cefb8e376 Add managed group resource (#118)
* feat: add managed group resource

* feat: add tests for managed group resource

* update go.sum

* update tests

* simplify the managed group resource

* use WithDefaultPasswordAuthMethodId

* Managed groups (#129)

* docs: update host catalog resource with correct value for type attribute

* build: add Makefile target for auto-generating docs

* bugfix: make OIDC account attribute for subject ForceNew

* docs: update auto-generated docs

* Add credential library resource for Vault (#114)

* Integrate with Vault to retrieve and manage per session credentials

Co-authored-by: Louis Ruch <louisruch@gmail.com>

* Update token/clientKey on hmac change (#125)

* Update token/clientKey on hmac change

* Update changelog

* Update docs

* Prep for 1.0.3

* v1.0.3

* Update terraform-plugin-sdk

* Fix Typo

* Adopt American spelling

* fix the parameter that is actually being sent as the auth method id

Co-authored-by: Jeff Malnick <malnick@gmail.com>
Co-authored-by: Louis Ruch <louisruch@gmail.com>
Co-authored-by: Jeff Mitchell <jeffrey.mitchell@gmail.com>
Co-authored-by: tf-release-bot <terraform@hashicorp.com>
Co-authored-by: Lewis Cowper <593574+lewiscowper@users.noreply.github.com>

* nits and updates

* OIDC auth method + get filter from attributes

* Add changelog

* Fix schema description

Co-authored-by: Riley Guerin <rileytg@users.noreply.github.com>
Co-authored-by: Louis Ruch <louisruch@gmail.com>
Co-authored-by: Jeff Mitchell <jeffrey.mitchell@gmail.com>
Co-authored-by: tf-release-bot <terraform@hashicorp.com>
Co-authored-by: Lewis Cowper <593574+lewiscowper@users.noreply.github.com>
2021-08-17 07:22:09 +02:00
Lewis Cowper 77eda49baa Adopt American spelling 2021-08-11 14:04:34 -07:00
Lewis Cowper 3f8368e7a6 Fix Typo 2021-08-11 14:04:34 -07:00
Louis Ruch a24f9e15e4 Update terraform-plugin-sdk 2021-06-30 20:13:00 -07:00
tf-release-bot 99914e6317 v1.0.3 2021-06-30 23:47:20 +00:00
Jeff Mitchell 336f68ba68 Prep for 1.0.3 2021-06-30 19:40:27 -04:00
Louis Ruch e1f8352fc4 Update token/clientKey on hmac change (#125)
* Update token/clientKey on hmac change

* Update changelog

* Update docs
2021-06-25 13:30:23 -07:00
Jeff MalnickandLouis Ruch 4f0509c55d Add credential library resource for Vault (#114)
* Integrate with Vault to retrieve and manage per session credentials

Co-authored-by: Louis Ruch <louisruch@gmail.com>
2021-06-22 21:07:07 -07:00
Jeff Malnick 7c73927d17 docs: update auto-generated docs 2021-06-21 10:50:04 -07:00
Jeff Malnick 3c5bbd53c6 bugfix: make OIDC account attribute for subject ForceNew 2021-06-21 10:25:14 -07:00
Jeff Malnick 2d2f825035 build: add Makefile target for auto-generating docs 2021-06-21 10:24:16 -07:00
Jeff Malnick 30b38ea89d docs: update host catalog resource with correct value for type attribute 2021-06-21 10:24:16 -07:00
Jeff Malnick 1c1e593eab feat: add claim scopes attribute 2021-05-25 13:14:02 -07:00
Jeff Malnick 8bfac9f6fa feat: add account claim maps for OIDC auth method resource 2021-05-24 10:03:55 -07:00
Jeff Malnick 3d8121234f build: update boundary mod ref 2021-05-24 10:03:55 -07:00
dependabot[bot] 549a843382 build(deps): bump github.com/hashicorp/boundary from 0.2.0 to 0.2.1 (#109)
Bumps [github.com/hashicorp/boundary](https://github.com/hashicorp/boundary) from 0.2.0 to 0.2.1.
- [Release notes](https://github.com/hashicorp/boundary/releases)
- [Changelog](https://github.com/hashicorp/boundary/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/boundary/compare/v0.2.0...v0.2.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-08 12:54:54 -07:00
tf-release-bot 38f1cf40e9 v1.0.2 2021-05-06 18:52:44 +00:00
Jeff Malnick 4f4318d005 v1.0.2 (#108)
v1.0.2 docs, go mod, and changelog
2021-05-05 10:02:53 -07:00
dependabot[bot] 5af7f8b662 build(deps): bump github.com/hashicorp/boundary/api from 0.0.9 to 0.0.10 (#107)
Bumps [github.com/hashicorp/boundary/api](https://github.com/hashicorp/boundary) from 0.0.9 to 0.0.10.
- [Release notes](https://github.com/hashicorp/boundary/releases)
- [Changelog](https://github.com/hashicorp/boundary/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/boundary/compare/api/v0.0.9...api/v0.0.10)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-05 09:10:32 -07:00
Jeff Malnick 3d42195a26 Add OIDC auth method and account resource (#105)
add OIDC auth method and account resources
2021-05-05 08:33:15 -07:00
Louis Ruch 9bc08d4c48 go mody tidy 2021-05-04 16:38:39 -07:00
Brian Flad 4de1075067 provider: Bump minimum Go version to 1.16 (#104) 2021-05-04 16:25:41 -04:00
Jim dc46913c63 bump deps and catch some unreported errors (#101) 2021-04-28 18:22:18 -04:00
Michele DeggesandJim Lambert bb85735e02 Update ssh key fingerprint (#98)
Co-authored-by: Jim Lambert <jlambert@hashicorp.com>
2021-04-28 15:26:19 -04:00
Jim f49ee1d5bc update TF plugin sdk -> related to GPG key rotation (#100) 2021-04-28 15:16:18 -04:00
Jeff Malnick b01f482fb2 Add contributing guide with pronoun expectations (#92)
* docs: add contributing guide with pronoun expectations
2021-03-30 16:57:11 -07:00
Louis Ruch b69e175687 Boundary 0.1.8 (#91)
* Bump boundary to 0.1.8
2021-03-10 11:58:06 -08:00
tf-release-bot 3f0d2b2acd v1.0.1 2021-02-02 17:41:22 +00:00
Louis Ruch a2c645304f Worker filter (#76)
* Add target worker filtering

* Update docs

* Update changelog
2021-02-02 08:58:10 -08:00
Louis Ruch c0aa9bf5b1 Fix changelog 2021-02-01 11:31:28 -08:00
Louis Ruch 7403e3648e Update boundary (#75)
* Update to latest boundary

* Update changelog
2021-02-01 11:04:08 -08:00
tf-release-bot b96e119b9e v1.0.0 2021-01-20 18:26:04 +00:00
Louis Ruch d94cd5a5ed Dont allow password change via tf apply (#70)
* Don't allow password change via tf apply

* Bump Terraform Boundary provider version to v1.0.0
2021-01-20 08:15:57 -08:00
dependabot[bot] 187d81d91d build(deps): bump tomhjp/gh-action-jira-comment from v0.1.0 to v0.2.0
Bumps [tomhjp/gh-action-jira-comment](https://github.com/tomhjp/gh-action-jira-comment) from v0.1.0 to v0.2.0.
- [Release notes](https://github.com/tomhjp/gh-action-jira-comment/releases)
- [Commits](https://github.com/tomhjp/gh-action-jira-comment/compare/v0.1.0...6eb6b9ead70221916b6badd118c24535ed220bd9)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-14 23:41:55 +00:00
dependabot[bot] 15a46cc8c2 build(deps): bump atlassian/gajira-transition from v2.0.1 to v2.0.2
Bumps [atlassian/gajira-transition](https://github.com/atlassian/gajira-transition) from v2.0.1 to v2.0.2.
- [Release notes](https://github.com/atlassian/gajira-transition/releases)
- [Commits](https://github.com/atlassian/gajira-transition/compare/v2.0.1...0fb280dcc874710a4ac5eced8789e1def040e35d)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-14 23:41:43 +00:00
dependabot[bot] 2a880c05c5 build(deps): bump tomhjp/gh-action-jira-create from v0.1.3 to v0.2.0
Bumps [tomhjp/gh-action-jira-create](https://github.com/tomhjp/gh-action-jira-create) from v0.1.3 to v0.2.0.
- [Release notes](https://github.com/tomhjp/gh-action-jira-create/releases)
- [Commits](https://github.com/tomhjp/gh-action-jira-create/compare/v0.1.3...5f39ec38266014b4aacd129f0f69673b5efdb4db)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-14 23:41:27 +00:00
Louis Ruch 224c8f5849 Update docs (#65)
* Update go mod and include go:generate for docs

* go generate
2021-01-14 14:07:36 -08:00
Paul Tyng 39f8c9f501 Turn on dependabot for actions and Go 2021-01-14 16:50:43 -05:00
Louis Ruch 9cb3297615 Update CHANGELOG.md 2021-01-14 13:23:03 -08:00
190 changed files with 16454 additions and 1841 deletions

No files matched your search

+13 -5
View File
@@ -1,16 +1,24 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
version: 2.1
jobs:
build:
resource_class: large
machine:
image: 'ubuntu-1604:201903-01'
image: 'ubuntu-2004:202107-02'
working_directory: ~/terraform-provider-watchtower
steps:
- add_ssh_keys:
fingerprints:
# hashicorp-ci github "machine" user, for private modules
- "c6:96:98:82:dc:04:6c:39:dd:ac:83:05:e3:15:1c:98"
- checkout
- run:
name: "Install go"
command: |
unset GOPATH # ci image has done strange things with GOPATH, unset it so install-go can fix it
make install-go
source ~/.bashrc
go mod download
- run:
name: "Run Acceptance Tests"
command: |
source ~/.bashrc
make testacc-ci
+16
View File
@@ -0,0 +1,16 @@
schema_version = 1
project {
license = "MPL-2.0"
copyright_year = 2020
# (OPTIONAL) A list of globs that should not have copyright or license headers.
# Supports doublestar glob patterns for more flexibility in defining which
# files or folders should be ignored
# Default: []
header_ignore = [
"examples/**.tf",
"examples/**.sh",
]
}
+20
View File
@@ -0,0 +1,20 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
# See GitHub's docs for more information on this file:
# https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every weekday
interval: "daily"
# Maintain dependencies for Go modules
- package-ecosystem: "gomod"
directory: "/"
schedule:
# Check for updates to Go modules every weekday
interval: "daily"
+5 -5
View File
@@ -30,7 +30,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.JIRA_SYNC_GITHUB_TOKEN }}
- name: Login
uses: atlassian/gajira-login@v2.0.0
uses: atlassian/gajira-login@v3.0.1
env:
JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
@@ -48,7 +48,7 @@ jobs:
- name: Create ticket
if: github.event.action == 'opened' && !steps.boundary-team-role.outputs.role
uses: tomhjp/gh-action-jira-create@v0.1.3
uses: tomhjp/gh-action-jira-create@v0.2.0
with:
project: ICU
issuetype: "GH Issue"
@@ -67,21 +67,21 @@ jobs:
- name: Sync comment
if: github.event.action == 'created' && steps.search.outputs.issue
uses: tomhjp/gh-action-jira-comment@v0.1.0
uses: tomhjp/gh-action-jira-comment@v0.2.0
with:
issue: ${{ steps.search.outputs.issue }}
comment: "${{ github.actor }} ${{ github.event.review.state || 'commented' }}:\n\n${{ github.event.comment.body || github.event.review.body }}\n\n${{ github.event.comment.html_url || github.event.review.html_url }}"
- name: Close ticket
if: (github.event.action == 'closed' || github.event.action == 'deleted') && steps.search.outputs.issue
uses: atlassian/gajira-transition@v2.0.1
uses: atlassian/gajira-transition@v3.0.1
with:
issue: ${{ steps.search.outputs.issue }}
transition: Done
- name: Reopen ticket
if: github.event.action == 'reopened' && steps.search.outputs.issue
uses: atlassian/gajira-transition@v2.0.1
uses: atlassian/gajira-transition@v3.0.1
with:
issue: ${{ steps.search.outputs.issue }}
transition: "To Do"
+51
View File
@@ -0,0 +1,51 @@
name: Release
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*'
permissions:
contents: write
jobs:
go-version:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.go-version.outputs.version }}
steps:
- uses: actions/checkout@v3
- id: go-version
run: echo "::set-output name=version::$(cat ./.go-version)"
release-notes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Generate Release Notes
run: sed -n -e "1{/# /d;}" -e "2{/^$/d;}" -e "/# $(git describe --abbrev=0 --exclude="$(git describe --abbrev=0 --match='v*.*.*' --tags)" --match='v*.*.*' --tags | tr -d v)/q;p" CHANGELOG.md > release-notes.txt
- uses: actions/upload-artifact@v3
with:
name: release-notes
path: release-notes.txt
retention-days: 1
terraform-provider-release:
name: 'Terraform Provider Release'
needs: [go-version, release-notes]
uses: hashicorp/ghaction-terraform-provider-release/.github/workflows/hashicorp.yml@v2
secrets:
hc-releases-github-token: '${{ secrets.HASHI_RELEASES_GITHUB_TOKEN }}'
hc-releases-host-staging: '${{ secrets.HC_RELEASES_HOST_STAGING }}'
hc-releases-host-prod: '${{ secrets.HC_RELEASES_HOST_PROD }}'
hc-releases-key-prod: '${{ secrets.HC_RELEASES_KEY_PROD }}'
hc-releases-key-staging: '${{ secrets.HC_RELEASES_KEY_STAGING }}'
hc-releases-terraform-registry-sync-token: '${{ secrets.TF_PROVIDER_RELEASE_TERRAFORM_REGISTRY_SYNC_TOKEN }}'
setup-signore-github-token: '${{ secrets.HASHI_SIGNORE_GITHUB_TOKEN }}'
signore-client-id: '${{ secrets.SIGNORE_CLIENT_ID }}'
signore-client-secret: '${{ secrets.SIGNORE_CLIENT_SECRET }}'
with:
release-notes: true
setup-go-version: '${{ needs.go-version.outputs.version }}'
# Product Version (e.g. v1.2.3 or github.ref_name)
product-version: '${{ github.ref_name }}'
+3
View File
@@ -33,3 +33,6 @@ website/vendor
# Keep windows files with windows line endings
*.winfile eol=crlf
# Compilation outputs
/plugins/kms/assets/*/*/boundary-plugin*
+1 -1
View File
@@ -1 +1 @@
1.15.2
1.19.1
+78
View File
@@ -0,0 +1,78 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
archives:
- files:
# Ensure only built binary is archived
- 'none*'
format: zip
name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}'
before:
hooks:
- 'go mod download'
- './scripts/plugins-all.sh'
builds:
- # Binary naming only required for Terraform CLI 0.12
binary: '{{ .ProjectName }}_v{{ .Version }}_x5'
env:
- CGO_ENABLED=0
flags:
- -trimpath
goos:
- darwin
- freebsd
- linux
- windows
goarch:
- '386'
- amd64
- arm
- arm64
ignore:
- goarch: arm
goos: windows
- goarch: arm64
goos: freebsd
- goarch: arm64
goos: windows
ldflags:
- -s -w -X main.Version={{.Version}}
mod_timestamp: '{{ .CommitTimestamp }}'
checksum:
algorithm: sha256
extra_files:
- glob: 'terraform-registry-manifest.json'
name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS'
publishers:
- checksum: true
# Terraform CLI 0.10 - 0.11 perform discovery via HTTP headers on releases.hashicorp.com
# For providers which have existed since those CLI versions, exclude
# discovery by setting the protocol version headers to 5.
cmd: hc-releases upload -product {{ .ProjectName }} -version {{ .Version }} -file={{ .ArtifactPath }}={{ .ArtifactName }} -header=x-terraform-protocol-version=5 -header=x-terraform-protocol-versions=5.0
env:
- HC_RELEASES_HOST={{ .Env.HC_RELEASES_HOST }}
- HC_RELEASES_KEY={{ .Env.HC_RELEASES_KEY }}
extra_files:
- glob: 'terraform-registry-manifest.json'
name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
name: upload
signature: true
release:
extra_files:
- glob: 'terraform-registry-manifest.json'
name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
ids:
- none
signs:
- args: ["sign", "--dearmor", "--file", "${artifact}", "--out", "${signature}"]
artifacts: checksum
cmd: signore
signature: ${artifact}.sig
- args: ["sign", "--dearmor", "--file", "${artifact}", "--out", "${signature}"]
artifacts: checksum
cmd: signore
id: key-id
signature: ${artifact}.72D7468F.sig
snapshot:
name_template: "{{ .Tag }}-next"
+5
View File
@@ -0,0 +1,5 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
url_source_repository = "https://github.com/hashicorp/terraform-provider-boundary"
url_license = "https://github.com/hashicorp/terraform-provider-boundary/blob/main/LICENSE"
-1
View File
@@ -1 +0,0 @@
Protocol 5.0 only
+212 -2
View File
@@ -1,7 +1,217 @@
# Boundary Terraform Provider CHANGELOG
Canonical reference for changes, improvements, and bugfixes for the Boundary Terraform provider.
## 1.1.4 (February 15, 2023)
### New and Improved
* Add support for worker egress and ingress filters ([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/319))
* Add support for vault ssh certificate credential libraries ([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/320))
* Add support for targets with address configurations ([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/308))
## 1.1.3 (November 29, 2022)
### New and Improved
* Add support for a workers as a resource
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/293)).
## 1.1.2 (October 18, 2022)
### New and Improved
* Add support for setting mapping overrides for vault credential libraries
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/287)).
### Bug Fixes
* Improve error message when authenticating to boundary
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/290)).
* Set state before returning an error when creating a resource
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/289))
## 1.1.1 (October 12, 2022)
### Bug Fixes
* The plugin cleanup function is being called before the entire Terraform workflow is complete.
([Issue](https://github.com/hashicorp/terraform-provider-boundary/issues/282)),
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/285)).
## 1.1.0 (October 4, 2022)
### New and Improved
* Add support for JSON credentials
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/271)).
* Add support for setting the plugin execution directory from the config
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/280)).
### Deprecations/Changes
* Fix panic resulting from expired Vault credential store tokens
([Issue](https://github.com/hashicorp/terraform-provider-boundary/issues/279),
[PR](https://github.com/hashicorp/terraform-provider-boundary/pull/277)).
* Remove `application_credential_source_ids` of the `target` resource which was deprecated
in 1.0.12 ([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/273)).
* Remove `default_role` from the `role` resource, this schema was never supported and was
included mistakenly ([Issue](https://github.com/hashicorp/terraform-provider-boundary/issues/130),
[PR](https://github.com/hashicorp/terraform-provider-boundary/pull/269)).
## 1.0.12 (September 13, 2022)
### New and Improved
* Add support for SSH targets
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/264)).
### Deprecations/Changes
* Deprecate `application_credential_source_ids` of the `target` resource
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/260)).
## 1.0.11 (August 26, 2022)
### New and Improved
* Add support for SSH private key credentials
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/257)).
* Add support for credential type in Vault libraries
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/257)).
## 1.0.10 (August 10, 2022)
### New and Improved
* Adds support for static credential stores
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/236)).
* Adds support for username password credentials
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/242)).
## 1.0.9 (June 6, 2022)
### Bug Fixes
* The bug fix released in 1.0.8 to resolve the `plugin is nil` error only worked for
Linux AMD64. This was due to a build issue where the plugin binaries were only built for
Linux AMD64. Other platforms would receive an error similar to:
Error: error reading wrappers from "recovery_kms_hcl":
Error configuring kms: error fetching kms plugin rpc client:
fork/exec boundary-plugin-kms-awskms.gz: exec format error
([Issue](https://github.com/hashicorp/terraform-provider-boundary/issues/209)),
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/216)).
## 1.0.8 (June 1, 2022)
### Bug Fixes
* After moving to go-kms-wrapping V2, the Boundary Terraform Provider
did not load all KMS plugins resulting in an error when trying to
create a wrapper for any type other than 'aead':
Error: error reading wrappers from "recovery_kms_hcl":
Error configuring kms: plugin is nil
([Issue](https://github.com/hashicorp/terraform-provider-boundary/issues/209)),
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/213)).
## 1.0.7 (May 16, 2022)
### Deprecations/Changes
* Undoes an erroneous deprecation of the `login_name` and `password` fields in `resource_account_password` and `resource_account`.
Deprecates `resource_account` that was replaced with `resource_account_password`
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/201)).
## 1.0.6 (January 21, 2022)
### New and Improved
* Adds dynamic host plugin catalog/set
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/159)).
* Adds support for insecure TLS to Boundary
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/163)).
### Deprecations/Changes
* Removes fields `host_set_ids` and `application_credential_library_ids` of the
`target` resource, which were deprecated in 1.0.5
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/150)).
## 1.0.5 (September 09, 2021)
### Deprecations/Changes
* Deprecate fields `host_set_ids` and `application_credential_library_ids` of the
`target` resource. See boundary 0.5.0 [changelog](https://github.com/hashicorp/boundary/blob/main/CHANGELOG.md#deprecationschanges) for more detail on the deprecation.
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/134)).
## 1.0.4 (August 19, 2021)
### New and Improved
* Adds managed groups resource
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/118)).
## 1.0.3 (June 30, 2021)
### New and Improved
* Adds credential library resource for Vault
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/114)).
* Adds credential store resource for Vault
([PR 1](https://github.com/hashicorp/terraform-provider-boundary/pull/114)),
([PR 2](https://github.com/hashicorp/terraform-provider-boundary/pull/125)).
* Adds claim scopes attribute to OIDC auth method
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/112)).
* Adds account claim maps attribute to OIDC auth method
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/111)).
### Bug Fixes
* Make OIDC account attribute for subject ForceNew
([Issue](https://github.com/hashicorp/terraform-provider-boundary/issues/119)),
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/122)).
* Update static type attribute for host catalog resource
([Issue](https://github.com/hashicorp/terraform-provider-boundary/issues/115)),
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/121)).
## 1.0.2 (May 06, 2021)
### New and Improved
* Adds OIDC account resource
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/105)).
* Adds OIDC auth method resource
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/105)).
### Deprecations/Changes
* Deprecates fields on `resource_auth_method` that will be replaced in the future with generic `attributes` attribute.
## 1.0.1 (February 02, 2021)
### New and Improved
* Adds worker filter to target resource
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/76)).
## 1.0.0 (January 20, 2021)
We are bumping the version of the Boundary Terraform provider to v1.0.0 and will release new versions of the provider at its own cadence instead of keeping it in lockstep with Boundary.
### Bug Fixes
* During `terraform apply`, do not update existing user account passwords when the password field is updated in the tf file.
([Issue](https://github.com/hashicorp/terraform-provider-boundary/issues/71)),
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/70)).
## 0.1.4 (January 14, 2021)
Boundary 0.1.4 release ([see boundary changelog](https://github.com/hashicorp/boundary/blob/main/CHANGELOG.md#014-20210105))
### New and Improved
## 0.1.0 (2020/10/14)
Update provider to handle new domain errors ([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/63)).
## 0.1.0 (October 14, 2020)
Initial release!
+6
View File
@@ -0,0 +1,6 @@
# Contributing to Boundary
Thank you for contributing to Boundary! Here you can find common questions around reporting issues and opening
pull requests to our project.
When contributing in any way to the Boundary project (new issue, PR, etc), please be aware that our team identifies with many gender pronouns and to use non-binary pronouns when addressing our team. For more reading on our code of conduct, please see the [HashiCorp community guidelines](https://www.hashicorp.com/community-guidelines).
+4 -1
View File
@@ -1,4 +1,7 @@
FROM golang:1.15
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
FROM golang:1.19
WORKDIR /go/src/terraform-provider-boundary
COPY . .
+2
View File
@@ -1,3 +1,5 @@
Copyright (c) 2020 HashiCorp, Inc.
Mozilla Public License Version 2.0
==================================
+50 -5
View File
@@ -1,4 +1,4 @@
default: testacc
default: testacc
GOOS=$(shell go env GOOS)
GOARCH=$(shell go env GOARCH)
INSTALL_PATH=~/.local/share/terraform/plugins/localhost/providers/boundary/0.0.1/linux_$(GOARCH)
@@ -11,6 +11,16 @@ ifeq ($(GOOS), "windows")
INSTALL_PATH=%APPDATA%/HashiCorp/Terraform/plugins/localhost/providers/boundary/0.0.1/windows_$(GOARCH)
endif
REGISTRY_NAME?=docker.io/hashicorpboundary
IMAGE_NAME=postgres
IMAGE_TAG ?= $(REGISTRY_NAME)/$(IMAGE_NAME):11-alpine
DOCKER_ARGS ?= -d
PG_OPTS ?=
TEST_DB_PORT ?= 5432
BOUNDARY_VERSION = $(shell go mod edit -json | jq -r '.["Require"][] | select(.Path=="github.com/hashicorp/boundary") | .["Version"]')
GOPATH ?= ~/go
GOMODCACHE ?= $(GOPATH)/pkg/mod
tools:
go generate -tags tools tools/tools.go
@@ -24,15 +34,22 @@ test:
testacc:
TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m
testacc-ci: install-go
testacc-ci:
git config --global --add url."git@github.com:".insteadOf "https://github.com/"
TF_ACC=1 ~/.go/bin/go test ./... -v $(TESTARGS) -timeout 120m
install-go:
install-go: ~/.go/bin/go
~/.go/bin/go:
./ci/goinstall.sh
dev:
mkdir -p $(INSTALL_PATH)
GOOS=${GOOS} GOARCH=${GOARCH} ./scripts/plugins.sh
mkdir -p $(INSTALL_PATH)
go build -o $(INSTALL_PATH)/terraform-provider-boundary main.go
dev-no-plugins:
mkdir -p $(INSTALL_PATH)
go build -o $(INSTALL_PATH)/terraform-provider-boundary main.go
all:
@@ -41,7 +58,35 @@ all:
GOOS=windows go build -o $(BUILD_ALL_PATH)/terraform-provider-boundary_windows-amd64 main.go
GOOS=linux go build -o $(BUILD_ALL_PATH)/terraform-provider-boundary_linux-amd64 main.go
docs:
go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs
rm-id-flag-from-docs:
find docs/ -name "*.md" -type f | xargs sed -i -e '/- \*\*id\*\*/d'
.PHONY: testacc tools
test-database-up:
@echo "Using image: $(IMAGE_TAG)"
@echo "Additional postgres configuration: $(PG_OPTS)"
@echo "Using volume: $(GOMODCACHE)/github.com/hashicorp/boundary@$(BOUNDARY_VERSION)/internal/db/schema/migrations:/migrations"
@docker run \
$(DOCKER_ARGS) \
--name boundary-sql-tests \
-p $(TEST_DB_PORT):5432 \
-e POSTGRES_PASSWORD=boundary \
-e POSTGRES_USER=boundary \
-e POSTGRES_DB=boundary \
-e PGDATA=/pgdata \
--mount type=tmpfs,destination=/pgdata \
-v "$(GOMODCACHE)/github.com/hashicorp/boundary@$(BOUNDARY_VERSION)/internal/db/schema/migrations":/migrations \
$(IMAGE_TAG) \
-c 'config_file=/etc/postgresql/postgresql.conf' \
$(PG_OPTS) 1> /dev/null
@echo "Test database available at: 127.0.0.1:$(TEST_DB_PORT)"
@echo "For database logs run:"
@echo " docker logs boundary-sql-tests"
test-database-down:
docker stop boundary-sql-tests || true
docker rm -v boundary-sql-tests || true
.PHONY: testacc tools docs test-database-up test-database-down
+14 -3
View File
@@ -9,7 +9,7 @@ Requirements
------------
- [Terraform](https://www.terraform.io/downloads.html) >= 0.12.x
- [Go](https://golang.org/doc/install) >= 1.15
- [Go](https://golang.org/doc/install) >= 1.19
Building The Provider
---------------------
@@ -53,7 +53,15 @@ If you wish to work on the provider, you'll first need [Go](http://www.golang.or
To compile the provider, run `go install`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory.
In order to run the full suite of Acceptance tests, run `make testacc`.
In order to run the full suite of Acceptance tests,
a postgres docker container must be started first:
```sh
$ go mod download # ensure boundary is installed, files are used by the docker image
$ make test-database-up
```
Once the test database is ready the tests can be run using `make testacc`.
*Note:* Acceptance tests create real resources, and often cost money to run.
@@ -61,6 +69,9 @@ In order to run the full suite of Acceptance tests, run `make testacc`.
$ make testacc
```
For more details on the docker image and troubleshooting see the
[boundary testing doc](https://github.com/hashicorp/boundary/blob/main/CONTRIBUTING.md#testing).
Generating Docs
----------------------
@@ -129,7 +140,7 @@ resource "boundary_user" "users" {
scope_id = boundary_scope.corp.id
}
// organiation level group for readonly users
// organization level group for readonly users
resource "boundary_group" "readonly" {
name = "readonly"
description = "Organization group for readonly users"
+4 -1
View File
@@ -1,7 +1,10 @@
#!/bin/bash
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
set -e
VERSION="1.15"
VERSION="1.19.1"
[ -z "$GOROOT" ] && GOROOT="$HOME/.go"
[ -z "$GOPATH" ] && GOPATH="$HOME/go"
+9 -6
View File
@@ -22,16 +22,19 @@ provider "boundary" {
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **addr** (String, Required) The base url of the Boundary API, e.g. "http://127.0.0.1:9200". If not set, it will be read from the "BOUNDARY_ADDR" env var.
- `addr` (String) The base url of the Boundary API, e.g. "http://127.0.0.1:9200". If not set, it will be read from the "BOUNDARY_ADDR" env var.
### Optional
- **auth_method_id** (String, Optional) The auth method ID e.g. ampw_1234567890
- **password_auth_method_login_name** (String, Optional) The auth method login name for password-style auth methods
- **password_auth_method_password** (String, Optional) The auth method password for password-style auth methods
- **recovery_kms_hcl** (String, Optional) Can be a heredoc string or a path on disk. If set, the string/file will be parsed as HCL and used with the recovery KMS mechanism. While this is set, it will override any other authentication information; the KMS mechanism will always be used. See Boundary's KMS docs for examples: https://boundaryproject.io/docs/configuration/kms
- **token** (String, Optional) The Boundary token to use, as a string or path on disk containing just the string. If set, the token read here will be used in place of authenticating with the auth method specified in "auth_method_id", although the recovery KMS mechanism will still override this. Can also be set with the BOUNDARY_TOKEN environment variable.
- `auth_method_id` (String) The auth method ID e.g. ampw_1234567890
- `password_auth_method_login_name` (String) The auth method login name for password-style auth methods
- `password_auth_method_password` (String) The auth method password for password-style auth methods
- `plugin_execution_dir` (String) Specifies a directory that the Boundary provider can use to write and execute its built-in plugins.
- `recovery_kms_hcl` (String) Can be a heredoc string or a path on disk. If set, the string/file will be parsed as HCL and used with the recovery KMS mechanism. While this is set, it will override any other authentication information; the KMS mechanism will always be used. See Boundary's KMS docs for examples: https://boundaryproject.io/docs/configuration/kms
- `tls_insecure` (Boolean) When set to true, does not validate the Boundary API endpoint certificate
- `token` (String) The Boundary token to use, as a string or path on disk containing just the string. If set, the token read here will be used in place of authenticating with the auth method specified in "auth_method_id", although the recovery KMS mechanism will still override this. Can also be set with the BOUNDARY_TOKEN environment variable.
+13 -39
View File
@@ -1,60 +1,34 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_account Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The account resource allows you to configure a Boundary account.
Deprecated: use boundary_account_password instead.
---
# Resource `boundary_account`
# boundary_account (Resource)
The account resource allows you to configure a Boundary account.
Deprecated: use `boundary_account_password` instead.
## Example Usage
```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_auth_method" "password" {
scope_id = boundary_scope.org.id
type = "password"
}
resource "boundary_account" "jeff" {
auth_method_id = boundary_auth_method.password.id
type = "password"
login_name = "jeff"
password = "$uper$ecure"
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **auth_method_id** (String, Required) The resource ID for the auth method.
- **type** (String, Required) The resource type.
- `auth_method_id` (String) The resource ID for the auth method.
- `type` (String) The resource type.
### Optional
- **description** (String, Optional) The account description.
- **login_name** (String, Optional) The login name for this account.
- **name** (String, Optional) The account name. Defaults to the resource name.
- **password** (String, Optional) The account password.
- `description` (String) The account description.
- `login_name` (String) The login name for this account.
- `name` (String) The account name. Defaults to the resource name.
- `password` (String, Sensitive) The account password. Only set on create, changes will not be reflected when updating account.
### Read-only
### Read-Only
- **id** (String, Read-only) The ID of the account.
- `id` (String) The ID of the account.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_account.foo <my-id>
```
+33
View File
@@ -0,0 +1,33 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_account_oidc Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The account resource allows you to configure a Boundary account.
---
# boundary_account_oidc (Resource)
The account resource allows you to configure a Boundary account.
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `auth_method_id` (String) The resource ID for the auth method.
### Optional
- `description` (String) The account description.
- `issuer` (String) The OIDC issuer.
- `name` (String) The account name. Defaults to the resource name.
- `subject` (String) The OIDC subject.
### Read-Only
- `id` (String) The ID of the account.
+62
View File
@@ -0,0 +1,62 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_account_password Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The account resource allows you to configure a Boundary account.
---
# boundary_account_password (Resource)
The account resource allows you to configure a Boundary account.
## Example Usage
```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_auth_method" "password" {
scope_id = boundary_scope.org.id
type = "password"
}
resource "boundary_account_password" "jeff" {
auth_method_id = boundary_auth_method.password.id
type = "password"
login_name = "jeff"
password = "$uper$ecure"
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `auth_method_id` (String) The resource ID for the auth method.
- `type` (String) The resource type.
### Optional
- `description` (String) The account description.
- `login_name` (String) The login name for this account.
- `name` (String) The account name. Defaults to the resource name.
- `password` (String, Sensitive) The account password. Only set on create, changes will not be reflected when updating account.
### Read-Only
- `id` (String) The ID of the account.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_account_password.foo <my-id>
```
+11 -9
View File
@@ -1,11 +1,12 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_auth_method Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The auth method resource allows you to configure a Boundary auth_method.
---
# Resource `boundary_auth_method`
# boundary_auth_method (Resource)
The auth method resource allows you to configure a Boundary auth_method.
@@ -26,23 +27,24 @@ resource "boundary_auth_method" "password" {
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **scope_id** (String, Required) The scope ID.
- **type** (String, Required) The resource type.
- `scope_id` (String) The scope ID.
- `type` (String) The resource type.
### Optional
- **description** (String, Optional) The auth method description.
- **min_login_name_length** (Number, Optional) The minimum login name length.
- **min_password_length** (Number, Optional) The minimum password length.
- **name** (String, Optional) The auth method name. Defaults to the resource name.
- `description` (String) The auth method description.
- `min_login_name_length` (Number, Deprecated) The minimum login name length.
- `min_password_length` (Number, Deprecated) The minimum password length.
- `name` (String) The auth method name. Defaults to the resource name.
### Read-only
### Read-Only
- **id** (String, Read-only) The ID of the account.
- `id` (String) The ID of the account.
## Import
+47
View File
@@ -0,0 +1,47 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_auth_method_oidc Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The OIDC auth method resource allows you to configure a Boundary authmethodoidc.
---
# boundary_auth_method_oidc (Resource)
The OIDC auth method resource allows you to configure a Boundary auth_method_oidc.
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `scope_id` (String) The scope ID.
### Optional
- `account_claim_maps` (List of String) Account claim maps for the to_claim of sub.
- `allowed_audiences` (List of String) Audiences for which the provider responses will be allowed
- `api_url_prefix` (String) The API prefix to use when generating callback URLs for the provider. Should be set to an address at which the provider can reach back to the controller.
- `callback_url` (String) The URL that should be provided to the IdP for callbacks.
- `claims_scopes` (List of String) Claims scopes.
- `client_id` (String) The client ID assigned to this auth method from the provider.
- `client_secret` (String, Sensitive) The secret key assigned to this auth method from the provider. Once set, only the hash will be kept and the original value can be removed from configuration.
- `client_secret_hmac` (String) The HMAC of the client secret returned by the Boundary controller, which is used for comparison after initial setting of the value.
- `description` (String) The auth method description.
- `disable_discovered_config_validation` (Boolean) Disables validation logic ensuring that the OIDC provider's information from its discovery endpoint matches the information here. The validation is only performed at create or update time.
- `idp_ca_certs` (List of String) A list of CA certificates to trust when validating the IdP's token signatures.
- `is_primary_for_scope` (Boolean) When true, makes this auth method the primary auth method for the scope in which it resides. The primary auth method for a scope means the the user will be automatically created when they login using an OIDC account.
- `issuer` (String) The issuer corresponding to the provider, which must match the issuer field in generated tokens.
- `max_age` (Number) The max age to provide to the provider, indicating how much time is allowed to have passed since the last authentication before the user is challenged again.
- `name` (String) The auth method name. Defaults to the resource name.
- `signing_algorithms` (List of String) Allowed signing algorithms for the provider's issued tokens.
- `state` (String) Can be one of 'inactive', 'active-private', or 'active-public'. Currently automatically set to active-public.
- `type` (String) The type of auth method; hardcoded.
### Read-Only
- `id` (String) The ID of the auth method.
+34
View File
@@ -0,0 +1,34 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_auth_method_password Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The auth method resource allows you to configure a Boundary authmethodpassword.
---
# boundary_auth_method_password (Resource)
The auth method resource allows you to configure a Boundary auth_method_password.
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `scope_id` (String) The scope ID.
### Optional
- `description` (String) The auth method description.
- `min_login_name_length` (Number) The minimum login name length.
- `min_password_length` (Number) The minimum password length.
- `name` (String) The auth method name. Defaults to the resource name.
- `type` (String) The resource type, hardcoded per resource
### Read-Only
- `id` (String) The ID of the account.
+69
View File
@@ -0,0 +1,69 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_credential_json Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The json credential resource allows you to congiure a credential using a json object.
---
# boundary_credential_json (Resource)
The json credential resource allows you to congiure a credential using a json object.
## Example Usage
```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "global scope"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_static" "example" {
name = "example_static_credential_store"
description = "My first static credential store!"
scope_id = boundary_scope.project.id
}
resource "boundary_credential_json" "example" {
name = "example_json"
description = "My first json credential!"
credential_store_id = boundary_credential_store_static.example.id
object = file("~/object.json") # change to valid json file
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `credential_store_id` (String) The credential store in which to save this json credential.
- `object` (String, Sensitive) The object for the this json credential. Either values encoded with the "jsonencode" function, pre-escaped JSON string, or a file
### Optional
- `description` (String) The description of this json credential.
- `name` (String) The name of this json credential. Defaults to the resource name.
### Read-Only
- `id` (String) The ID of this json credential.
- `object_hmac` (String) The object hmac.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_credential_json.example_json <my-id>
```
+115
View File
@@ -0,0 +1,115 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_credential_library_vault Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The credential library for Vault resource allows you to configure a Boundary credential library for Vault.
---
# boundary_credential_library_vault (Resource)
The credential library for Vault resource allows you to configure a Boundary credential library for Vault.
## Example Usage
```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_vault" "foo" {
name = "foo"
description = "My first Vault credential store!"
address = "http://127.0.0.1:8200" # change to Vault address
token = "s.0ufRo6XEGU2jOqnIr7OlFYP5" # change to valid Vault token
scope_id = boundary_scope.project.id
}
resource "boundary_credential_library_vault" "foo" {
name = "foo"
description = "My first Vault credential library!"
credential_store_id = boundary_credential_store_vault.foo.id
path = "my/secret/foo" # change to Vault backend path
http_method = "GET"
}
resource "boundary_credential_library_vault" "bar" {
name = "bar"
description = "My second Vault credential library!"
credential_store_id = boundary_credential_store_vault.foo.id
path = "my/secret/bar" # change to Vault backend path
http_method = "POST"
http_request_body = <<EOT
{
"key": "Value",
}
EOT
}
resource "boundary_credential_library_vault" "baz" {
name = "baz"
description = "vault username password credential with mapping overrides"
credential_store_id = boundary_credential_store_vault.foo.id
path = "my/secret/baz" # change to Vault backend path
http_method = "GET"
credential_type = "username_password"
credential_mapping_overrides = {
password_attribute = "alternative_password_label"
username_attribute = "alternative_username_label"
}
}
resource "boundary_credential_library_vault" "quz" {
name = "quz"
description = "vault ssh private key credential with mapping overrides"
credential_store_id = boundary_credential_store_vault.foo.id
path = "my/secret/quz" # change to Vault backend path
http_method = "GET"
credential_type = "ssh_private_key"
credential_mapping_overrides = {
private_key_attribute = "alternative_key_label"
private_key_passphrase_attribute = "alternative_passphrase_label"
username_attribute = "alternative_username_label"
}
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `credential_store_id` (String) The ID of the credential store that this library belongs to.
- `path` (String) The path in Vault to request credentials from.
### Optional
- `credential_mapping_overrides` (Map of String) The credential mapping override.
- `credential_type` (String) The type of credential the library generates.
- `description` (String) The Vault credential library description.
- `http_method` (String) The HTTP method the library uses when requesting credentials from Vault. Defaults to 'GET'
- `http_request_body` (String) The body of the HTTP request the library sends to Vault when requesting credentials. Only valid if `http_method` is set to `POST`.
- `name` (String) The Vault credential library name. Defaults to the resource name.
### Read-Only
- `id` (String) The ID of the Vault credential library.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_credential_library_vault.foo <my-id>
```
@@ -0,0 +1,111 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_credential_library_vault_ssh_certificate Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The credential library for Vault resource allows you to configure a Boundary credential library for Vault.
---
# boundary_credential_library_vault_ssh_certificate (Resource)
The credential library for Vault resource allows you to configure a Boundary credential library for Vault.
## Example Usage
```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_vault" "foo" {
name = "foo"
description = "My first Vault credential store!"
address = "http://127.0.0.1:8200" # change to Vault address
token = "s.0ufRo6XEGU2jOqnIr7OlFYP5" # change to valid Vault token
scope_id = boundary_scope.project.id
}
resource "boundary_credential_library_vault_ssh_certificate" "foo" {
name = "foo"
description = "My first Vault SSH certificate credential library!"
credential_store_id = boundary_credential_store_vault.foo.id
path = "ssh/sign/foo" # change to correct Vault endpoint and role
username = "foo" # change to valid username
}
resource "boundary_credential_library_vault_ssh_certificate" "bar" {
name = "bar"
description = "My second Vault SSH certificate credential library!"
credential_store_id = boundary_credential_store_vault.foo.id
path = "ssh/sign/foo" # change to correct Vault endpoint and role
username = "foo"
key_type = "ecdsa"
key_bits = 384
extensions = {
permit-pty = ""
}
}
resource "boundary_credential_library_vault_ssh_certificate" "baz" {
name = "baz"
description = "vault "
credential_store_id = boundary_credential_store_vault.foo.id
path = "ssh/issue/foo" # change to correct Vault endpoint and role
username = "foo"
key_type = "rsa"
key_bits = 4096
extensions = {
permit-pty = ""
permit-X11-forwarding = ""
}
critical_options = {
force-command = "/bin/some_script"
}
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `credential_store_id` (String) The ID of the credential store that this library belongs to.
- `path` (String) The path in Vault to request credentials from.
- `username` (String) The username to use with the certificate returned by the library.
### Optional
- `critical_options` (Map of String) Specifies a map of the critical options that the certificate should be signed for.
- `description` (String) The Vault credential library description.
- `extensions` (Map of String) Specifies a map of the extensions that the certificate should be signed for.
- `key_bits` (Number) Specifies the number of bits to use for the generated keys.
- `key_id` (String) Specifies the key id a certificate should have.
- `key_type` (String) Specifies the desired key type; must be ed25519, ecdsa, or rsa.
- `name` (String) The Vault credential library name. Defaults to the resource name.
- `ttl` (String) Specifies the requested time to live for a certificate returned from the library.
### Read-Only
- `id` (String) The ID of the Vault credential library.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_credential_library_vault_ssh_certificate.foo <my-id>
```
@@ -0,0 +1,74 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_credential_ssh_private_key Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The SSH private key credential resource allows you to configure a credential using a username, private key and optional passphrase.
---
# boundary_credential_ssh_private_key (Resource)
The SSH private key credential resource allows you to configure a credential using a username, private key and optional passphrase.
## Example Usage
```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "global scope"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_static" "example" {
name = "example_static_credential_store"
description = "My first static credential store!"
scope_id = boundary_scope.project.id
}
resource "boundary_credential_ssh_private_key" "example" {
name = "example_ssh_private_key"
description = "My first ssh private key credential!"
credential_store_id = boundary_credential_store_static.example.id
username = "my-username"
private_key = file("~/.ssh/id_rsa") # change to valid SSH Private Key
private_key_passphrase = "optional-passphrase" # change to the passphrase of the Private Key if required
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `credential_store_id` (String) ID of the credential store this credential belongs to.
- `private_key` (String, Sensitive) The private key associated with the credential.
- `username` (String) The username associated with the credential.
### Optional
- `description` (String) The description of the credential.
- `name` (String) The name of the credential. Defaults to the resource name.
- `private_key_passphrase` (String, Sensitive) The passphrase of the private key associated with the credential.
### Read-Only
- `id` (String) The ID of the credential.
- `private_key_hmac` (String) The private key hmac.
- `private_key_passphrase_hmac` (String) The private key passphrase hmac.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_credential_ssh_private_key.example_ssh_private_key <my-id>
```
+60
View File
@@ -0,0 +1,60 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_credential_store_static Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The static credential store resource allows you to configure a Boundary static credential store.
---
# boundary_credential_store_static (Resource)
The static credential store resource allows you to configure a Boundary static credential store.
## Example Usage
```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "global scope"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_static" "example" {
name = "example_static_credential_store"
description = "My first static credential store!"
scope_id = boundary_scope.project.id
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `scope_id` (String) The scope for this credential store.
### Optional
- `description` (String) The static credential store description.
- `name` (String) The static credential store name. Defaults to the resource name.
### Read-Only
- `id` (String) The ID of the static credential store.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_credential_store_static.example_static_credential_store <my-id>
```
+72
View File
@@ -0,0 +1,72 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_credential_store_vault Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The credential store for Vault resource allows you to configure a Boundary credential store for Vault.
---
# boundary_credential_store_vault (Resource)
The credential store for Vault resource allows you to configure a Boundary credential store for Vault.
## Example Usage
```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_vault" "example" {
name = "foo"
description = "My first Vault credential store!"
address = "http://127.0.0.1:8200" # change to Vault address
token = "s.0ufRo6XEGU2jOqnIr7OlFYP5" # change to valid Vault token
scope_id = boundary_scope.project.id
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `address` (String) The address to Vault server. This should be a complete URL such as 'https://127.0.0.1:8200'
- `scope_id` (String) The scope for this credential store.
- `token` (String, Sensitive) A token used for accessing Vault.
### Optional
- `ca_cert` (String) A PEM-encoded CA certificate to verify the Vault server's TLS certificate.
- `client_certificate` (String) A PEM-encoded client certificate to use for TLS authentication to the Vault server.
- `client_certificate_key` (String, Sensitive) A PEM-encoded private key matching the client certificate from 'client_certificate'.
- `description` (String) The Vault credential store description.
- `name` (String) The Vault credential store name. Defaults to the resource name.
- `namespace` (String) The namespace within Vault to use.
- `tls_server_name` (String) Name to use as the SNI host when connecting to Vault via TLS.
- `tls_skip_verify` (Boolean) Whether or not to skip TLS verification.
### Read-Only
- `client_certificate_key_hmac` (String) The Vault client certificate key hmac.
- `id` (String) The ID of the Vault credential store.
- `token_hmac` (String) The Vault token hmac.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_credential_store_vault.foo <my-id>
```
@@ -0,0 +1,71 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_credential_username_password Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The username/password credential resource allows you to configure a credential using a username and password pair.
---
# boundary_credential_username_password (Resource)
The username/password credential resource allows you to configure a credential using a username and password pair.
## Example Usage
```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "global scope"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_static" "example" {
name = "example_static_credential_store"
description = "My first static credential store!"
scope_id = boundary_scope.project.id
}
resource "boundary_credential_username_password" "example" {
name = "example_username_password"
description = "My first username password credential!"
credential_store_id = boundary_credential_store_static.example.id
username = "my-username"
password = "my-password"
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `credential_store_id` (String) The credential store in which to save this username/password credential.
- `password` (String, Sensitive) The password of this username/password credential.
- `username` (String) The username of this username/password credential.
### Optional
- `description` (String) The description of this username/password credential.
- `name` (String) The name of this username/password credential. Defaults to the resource name.
### Read-Only
- `id` (String) The ID of this username/password credential.
- `password_hmac` (String) The password hmac.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_credential_username_password.example_username_password <my-id>
```
+11 -10
View File
@@ -45,10 +45,10 @@ resource "boundary_scope" "org" {
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_user" "foo" {
@@ -64,21 +64,22 @@ resource "boundary_group" "example" {
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **scope_id** (String, Required) The scope ID in which the resource is created. Defaults to the provider's `default_scope` if unset.
- `scope_id` (String) The scope ID in which the resource is created. Defaults to the provider's `default_scope` if unset.
### Optional
- **description** (String, Optional) The group description.
- **member_ids** (Set of String, Optional) Resource IDs for group members, these are most likely boundary users.
- **name** (String, Optional) The group name. Defaults to the resource name.
- `description` (String) The group description.
- `member_ids` (Set of String) Resource IDs for group members, these are most likely boundary users.
- `name` (String) The group name. Defaults to the resource name.
### Read-only
### Read-Only
- **id** (String, Read-only) The ID of the group.
- `id` (String) The ID of the group.
## Import
+28 -18
View File
@@ -1,13 +1,14 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_host Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The host resource allows you to configure a Boundary static host. Hosts are always part of a project, so a project resource should be used inline or you should have the project ID in hand to successfully configure a host.
Deprecated: use boundary_host_static instead.
---
# Resource `boundary_host`
# boundary_host (Resource)
The host resource allows you to configure a Boundary static host. Hosts are always part of a project, so a project resource should be used inline or you should have the project ID in hand to successfully configure a host.
Deprecated: use `boundary_host_static` instead.
## Example Usage
@@ -21,36 +22,45 @@ resource "boundary_scope" "org" {
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_host_catalog" "static" {
name = "My catalog"
description = "My first host catalog!"
type = "static"
scope_id = boundary_scope.project.id
}
resource "boundary_host" "example" {
name = "example_host"
description = "My first host!"
address = "10.0.0.1"
scope_id = boundary_scope.project.id
type = "static"
name = "example_host"
description = "My first host!"
address = "10.0.0.1"
host_catalog_id = boundary_host_catalog.static.id
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **host_catalog_id** (String, Required)
- **type** (String, Required)
- `host_catalog_id` (String)
- `type` (String) The type of host
### Optional
- **address** (String, Optional) The static address of the host resource as `<IP>` (note: port assignment occurs in the target resource definition, do not add :port here) or a domain name.
- **description** (String, Optional) The host description.
- **name** (String, Optional) The host name. Defaults to the resource name.
- `address` (String) The static address of the host resource as `<IP>` (note: port assignment occurs in the target resource definition, do not add :port here) or a domain name.
- `description` (String) The host description.
- `name` (String) The host name. Defaults to the resource name.
### Read-only
### Read-Only
- **id** (String, Read-only) The ID of the host.
- `id` (String) The ID of the host.
## Import
+15 -13
View File
@@ -1,13 +1,14 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_host_catalog Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The host catalog resource allows you to configure a Boundary host catalog. Host catalogs are always part of a project, so a project resource should be used inline or you should have the project ID in hand to successfully configure a host catalog.
Deprecated: use boundary_host_catalog_static instead.
---
# Resource `boundary_host_catalog`
# boundary_host_catalog (Resource)
The host catalog resource allows you to configure a Boundary host catalog. Host catalogs are always part of a project, so a project resource should be used inline or you should have the project ID in hand to successfully configure a host catalog.
Deprecated: use `boundary_host_catalog_static` instead.
## Example Usage
@@ -21,10 +22,10 @@ resource "boundary_scope" "org" {
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_host_catalog" "example" {
@@ -35,21 +36,22 @@ resource "boundary_host_catalog" "example" {
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **scope_id** (String, Required) The scope ID in which the resource is created.
- **type** (String, Required) The host catalog type. Only `Static` (yes, title case) is supported.
- `scope_id` (String) The scope ID in which the resource is created.
- `type` (String) The host catalog type. Only `static` is supported.
### Optional
- **description** (String, Optional) The host catalog description.
- **name** (String, Optional) The host catalog name. Defaults to the resource name.
- `description` (String) The host catalog description.
- `name` (String) The host catalog name. Defaults to the resource name.
### Read-only
### Read-Only
- **id** (String, Read-only) The ID of the host catalog.
- `id` (String) The ID of the host catalog.
## Import
+108
View File
@@ -0,0 +1,108 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_host_catalog_plugin Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The host catalog resource allows you to configure a Boundary plugin-type host catalog. Host catalogs are always part of a project, so a project resource should be used inline or you should have the project ID in hand to successfully configure a host catalog.
---
# boundary_host_catalog_plugin (Resource)
The host catalog resource allows you to configure a Boundary plugin-type host catalog. Host catalogs are always part of a project, so a project resource should be used inline or you should have the project ID in hand to successfully configure a host catalog.
## Example Usage
```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = boundary_scope.global.id
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
# For more information about the aws plugin, please visit here:
# https://github.com/hashicorp/boundary-plugin-host-aws
#
# For more information about aws users, please visit here:
# https://learn.hashicorp.com/tutorials/boundary/aws-host-catalogs?in=boundary/oss-access-management#configure-terraform-and-iam-user-privileges
resource "boundary_host_catalog_plugin" "aws_example" {
name = "My aws catalog"
description = "My first host catalog!"
scope_id = boundary_scope.project.id
plugin_name = "aws"
attributes_json = jsonencode({ "region" = "us-east-1" })
# recommended to pass in aws secrets using a file() or using environment variables
# the secrets below must be generated in aws by creating a aws iam user with programmatic access
secrets_json = jsonencode({
"access_key_id" = "aws_access_key_id_value",
"secret_access_key" = "aws_secret_access_key_value"
})
}
# For more information about the azure plugin, please visit here:
# https://github.com/hashicorp/boundary-plugin-host-azure
#
# For more information about azure ad applications, please visit here:
# https://learn.hashicorp.com/tutorials/boundary/azure-host-catalogs#register-a-new-azure-ad-application-1
resource "boundary_host_catalog_plugin" "azure_example" {
name = "My azure catalog"
description = "My second host catalog!"
scope_id = boundary_scope.project.id
plugin_name = "azure"
# the attributes below must be generated in azure by creating an ad application
attributes_json = jsonencode({
"disable_credential_rotation" = "true",
"tenant_id" = "ARM_TENANT_ID",
"subscription_id" = "ARM_SUBSCRIPTION_ID",
"client_id" = "ARM_CLIENT_ID"
})
# recommended to pass in aws secrets using a file() or using environment variables
# the secrets below must be generated in azure by creating an ad application
secrets_json = jsonencode({
"secret_value" = "ARM_CLIENT_SECRET"
})
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `scope_id` (String) The scope ID in which the resource is created.
### Optional
- `attributes_json` (String) The attributes for the host catalog. Either values encoded with the "jsonencode" function, pre-escaped JSON string, or a file:// or env:// path. Set to a string "null" or remove the block to clear all attributes in the host catalog.
- `description` (String) The host catalog description.
- `internal_force_update` (String) Internal only. Used to force update so that we can always check the value of secrets.
- `internal_hmac_used_for_secrets_config_hmac` (String) Internal only. The Boundary-provided HMAC used to calculate the current value of the HMAC'd config. Used for drift detection.
- `internal_secrets_config_hmac` (String) Internal only. HMAC of (serverSecretsHmac + config secrets). Used for proper secrets handling.
- `name` (String) The host catalog name. Defaults to the resource name.
- `plugin_id` (String) The ID of the plugin that should back the resource. This or plugin_name must be defined.
- `plugin_name` (String) The name of the plugin that should back the resource. This or plugin_id must be defined.
- `secrets_hmac` (String) The HMAC'd secrets value returned from the server.
- `secrets_json` (String, Sensitive) The secrets for the host catalog. Either values encoded with the "jsonencode" function, pre-escaped JSON string, or a file:// or env:// path. Set to a string "null" to clear any existing values. NOTE: Unlike "attributes_json", removing this block will NOT clear secrets from the host catalog; this allows injecting secrets for one call, then removing them for storage.
### Read-Only
- `id` (String) The ID of the host catalog.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_host_catalog_plugin.foo <my-id>
```
+60
View File
@@ -0,0 +1,60 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_host_catalog_static Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The static host catalog resource allows you to configure a Boundary static-type host catalog. Host catalogs are always part of a project, so a project resource should be used inline or you should have the project ID in hand to successfully configure a host catalog.
---
# boundary_host_catalog_static (Resource)
The static host catalog resource allows you to configure a Boundary static-type host catalog. Host catalogs are always part of a project, so a project resource should be used inline or you should have the project ID in hand to successfully configure a host catalog.
## Example Usage
```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = boundary_scope.global.id
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_host_catalog_static" "example" {
name = "My catalog"
description = "My first host catalog!"
scope_id = boundary_scope.project.id
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `scope_id` (String) The scope ID in which the resource is created.
### Optional
- `description` (String) The host catalog description.
- `name` (String) The host catalog name. Defaults to the resource name.
### Read-Only
- `id` (String) The ID of the host catalog.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_host_catalog_static.foo <my-id>
```
+24 -18
View File
@@ -1,13 +1,14 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_host_set Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The host_set resource allows you to configure a Boundary host set. Host sets are always part of a host catalog, so a host catalog resource should be used inline or you should have the host catalog ID in hand to successfully configure a host set.
Deprecated: use boundary_host_set_static instead.
---
# Resource `boundary_host_set`
# boundary_host_set (Resource)
The host_set resource allows you to configure a Boundary host set. Host sets are always part of a host catalog, so a host catalog resource should be used inline or you should have the host catalog ID in hand to successfully configure a host set.
Deprecated: use `boundary_host_set_static` instead.
## Example Usage
@@ -21,17 +22,19 @@ resource "boundary_scope" "org" {
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_host_catalog" "static" {
type = "static"
scope_id = boundary_scope.project.id
}
resource "boundary_host" "1" {
resource "boundary_host" "first" {
type = "static"
name = "host_1"
description = "My first host!"
address = "10.0.0.1"
@@ -39,7 +42,8 @@ resource "boundary_host" "1" {
scope_id = boundary_scope.project.id
}
resource "boundary_host" "2" {
resource "boundary_host" "second" {
type = "static"
name = "host_2"
description = "My second host!"
address = "10.0.0.2"
@@ -49,29 +53,31 @@ resource "boundary_host" "2" {
resource "boundary_host_set" "web" {
host_catalog_id = boundary_host_catalog.static.id
type = "static"
host_ids = [
boundary_host.1.id,
boundary_host.2.id,
boundary_host.first.id,
boundary_host.second.id,
]
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **host_catalog_id** (String, Required) The catalog for the hostset.
- **type** (String, Required)
- `host_catalog_id` (String) The catalog for the host set.
- `type` (String) The type of host set
### Optional
- **description** (String, Optional) The hostset description.
- **host_ids** (Set of String, Optional) The list of host IDs contained in this set.
- **name** (String, Optional) The hostset name. Defaults to the resource name.
- `description` (String) The host set description.
- `host_ids` (Set of String) The list of host IDs contained in this set.
- `name` (String) The host set name. Defaults to the resource name.
### Read-only
### Read-Only
- **id** (String, Read-only) The ID of the hostset.
- `id` (String) The ID of the host set.
## Import
+147
View File
@@ -0,0 +1,147 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_host_set_plugin Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The hostsetplugin resource allows you to configure a Boundary host set. Host sets are always part of a host catalog, so a host catalog resource should be used inline or you should have the host catalog ID in hand to successfully configure a host set.
---
# boundary_host_set_plugin (Resource)
The host_set_plugin resource allows you to configure a Boundary host set. Host sets are always part of a host catalog, so a host catalog resource should be used inline or you should have the host catalog ID in hand to successfully configure a host set.
## Example Usage
```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
# For more information about the aws plugin, please visit here:
# https://github.com/hashicorp/boundary-plugin-host-aws
#
# For more information about aws users, please visit here:
# https://learn.hashicorp.com/tutorials/boundary/aws-host-catalogs?in=boundary/oss-access-management#configure-terraform-and-iam-user-privileges
resource "boundary_host_catalog_plugin" "aws_example" {
name = "My aws catalog"
description = "My first host catalog!"
scope_id = boundary_scope.project.id
plugin_name = "aws"
attributes_json = jsonencode({ "region" = "us-east-1" })
# recommended to pass in aws secrets using a file() or using environment variables
# the secrets below must be generated in aws by creating a aws iam user with programmatic access
secrets_json = jsonencode({
"access_key_id" = "aws_access_key_id_value",
"secret_access_key" = "aws_secret_access_key_value"
})
}
resource "boundary_host_set_plugin" "web" {
name = "My web host set plugin"
host_catalog_id = boundary_host_catalog_plugin.aws_exmaple.id
attributes_json = jsonencode({ "filters" = "tag:service-type=web" })
}
resource "boundary_host_set_plugin" "foobar" {
name = "My foobar host set plugin"
host_catalog_id = boundary_host_catalog_plugin.aws_exmaple.id
preferred_endpoints = ["cidr:54.0.0.0/8"]
attributes_json = jsonencode({
"filters" = "tag-key=foo",
"filters" = "tag-key=bar"
})
}
resource "boundary_host_set_plugin" "launch" {
name = "My launch host set plugin"
host_catalog_id = boundary_host_catalog_plugin.aws_exmaple.id
sync_interval_seconds = 60
attributes_json = jsonencode({
"filters" = "tag:development=prod,dev",
"filters" = "launch-time=2022-01-04T*"
})
}
# For more information about the azure plugin, please visit here:
# https://github.com/hashicorp/boundary-plugin-host-azure
#
# For more information about azure ad applications, please visit here:
# https://learn.hashicorp.com/tutorials/boundary/azure-host-catalogs#register-a-new-azure-ad-application-1
resource "boundary_host_catalog_plugin" "azure_example" {
name = "My azure catalog"
description = "My second host catalog!"
scope_id = boundary_scope.project.id
plugin_name = "azure"
# the attributes below must be generated in azure by creating an ad application
attributes_json = jsonencode({
"disable_credential_rotation" = "true",
"tenant_id" = "ARM_TENANT_ID",
"subscription_id" = "ARM_SUBSCRIPTION_ID",
"client_id" = "ARM_CLIENT_ID"
})
# recommended to pass in aws secrets using a file() or using environment variables
# the secrets below must be generated in azure by creating an ad application
secrets_json = jsonencode({
"secret_value" = "ARM_CLIENT_SECRET"
})
}
resource "boundary_host_set_plugin" "database" {
name = "My database host set plugin"
host_catalog_id = boundary_host_catalog_plugin.azure_exmaple.id
attributes_json = jsonencode({ "filter" = "tagName eq 'service-type' and tagValue eq 'database'" })
}
resource "boundary_host_set_plugin" "foodev" {
name = "My foodev host set plugin"
host_catalog_id = boundary_host_catalog_plugin.azure_exmaple.id
preferred_endpoints = ["cidr:54.0.0.0/8"]
sync_interval_seconds = 60
attributes_json = jsonencode({
"filter" = "tagName eq 'tag-key' and tagValue eq 'foo'",
"filter" = "tagName eq 'application' and tagValue eq 'dev'",
})
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `host_catalog_id` (String) The catalog for the host set.
### Optional
- `attributes_json` (String) The attributes for the host set. Either values encoded with the "jsonencode" function, pre-escaped JSON string, or a file:// or env:// path. Set to a string "null" or remove the block to clear all attributes in the host set.
- `description` (String) The host set description.
- `name` (String) The host set name. Defaults to the resource name.
- `preferred_endpoints` (List of String) The ordered list of preferred endpoints.
- `sync_interval_seconds` (Number) The value to set for the sync interval seconds.
- `type` (String) The type of host set
### Read-Only
- `id` (String) The ID of the host set.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_host_set_plugin.foo <my-id>
```
+82
View File
@@ -0,0 +1,82 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_host_set_static Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The hostsetstatic resource allows you to configure a Boundary host set. Host sets are always part of a host catalog, so a host catalog resource should be used inline or you should have the host catalog ID in hand to successfully configure a host set.
---
# boundary_host_set_static (Resource)
The host_set_static resource allows you to configure a Boundary host set. Host sets are always part of a host catalog, so a host catalog resource should be used inline or you should have the host catalog ID in hand to successfully configure a host set.
## Example Usage
```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_host_catalog_static" "example" {
scope_id = boundary_scope.project.id
}
resource "boundary_host_static" "first" {
name = "host_1"
description = "My first host!"
address = "10.0.0.1"
host_catalog_id = boundary_host_catalog_static.example.id
}
resource "boundary_host_static" "second" {
name = "host_2"
description = "My second host!"
address = "10.0.0.2"
host_catalog_id = boundary_host_catalog_static.example.id
}
resource "boundary_host_set_static" "web" {
host_catalog_id = boundary_host_catalog_static.example.id
host_ids = [
boundary_host_static.first.id,
boundary_host_static.second.id,
]
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `host_catalog_id` (String) The catalog for the host set.
### Optional
- `description` (String) The host set description.
- `host_ids` (Set of String) The list of host IDs contained in this set.
- `name` (String) The host set name. Defaults to the resource name.
- `type` (String) The type of host set
### Read-Only
- `id` (String) The ID of the host set.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_host_set_static.foo <my-id>
```
+69
View File
@@ -0,0 +1,69 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_host_static Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The static host resource allows you to configure a Boundary static host. Hosts are always part of a project, so a project resource should be used inline or you should have the project ID in hand to successfully configure a host.
---
# boundary_host_static (Resource)
The static host resource allows you to configure a Boundary static host. Hosts are always part of a project, so a project resource should be used inline or you should have the project ID in hand to successfully configure a host.
## Example Usage
```terraform
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_host_catalog_static" "example" {
name = "My catalog"
description = "My first host catalog!"
scope_id = boundary_scope.project.id
}
resource "boundary_host_static" "example" {
name = "example_host"
description = "My first host!"
address = "10.0.0.1"
host_catalog_id = boundary_host_catalog_static.example.id
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `host_catalog_id` (String)
### Optional
- `address` (String) The static address of the host resource as `<IP>` (note: port assignment occurs in the target resource definition, do not add :port here) or a domain name.
- `description` (String) The host description.
- `name` (String) The host name. Defaults to the resource name.
- `type` (String) The type of host
### Read-Only
- `id` (String) The ID of the host.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_host_static.foo <my-id>
```
+32
View File
@@ -0,0 +1,32 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_managed_group Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The managed group resource allows you to configure a Boundary group.
---
# boundary_managed_group (Resource)
The managed group resource allows you to configure a Boundary group.
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `auth_method_id` (String) The resource ID for the auth method.
- `filter` (String) Boolean expression to filter the workers for this managed group.
### Optional
- `description` (String) The managed group description.
- `name` (String) The managed group name. Defaults to the resource name.
### Read-Only
- `id` (String) The ID of the group.
+27 -27
View File
@@ -51,10 +51,10 @@ resource "boundary_user" "bar" {
}
resource "boundary_role" "example" {
name = "My role"
description = "My first role!"
principals = [boundary_user.foo.id, boundary_user.bar.id]
scope_id = boundary_scope.org.id
name = "My role"
description = "My first role!"
principal_ids = [boundary_user.foo.id, boundary_user.bar.id]
scope_id = boundary_scope.org.id
}
```
@@ -76,11 +76,11 @@ resource "boundary_user" "readonly" {
}
resource "boundary_role" "readonly" {
name = "readonly"
description = "A readonly role"
principals = [boundary_user.readonly.id]
grants = ["id=*;action=read"]
scope_id = boundary_scope.org.id
name = "readonly"
description = "A readonly role"
principal_ids = [boundary_user.readonly.id]
grant_strings = ["id=*;type=*;actions=read"]
scope_id = boundary_scope.org.id
}
```
@@ -96,10 +96,10 @@ resource "boundary_scope" "org" {
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_user" "readonly" {
@@ -109,32 +109,32 @@ resource "boundary_user" "readonly" {
}
resource "boundary_role" "readonly" {
name = "readonly"
description = "A readonly role"
principals = [boundary_user.readonly.id]
grants = ["id=*;action=read"]
scope_id = boundary_scope.project.id
name = "readonly"
description = "A readonly role"
principal_ids = [boundary_user.readonly.id]
grant_strings = ["id=*;type=*;actions=read"]
scope_id = boundary_scope.project.id
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **scope_id** (String, Required) The scope ID in which the resource is created. Defaults to the provider's `default_scope` if unset.
- `scope_id` (String) The scope ID in which the resource is created. Defaults to the provider's `default_scope` if unset.
### Optional
- **default_role** (Boolean, Optional) Indicates that the role containing this value is the default role (that is, has the id 'r_default'), which triggers some specialized behavior to allow it to be imported and managed.
- **description** (String, Optional) The role description.
- **grant_scope_id** (String, Optional)
- **grant_strings** (Set of String, Optional) A list of stringified grants for the role.
- **name** (String, Optional) The role name. Defaults to the resource name.
- **principal_ids** (Set of String, Optional) A list of principal (user or group) IDs to add as principals on the role.
- `description` (String) The role description.
- `grant_scope_id` (String)
- `grant_strings` (Set of String) A list of stringified grants for the role.
- `name` (String) The role name. Defaults to the resource name.
- `principal_ids` (Set of String) A list of principal (user or group) IDs to add as principals on the role.
### Read-only
### Read-Only
- **id** (String, Read-only) The ID of the role.
- `id` (String) The ID of the role.
## Import
+9 -8
View File
@@ -60,23 +60,24 @@ resource "boundary_role" "org_admin" {
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **scope_id** (String, Required) The scope ID containing the sub scope resource.
- `scope_id` (String) The scope ID containing the sub scope resource.
### Optional
- **auto_create_admin_role** (Boolean, Optional) If set, when a new scope is created, the provider will not disable the functionality that automatically creates a role in the new scope and gives permissions to manage the scope to the provider's user. Marking this true makes for simpler HCL but results in role resources that are unmanaged by Terraform.
- **auto_create_default_role** (Boolean, Optional) Only relevant when creating an org scope. If set, when a new scope is created, the provider will not disable the functionality that automatically creates a role in the new scope and gives listing of scopes and auth methods and the ability to authenticate to the anonymous user. Marking this true makes for simpler HCL but results in role resources that are unmanaged by Terraform.
- **description** (String, Optional) The scope description.
- **global_scope** (Boolean, Optional) Indicates that the scope containing this value is the global scope, which triggers some specialized behavior to allow it to be imported and managed.
- **name** (String, Optional) The scope name. Defaults to the resource name.
- `auto_create_admin_role` (Boolean) If set, when a new scope is created, the provider will not disable the functionality that automatically creates a role in the new scope and gives permissions to manage the scope to the provider's user. Marking this true makes for simpler HCL but results in role resources that are unmanaged by Terraform.
- `auto_create_default_role` (Boolean) Only relevant when creating an org scope. If set, when a new scope is created, the provider will not disable the functionality that automatically creates a role in the new scope and gives listing of scopes and auth methods and the ability to authenticate to the anonymous user. Marking this true makes for simpler HCL but results in role resources that are unmanaged by Terraform.
- `description` (String) The scope description.
- `global_scope` (Boolean) Indicates that the scope containing this value is the global scope, which triggers some specialized behavior to allow it to be imported and managed.
- `name` (String) The scope name. Defaults to the resource name.
### Read-only
### Read-Only
- **id** (String, Read-only) The ID of the scope.
- `id` (String) The ID of the scope.
## Import
+71 -16
View File
@@ -1,11 +1,12 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_target Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The target resource allows you to configure a Boundary target.
---
# Resource `boundary_target`
# boundary_target (Resource)
The target resource allows you to configure a Boundary target.
@@ -26,10 +27,27 @@ resource "boundary_scope" "org" {
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_vault" "foo" {
name = "vault_store"
description = "My first Vault credential store!"
address = "http://127.0.0.1:8200" # change to Vault address
token = "s.0ufRo6XEGU2jOqnIr7OlFYP5" # change to valid Vault token
scope_id = boundary_scope.project.id
}
resource "boundary_credential_library_vault" "foo" {
name = "foo"
description = "My first Vault credential library!"
credential_store_id = boundary_credential_store_vault.foo.id
path = "my/secret/foo" # change to Vault backend path
http_method = "GET"
credential_type = "username_password"
}
resource "boundary_host_catalog" "foo" {
@@ -40,6 +58,7 @@ resource "boundary_host_catalog" "foo" {
}
resource "boundary_host" "foo" {
type = "static"
name = "foo"
host_catalog_id = boundary_host_catalog.foo.id
scope_id = boundary_scope.project.id
@@ -47,6 +66,7 @@ resource "boundary_host" "foo" {
}
resource "boundary_host" "bar" {
type = "static"
name = "bar"
host_catalog_id = boundary_host_catalog.foo.id
scope_id = boundary_scope.project.id
@@ -54,6 +74,7 @@ resource "boundary_host" "bar" {
}
resource "boundary_host_set" "foo" {
type = "static"
name = "foo"
host_catalog_id = boundary_host_catalog.foo.id
@@ -66,33 +87,67 @@ resource "boundary_host_set" "foo" {
resource "boundary_target" "foo" {
name = "foo"
description = "Foo target"
type = "tcp"
default_port = "22"
scope_id = boundary_scope.project.id
host_set_ids = [
host_source_ids = [
boundary_host_set.foo.id
]
brokered_credential_source_ids = [
boundary_credential_library_vault.foo.id
]
}
resource "boundary_target" "ssh_foo" {
name = "ssh_foo"
description = "Ssh target"
type = "ssh"
default_port = "22"
scope_id = boundary_scope.project.id
host_source_ids = [
boundary_host_set.foo.id
]
injected_application_credential_source_ids = [
boundary_credential_library_vault.foo.id
]
}
resource "boundary_target" "address_foo" {
name = "address_foo"
description = "Foo target with an address"
type = "tcp"
default_port = "22"
scope_id = boundary_scope.project.id
address = "127.0.0.1"
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **scope_id** (String, Required) The scope ID in which the resource is created. Defaults to the provider's `default_scope` if unset.
- **type** (String, Required) The target resource type.
- `scope_id` (String) The scope ID in which the resource is created. Defaults to the provider's `default_scope` if unset.
- `type` (String) The target resource type.
### Optional
- **default_port** (Number, Optional) The default port for this target.
- **description** (String, Optional) The target description.
- **host_set_ids** (Set of String, Optional) A list of host set ID's.
- **name** (String, Optional) The target name. Defaults to the resource name.
- **session_connection_limit** (Number, Optional)
- **session_max_seconds** (Number, Optional)
- `address` (String) Optionally, a valid network address to connect to for this target. Cannot be used alongside host_source_ids.
- `brokered_credential_source_ids` (Set of String) A list of brokered credential source ID's.
- `default_port` (Number) The default port for this target.
- `description` (String) The target description.
- `egress_worker_filter` (String) Boolean expression to filter the workers used to access this target
- `host_source_ids` (Set of String) A list of host source ID's. Cannot be used alongside address.
- `ingress_worker_filter` (String) HCP Only. Boolean expression to filter the workers a user will connect to when initiating a session against this target
- `injected_application_credential_source_ids` (Set of String) A list of injected application credential source ID's.
- `name` (String) The target name. Defaults to the resource name.
- `session_connection_limit` (Number)
- `session_max_seconds` (Number)
- `worker_filter` (String, Deprecated) Boolean expression to filter the workers for this target
### Read-only
### Read-Only
- **id** (String, Read-only) The ID of the target.
- `id` (String) The ID of the target.
## Import
+11 -9
View File
@@ -1,11 +1,12 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_user Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The user resource allows you to configure a Boundary user.
---
# Resource `boundary_user`
# boundary_user (Resource)
The user resource allows you to configure a Boundary user.
@@ -25,7 +26,7 @@ resource "boundary_auth_method" "password" {
type = "password"
}
resource "boundary_account" "jeff" {
resource "boundary_account_password" "jeff" {
auth_method_id = boundary_auth_method.password.id
type = "password"
login_name = "jeff"
@@ -35,26 +36,27 @@ resource "boundary_account" "jeff" {
resource "boundary_user" "jeff" {
name = "jeff"
description = "Jeff's user resource"
account_ids = [boundary_account.jeff.id]
account_ids = [boundary_account_password.jeff.id]
scope_id = boundary_scope.org.id
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **scope_id** (String, Required) The scope ID in which the resource is created. Defaults to the provider's `default_scope` if unset.
- `scope_id` (String) The scope ID in which the resource is created. Defaults to the provider's `default_scope` if unset.
### Optional
- **account_ids** (Set of String, Optional) Account ID's to associate with this user resource.
- **description** (String, Optional) The user description.
- **name** (String, Optional) The username. Defaults to the resource name.
- `account_ids` (Set of String) Account ID's to associate with this user resource.
- `description` (String) The user description.
- `name` (String) The username. Defaults to the resource name.
### Read-only
### Read-Only
- **id** (String, Read-only) The ID of the user.
- `id` (String) The ID of the user.
## Import
+39
View File
@@ -0,0 +1,39 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "boundary_worker Resource - terraform-provider-boundary"
subcategory: ""
description: |-
The resource allows you to create a self-managed worker object.
---
# boundary_worker (Resource)
The resource allows you to create a self-managed worker object.
<!-- schema generated by tfplugindocs -->
## Schema
### Optional
- `description` (String) The description for the worker.
- `name` (String) The name for the worker.
- `scope_id` (String) The scope for the worker. Defaults to `global`.
- `worker_generated_auth_token` (String) The worker authentication token required to register the worker for the worker-led authentication flow. Leaving this blank will result in a controller generated token.
### Read-Only
- `address` (String) The accessible address of the self managed worker.
- `authorized_actions` (List of String) A list of actions that the worker is entitled to perform.
- `controller_generated_activation_token` (String) A single use token generated by the controller to be passed to the self-managed worker.
- `id` (String) The ID of the worker.
- `release_version` (Number) The version of the Boundary binary running on the self managed worker.
## Import
Import is supported using the following syntax:
```shell
terraform import boundary_worker.foo <my-id>
```
@@ -1 +0,0 @@
terraform import boundary_account.foo <my-id>
@@ -0,0 +1 @@
terraform import boundary_account_password.foo <my-id>
@@ -11,7 +11,7 @@ resource "boundary_auth_method" "password" {
type = "password"
}
resource "boundary_account" "jeff" {
resource "boundary_account_password" "jeff" {
auth_method_id = boundary_auth_method.password.id
type = "password"
login_name = "jeff"
@@ -0,0 +1 @@
terraform import boundary_credential_json.example_json <my-id>
@@ -0,0 +1,27 @@
resource "boundary_scope" "org" {
name = "organization_one"
description = "global scope"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_static" "example" {
name = "example_static_credential_store"
description = "My first static credential store!"
scope_id = boundary_scope.project.id
}
resource "boundary_credential_json" "example" {
name = "example_json"
description = "My first json credential!"
credential_store_id = boundary_credential_store_static.example.id
object = file("~/object.json") # change to valid json file
}
@@ -0,0 +1 @@
terraform import boundary_credential_library_vault.foo <my-id>
@@ -0,0 +1,70 @@
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_vault" "foo" {
name = "foo"
description = "My first Vault credential store!"
address = "http://127.0.0.1:8200" # change to Vault address
token = "s.0ufRo6XEGU2jOqnIr7OlFYP5" # change to valid Vault token
scope_id = boundary_scope.project.id
}
resource "boundary_credential_library_vault" "foo" {
name = "foo"
description = "My first Vault credential library!"
credential_store_id = boundary_credential_store_vault.foo.id
path = "my/secret/foo" # change to Vault backend path
http_method = "GET"
}
resource "boundary_credential_library_vault" "bar" {
name = "bar"
description = "My second Vault credential library!"
credential_store_id = boundary_credential_store_vault.foo.id
path = "my/secret/bar" # change to Vault backend path
http_method = "POST"
http_request_body = <<EOT
{
"key": "Value",
}
EOT
}
resource "boundary_credential_library_vault" "baz" {
name = "baz"
description = "vault username password credential with mapping overrides"
credential_store_id = boundary_credential_store_vault.foo.id
path = "my/secret/baz" # change to Vault backend path
http_method = "GET"
credential_type = "username_password"
credential_mapping_overrides = {
password_attribute = "alternative_password_label"
username_attribute = "alternative_username_label"
}
}
resource "boundary_credential_library_vault" "quz" {
name = "quz"
description = "vault ssh private key credential with mapping overrides"
credential_store_id = boundary_credential_store_vault.foo.id
path = "my/secret/quz" # change to Vault backend path
http_method = "GET"
credential_type = "ssh_private_key"
credential_mapping_overrides = {
private_key_attribute = "alternative_key_label"
private_key_passphrase_attribute = "alternative_passphrase_label"
username_attribute = "alternative_username_label"
}
}
@@ -0,0 +1 @@
terraform import boundary_credential_library_vault_ssh_certificate.foo <my-id>
@@ -0,0 +1,63 @@
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_vault" "foo" {
name = "foo"
description = "My first Vault credential store!"
address = "http://127.0.0.1:8200" # change to Vault address
token = "s.0ufRo6XEGU2jOqnIr7OlFYP5" # change to valid Vault token
scope_id = boundary_scope.project.id
}
resource "boundary_credential_library_vault_ssh_certificate" "foo" {
name = "foo"
description = "My first Vault SSH certificate credential library!"
credential_store_id = boundary_credential_store_vault.foo.id
path = "ssh/sign/foo" # change to correct Vault endpoint and role
username = "foo" # change to valid username
}
resource "boundary_credential_library_vault_ssh_certificate" "bar" {
name = "bar"
description = "My second Vault SSH certificate credential library!"
credential_store_id = boundary_credential_store_vault.foo.id
path = "ssh/sign/foo" # change to correct Vault endpoint and role
username = "foo"
key_type = "ecdsa"
key_bits = 384
extensions = {
permit-pty = ""
}
}
resource "boundary_credential_library_vault_ssh_certificate" "baz" {
name = "baz"
description = "vault "
credential_store_id = boundary_credential_store_vault.foo.id
path = "ssh/issue/foo" # change to correct Vault endpoint and role
username = "foo"
key_type = "rsa"
key_bits = 4096
extensions = {
permit-pty = ""
permit-X11-forwarding = ""
}
critical_options = {
force-command = "/bin/some_script"
}
}
@@ -0,0 +1 @@
terraform import boundary_credential_ssh_private_key.example_ssh_private_key <my-id>
@@ -0,0 +1,29 @@
resource "boundary_scope" "org" {
name = "organization_one"
description = "global scope"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_static" "example" {
name = "example_static_credential_store"
description = "My first static credential store!"
scope_id = boundary_scope.project.id
}
resource "boundary_credential_ssh_private_key" "example" {
name = "example_ssh_private_key"
description = "My first ssh private key credential!"
credential_store_id = boundary_credential_store_static.example.id
username = "my-username"
private_key = file("~/.ssh/id_rsa") # change to valid SSH Private Key
private_key_passphrase = "optional-passphrase" # change to the passphrase of the Private Key if required
}
@@ -0,0 +1 @@
terraform import boundary_credential_store_static.example_static_credential_store <my-id>
@@ -0,0 +1,20 @@
resource "boundary_scope" "org" {
name = "organization_one"
description = "global scope"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_static" "example" {
name = "example_static_credential_store"
description = "My first static credential store!"
scope_id = boundary_scope.project.id
}
@@ -0,0 +1 @@
terraform import boundary_credential_store_vault.foo <my-id>
@@ -0,0 +1,22 @@
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_vault" "example" {
name = "foo"
description = "My first Vault credential store!"
address = "http://127.0.0.1:8200" # change to Vault address
token = "s.0ufRo6XEGU2jOqnIr7OlFYP5" # change to valid Vault token
scope_id = boundary_scope.project.id
}
@@ -0,0 +1 @@
terraform import boundary_credential_username_password.example_username_password <my-id>
@@ -0,0 +1,28 @@
resource "boundary_scope" "org" {
name = "organization_one"
description = "global scope"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_static" "example" {
name = "example_static_credential_store"
description = "My first static credential store!"
scope_id = boundary_scope.project.id
}
resource "boundary_credential_username_password" "example" {
name = "example_username_password"
description = "My first username password credential!"
credential_store_id = boundary_credential_store_static.example.id
username = "my-username"
password = "my-password"
}
@@ -7,10 +7,10 @@ resource "boundary_scope" "org" {
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_user" "foo" {
+16 -8
View File
@@ -7,15 +7,23 @@ resource "boundary_scope" "org" {
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_host_catalog" "static" {
name = "My catalog"
description = "My first host catalog!"
type = "static"
scope_id = boundary_scope.project.id
}
resource "boundary_host" "example" {
name = "example_host"
description = "My first host!"
address = "10.0.0.1"
scope_id = boundary_scope.project.id
type = "static"
name = "example_host"
description = "My first host!"
address = "10.0.0.1"
host_catalog_id = boundary_host_catalog.static.id
}
@@ -7,10 +7,10 @@ resource "boundary_scope" "org" {
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_host_catalog" "example" {
@@ -0,0 +1 @@
terraform import boundary_host_catalog_plugin.foo <my-id>
@@ -0,0 +1,60 @@
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = boundary_scope.global.id
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
# For more information about the aws plugin, please visit here:
# https://github.com/hashicorp/boundary-plugin-host-aws
#
# For more information about aws users, please visit here:
# https://learn.hashicorp.com/tutorials/boundary/aws-host-catalogs?in=boundary/oss-access-management#configure-terraform-and-iam-user-privileges
resource "boundary_host_catalog_plugin" "aws_example" {
name = "My aws catalog"
description = "My first host catalog!"
scope_id = boundary_scope.project.id
plugin_name = "aws"
attributes_json = jsonencode({ "region" = "us-east-1" })
# recommended to pass in aws secrets using a file() or using environment variables
# the secrets below must be generated in aws by creating a aws iam user with programmatic access
secrets_json = jsonencode({
"access_key_id" = "aws_access_key_id_value",
"secret_access_key" = "aws_secret_access_key_value"
})
}
# For more information about the azure plugin, please visit here:
# https://github.com/hashicorp/boundary-plugin-host-azure
#
# For more information about azure ad applications, please visit here:
# https://learn.hashicorp.com/tutorials/boundary/azure-host-catalogs#register-a-new-azure-ad-application-1
resource "boundary_host_catalog_plugin" "azure_example" {
name = "My azure catalog"
description = "My second host catalog!"
scope_id = boundary_scope.project.id
plugin_name = "azure"
# the attributes below must be generated in azure by creating an ad application
attributes_json = jsonencode({
"disable_credential_rotation" = "true",
"tenant_id" = "ARM_TENANT_ID",
"subscription_id" = "ARM_SUBSCRIPTION_ID",
"client_id" = "ARM_CLIENT_ID"
})
# recommended to pass in aws secrets using a file() or using environment variables
# the secrets below must be generated in azure by creating an ad application
secrets_json = jsonencode({
"secret_value" = "ARM_CLIENT_SECRET"
})
}
@@ -0,0 +1 @@
terraform import boundary_host_catalog_static.foo <my-id>
@@ -0,0 +1,20 @@
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = boundary_scope.global.id
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_host_catalog_static" "example" {
name = "My catalog"
description = "My first host catalog!"
scope_id = boundary_scope.project.id
}
@@ -7,17 +7,19 @@ resource "boundary_scope" "org" {
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_host_catalog" "static" {
type = "static"
scope_id = boundary_scope.project.id
}
resource "boundary_host" "1" {
resource "boundary_host" "first" {
type = "static"
name = "host_1"
description = "My first host!"
address = "10.0.0.1"
@@ -25,7 +27,8 @@ resource "boundary_host" "1" {
scope_id = boundary_scope.project.id
}
resource "boundary_host" "2" {
resource "boundary_host" "second" {
type = "static"
name = "host_2"
description = "My second host!"
address = "10.0.0.2"
@@ -35,8 +38,9 @@ resource "boundary_host" "2" {
resource "boundary_host_set" "web" {
host_catalog_id = boundary_host_catalog.static.id
type = "static"
host_ids = [
boundary_host.1.id,
boundary_host.2.id,
boundary_host.first.id,
boundary_host.second.id,
]
}
@@ -0,0 +1 @@
terraform import boundary_host_set_plugin.foo <my-id>
@@ -0,0 +1,103 @@
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
# For more information about the aws plugin, please visit here:
# https://github.com/hashicorp/boundary-plugin-host-aws
#
# For more information about aws users, please visit here:
# https://learn.hashicorp.com/tutorials/boundary/aws-host-catalogs?in=boundary/oss-access-management#configure-terraform-and-iam-user-privileges
resource "boundary_host_catalog_plugin" "aws_example" {
name = "My aws catalog"
description = "My first host catalog!"
scope_id = boundary_scope.project.id
plugin_name = "aws"
attributes_json = jsonencode({ "region" = "us-east-1" })
# recommended to pass in aws secrets using a file() or using environment variables
# the secrets below must be generated in aws by creating a aws iam user with programmatic access
secrets_json = jsonencode({
"access_key_id" = "aws_access_key_id_value",
"secret_access_key" = "aws_secret_access_key_value"
})
}
resource "boundary_host_set_plugin" "web" {
name = "My web host set plugin"
host_catalog_id = boundary_host_catalog_plugin.aws_exmaple.id
attributes_json = jsonencode({ "filters" = "tag:service-type=web" })
}
resource "boundary_host_set_plugin" "foobar" {
name = "My foobar host set plugin"
host_catalog_id = boundary_host_catalog_plugin.aws_exmaple.id
preferred_endpoints = ["cidr:54.0.0.0/8"]
attributes_json = jsonencode({
"filters" = "tag-key=foo",
"filters" = "tag-key=bar"
})
}
resource "boundary_host_set_plugin" "launch" {
name = "My launch host set plugin"
host_catalog_id = boundary_host_catalog_plugin.aws_exmaple.id
sync_interval_seconds = 60
attributes_json = jsonencode({
"filters" = "tag:development=prod,dev",
"filters" = "launch-time=2022-01-04T*"
})
}
# For more information about the azure plugin, please visit here:
# https://github.com/hashicorp/boundary-plugin-host-azure
#
# For more information about azure ad applications, please visit here:
# https://learn.hashicorp.com/tutorials/boundary/azure-host-catalogs#register-a-new-azure-ad-application-1
resource "boundary_host_catalog_plugin" "azure_example" {
name = "My azure catalog"
description = "My second host catalog!"
scope_id = boundary_scope.project.id
plugin_name = "azure"
# the attributes below must be generated in azure by creating an ad application
attributes_json = jsonencode({
"disable_credential_rotation" = "true",
"tenant_id" = "ARM_TENANT_ID",
"subscription_id" = "ARM_SUBSCRIPTION_ID",
"client_id" = "ARM_CLIENT_ID"
})
# recommended to pass in aws secrets using a file() or using environment variables
# the secrets below must be generated in azure by creating an ad application
secrets_json = jsonencode({
"secret_value" = "ARM_CLIENT_SECRET"
})
}
resource "boundary_host_set_plugin" "database" {
name = "My database host set plugin"
host_catalog_id = boundary_host_catalog_plugin.azure_exmaple.id
attributes_json = jsonencode({ "filter" = "tagName eq 'service-type' and tagValue eq 'database'" })
}
resource "boundary_host_set_plugin" "foodev" {
name = "My foodev host set plugin"
host_catalog_id = boundary_host_catalog_plugin.azure_exmaple.id
preferred_endpoints = ["cidr:54.0.0.0/8"]
sync_interval_seconds = 60
attributes_json = jsonencode({
"filter" = "tagName eq 'tag-key' and tagValue eq 'foo'",
"filter" = "tagName eq 'application' and tagValue eq 'dev'",
})
}
@@ -0,0 +1 @@
terraform import boundary_host_set_static.foo <my-id>
@@ -0,0 +1,40 @@
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_host_catalog_static" "example" {
scope_id = boundary_scope.project.id
}
resource "boundary_host_static" "first" {
name = "host_1"
description = "My first host!"
address = "10.0.0.1"
host_catalog_id = boundary_host_catalog_static.example.id
}
resource "boundary_host_static" "second" {
name = "host_2"
description = "My second host!"
address = "10.0.0.2"
host_catalog_id = boundary_host_catalog_static.example.id
}
resource "boundary_host_set_static" "web" {
host_catalog_id = boundary_host_catalog_static.example.id
host_ids = [
boundary_host_static.first.id,
boundary_host_static.second.id,
]
}
@@ -0,0 +1 @@
terraform import boundary_host_static.foo <my-id>
@@ -0,0 +1,27 @@
resource "boundary_scope" "org" {
name = "organization_one"
description = "My first scope!"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_host_catalog_static" "example" {
name = "My catalog"
description = "My first host catalog!"
scope_id = boundary_scope.project.id
}
resource "boundary_host_static" "example" {
name = "example_host"
description = "My first host!"
address = "10.0.0.1"
host_catalog_id = boundary_host_catalog_static.example.id
}
@@ -7,10 +7,10 @@ resource "boundary_scope" "org" {
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_user" "readonly" {
@@ -20,9 +20,9 @@ resource "boundary_user" "readonly" {
}
resource "boundary_role" "readonly" {
name = "readonly"
description = "A readonly role"
principals = [boundary_user.readonly.id]
grants = ["id=*;action=read"]
scope_id = boundary_scope.project.id
name = "readonly"
description = "A readonly role"
principal_ids = [boundary_user.readonly.id]
grant_strings = ["id=*;type=*;actions=read"]
scope_id = boundary_scope.project.id
}
@@ -13,9 +13,9 @@ resource "boundary_user" "readonly" {
}
resource "boundary_role" "readonly" {
name = "readonly"
description = "A readonly role"
principals = [boundary_user.readonly.id]
grants = ["id=*;action=read"]
scope_id = boundary_scope.org.id
name = "readonly"
description = "A readonly role"
principal_ids = [boundary_user.readonly.id]
grant_strings = ["id=*;type=*;actions=read"]
scope_id = boundary_scope.org.id
}
@@ -17,8 +17,8 @@ resource "boundary_user" "bar" {
}
resource "boundary_role" "example" {
name = "My role"
description = "My first role!"
principals = [boundary_user.foo.id, boundary_user.bar.id]
scope_id = boundary_scope.org.id
name = "My role"
description = "My first role!"
principal_ids = [boundary_user.foo.id, boundary_user.bar.id]
scope_id = boundary_scope.org.id
}
+52 -5
View File
@@ -12,10 +12,27 @@ resource "boundary_scope" "org" {
}
resource "boundary_scope" "project" {
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
name = "project_one"
description = "My first scope!"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}
resource "boundary_credential_store_vault" "foo" {
name = "vault_store"
description = "My first Vault credential store!"
address = "http://127.0.0.1:8200" # change to Vault address
token = "s.0ufRo6XEGU2jOqnIr7OlFYP5" # change to valid Vault token
scope_id = boundary_scope.project.id
}
resource "boundary_credential_library_vault" "foo" {
name = "foo"
description = "My first Vault credential library!"
credential_store_id = boundary_credential_store_vault.foo.id
path = "my/secret/foo" # change to Vault backend path
http_method = "GET"
credential_type = "username_password"
}
resource "boundary_host_catalog" "foo" {
@@ -26,6 +43,7 @@ resource "boundary_host_catalog" "foo" {
}
resource "boundary_host" "foo" {
type = "static"
name = "foo"
host_catalog_id = boundary_host_catalog.foo.id
scope_id = boundary_scope.project.id
@@ -33,6 +51,7 @@ resource "boundary_host" "foo" {
}
resource "boundary_host" "bar" {
type = "static"
name = "bar"
host_catalog_id = boundary_host_catalog.foo.id
scope_id = boundary_scope.project.id
@@ -40,6 +59,7 @@ resource "boundary_host" "bar" {
}
resource "boundary_host_set" "foo" {
type = "static"
name = "foo"
host_catalog_id = boundary_host_catalog.foo.id
@@ -52,9 +72,36 @@ resource "boundary_host_set" "foo" {
resource "boundary_target" "foo" {
name = "foo"
description = "Foo target"
type = "tcp"
default_port = "22"
scope_id = boundary_scope.project.id
host_set_ids = [
host_source_ids = [
boundary_host_set.foo.id
]
brokered_credential_source_ids = [
boundary_credential_library_vault.foo.id
]
}
resource "boundary_target" "ssh_foo" {
name = "ssh_foo"
description = "Ssh target"
type = "ssh"
default_port = "22"
scope_id = boundary_scope.project.id
host_source_ids = [
boundary_host_set.foo.id
]
injected_application_credential_source_ids = [
boundary_credential_library_vault.foo.id
]
}
resource "boundary_target" "address_foo" {
name = "address_foo"
description = "Foo target with an address"
type = "tcp"
default_port = "22"
scope_id = boundary_scope.project.id
address = "127.0.0.1"
}
+2 -2
View File
@@ -11,7 +11,7 @@ resource "boundary_auth_method" "password" {
type = "password"
}
resource "boundary_account" "jeff" {
resource "boundary_account_password" "jeff" {
auth_method_id = boundary_auth_method.password.id
type = "password"
login_name = "jeff"
@@ -21,6 +21,6 @@ resource "boundary_account" "jeff" {
resource "boundary_user" "jeff" {
name = "jeff"
description = "Jeff's user resource"
account_ids = [boundary_account.jeff.id]
account_ids = [boundary_account_password.jeff.id]
scope_id = boundary_scope.org.id
}
@@ -0,0 +1 @@
terraform import boundary_worker.foo <my-id>
@@ -0,0 +1,13 @@
resource "boundary_worker" "controller_led" {
scope_id = "global"
name = "worker 1"
description = "self managed worker with controlled led auth"
worker_generated_auth_token = var.worker_generated_auth_token
}
resource "boundary_self_managed_worker" "worker_led" {
scope_id = "global"
name = "worker 2"
description = "self managed worker with controlled led auth"
worker_generated_auth_token = var.worker_generated_auth_token
}
+180 -33
View File
@@ -1,39 +1,186 @@
module github.com/hashicorp/terraform-provider-boundary
go 1.15
go 1.19
require (
cloud.google.com/go v0.68.0 // indirect
cloud.google.com/go/storage v1.11.0 // indirect
github.com/Azure/azure-sdk-for-go v46.4.0+incompatible // indirect
github.com/Azure/go-autorest/autorest/azure/auth v0.5.3 // indirect
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
github.com/Azure/go-autorest/autorest/validation v0.3.0 // indirect
github.com/DataDog/datadog-go v4.0.0+incompatible // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.61.545 // indirect
github.com/aws/aws-sdk-go v1.35.4 // indirect
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
github.com/circonus-labs/circonusllhist v0.1.4 // indirect
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe // indirect
github.com/golang/snappy v0.0.2 // indirect
github.com/hashicorp/boundary v0.1.4
github.com/hashicorp/boundary/api v0.0.3
github.com/hashicorp/boundary/sdk v0.0.1
github.com/hashicorp/go-immutable-radix v1.3.0 // indirect
github.com/hashicorp/go-kms-wrapping v0.5.16
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/hcl/v2 v2.6.0 // indirect
github.com/hashicorp/terraform-plugin-docs v0.2.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.0.5-0.20201016174159-3a1c6c51f716
github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect
github.com/hashicorp/boundary v0.12.0
github.com/hashicorp/boundary/api v0.0.34
github.com/hashicorp/boundary/sdk v0.0.30
github.com/hashicorp/cap v0.2.0
github.com/hashicorp/go-cty v1.4.1-0.20200723130312-85980079f637
github.com/hashicorp/go-kms-wrapping/v2 v2.0.6-0.20221122211539-47c893099f13
github.com/hashicorp/go-secure-stdlib/configutil/v2 v2.0.7
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7
github.com/hashicorp/go-secure-stdlib/pluginutil/v2 v2.0.3
github.com/hashicorp/terraform-plugin-docs v0.13.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1
github.com/kr/pretty v0.3.1
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/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c // indirect
github.com/zclconf/go-cty v1.6.1 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
github.com/stretchr/testify v1.8.1
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
)
require (
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/DATA-DOG/go-sqlmock v1.5.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.1.1 // indirect
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
github.com/Microsoft/go-winio v0.5.0 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/agext/levenshtein v1.2.2 // indirect
github.com/alessio/shellescape v1.4.1 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/armon/go-metrics v0.3.9 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/cenkalti/backoff/v3 v3.0.0 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/containerd/continuity v0.1.0 // indirect
github.com/coreos/go-oidc/v3 v3.1.0 // indirect
github.com/danieljoos/wincred v1.1.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/cli v20.10.7+incompatible // indirect
github.com/docker/docker v20.10.9+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/dvsekhvalnov/jose2go v1.5.0 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/godbus/dbus/v5 v5.0.6 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-migrate/migrate/v4 v4.15.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.2 // indirect
github.com/hashicorp/dbassert v0.0.0-20210708202608-ecf920cf1ed8 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/eventlogger v0.1.1-0.20211106154408-4ff8da3a890c // indirect
github.com/hashicorp/eventlogger/filters/encrypt v0.1.7 // indirect
github.com/hashicorp/go-bexpr v0.1.10 // indirect
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-dbw v0.0.0-20220910135738-ed4505749995 // indirect
github.com/hashicorp/go-hclog v1.2.2 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-kms-wrapping/extras/kms/v2 v2.0.0-20221122211539-47c893099f13 // indirect
github.com/hashicorp/go-kms-wrapping/plugin/v2 v2.0.3 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-plugin v1.4.6 // indirect
github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-secure-stdlib/base62 v0.1.2 // indirect
github.com/hashicorp/go-secure-stdlib/gatedwriter v0.1.1 // indirect
github.com/hashicorp/go-secure-stdlib/kv-builder v0.1.1 // indirect
github.com/hashicorp/go-secure-stdlib/listenerutil v0.1.5-0.20221130175209-f7789ac19a1f // indirect
github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 // indirect
github.com/hashicorp/go-secure-stdlib/reloadutil v0.1.1 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1 // indirect
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/hc-install v0.4.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/hcl/v2 v2.15.0 // indirect
github.com/hashicorp/logutils v1.0.0 // indirect
github.com/hashicorp/nodeenrollment v0.1.18 // indirect
github.com/hashicorp/terraform-exec v0.17.3 // indirect
github.com/hashicorp/terraform-json v0.14.0 // indirect
github.com/hashicorp/terraform-plugin-go v0.14.1 // indirect
github.com/hashicorp/terraform-plugin-log v0.7.0 // indirect
github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c // indirect
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 // indirect
github.com/hashicorp/vault/api v1.3.1 // indirect
github.com/hashicorp/vault/sdk v0.3.0 // indirect
github.com/hashicorp/yamux v0.1.0 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.12.1 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
github.com/jackc/pgtype v1.11.0 // indirect
github.com/jackc/pgx/v4 v4.16.1 // indirect
github.com/jefferai/go-libsecret v0.0.0-20210525195240-b53481abef97 // indirect
github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f // indirect
github.com/jefferai/keyring v1.1.7-0.20220316160357-58a74bb55891 // indirect
github.com/jinzhu/gorm v1.9.12 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lib/pq v1.10.2 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a // indirect
github.com/mitchellh/cli v1.1.4 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/pointerstructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/mtibben/percent v0.2.1 // indirect
github.com/oklog/run v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/opencontainers/runc v1.0.2 // indirect
github.com/ory/dockertest/v3 v3.7.0 // indirect
github.com/pierrec/lz4 v2.5.2+incompatible // indirect
github.com/pires/go-proxyproto v0.6.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/posener/complete v1.2.3 // indirect
github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/russross/blackfriday v1.6.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/sethvargo/go-diceware v0.3.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
github.com/vmihailenco/tagparser v0.1.1 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xo/dburl v0.11.0 // indirect
github.com/zalando/go-keyring v0.2.1 // indirect
github.com/zclconf/go-cty v1.12.1 // indirect
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/exp v0.0.0-20220921164117-439092de6870 // indirect
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
golang.org/x/oauth2 v0.0.0-20220722155238-128564f6959c // indirect
golang.org/x/sys v0.2.0 // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220805133916-01dd62135a58 // indirect
google.golang.org/grpc v1.50.1 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/driver/postgres v1.3.8 // indirect
gorm.io/driver/sqlite v1.3.6 // indirect
gorm.io/gorm v1.23.8 // indirect
)
+997 -679
View File
File diff suppressed because it is too large. Load diff
+36 -7
View File
@@ -1,18 +1,47 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
const (
// Key used for common SDK ID resource attribute
// IDKey is used for common SDK ID resource attribute
IDKey = "id"
// Key used for common "name" resource attribute
// NameKey is used for common "name" resource attribute
NameKey = "name"
// Key used for common "description" resource attribute
// DescriptionKey is used for common "description" resource attribute
DescriptionKey = "description"
// Key used for common "scope_id" resource attribute
// ScopeIdKey is used for common "scope_id" resource attribute
ScopeIdKey = "scope_id"
// Key used for common "type" resource attribute
// TypeKey is used for common "type" resource attribute
TypeKey = "type"
// Key used for common "host_catalog_id" resource attribute
// HostCatalogIdKey is used for common "host_catalog_id" resource attribute
HostCatalogIdKey = "host_catalog_id"
// Key used for common "auth_method_id" resource attribute
// AuthMethodIdKey is used for common "auth_method_id" resource attribute
AuthMethodIdKey = "auth_method_id"
// PluginIdKey is used for common "plugin_id" resource attribute
PluginIdKey = "plugin_id"
// PluginNameKey is used for common "plugin_name" resource attribute
PluginNameKey = "plugin_name"
// AttributesJsonKey is used for setting attributes and corresponds to the
// API "attributes" key
AttributesJsonKey = "attributes_json"
// SecretsJsonKey is used for setting secrets and corresponds to the API
// "secrets" key
SecretsJsonKey = "secrets_json"
// SecretsHmacKey is a read-only key used for ensuring we detect if secrets
// have changed
SecretsHmacKey = "secrets_hmac"
// PreferredEndpointsKey is used for setting preferred endpoints
PreferredEndpointsKey = "preferred_endpoints"
// SyncIntervalSecondsKey is used for setting the interval seconds
SyncIntervalSecondsKey = "sync_interval_seconds"
// internalSecretsConfigHmacKey is used for storing an hmac of hmac from server +
// config string
internalSecretsConfigHmacKey = "internal_secrets_config_hmac"
// internalHmacUsedForSecretsConfigHmacKey is used for storing the server-provided
// hmac used when calculating the current value of secretsConfigHmacKey
internalHmacUsedForSecretsConfigHmacKey = "internal_hmac_used_for_secrets_config_hmac"
// internalForceUpdateKey is used to force updates so we can always check
// the value of secrets
internalForceUpdateKey = "internal_force_update"
)
+3
View File
@@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// Helpers for dealing with file paths and their contents
//
// Originally from Terraform; see
+83 -19
View File
@@ -1,17 +1,24 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
"context"
"errors"
"fmt"
"net/http"
"strings"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/authmethods"
"github.com/hashicorp/boundary/sdk/wrapper"
wrapping "github.com/hashicorp/go-kms-wrapping"
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
"github.com/hashicorp/go-secure-stdlib/configutil/v2"
"github.com/hashicorp/go-secure-stdlib/pluginutil/v2"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
kms_plugin_assets "github.com/hashicorp/terraform-provider-boundary/plugins/kms"
)
func init() {
@@ -25,7 +32,7 @@ func New() *schema.Provider {
"addr": {
Type: schema.TypeString,
Required: true,
Description: `The base url of the Boundary API, e.g. "http://127.0.0.1". If not set, it will be read from the "BOUNDARY_ADDR" env var.`,
Description: `The base url of the Boundary API, e.g. "http://127.0.0.1:9200". If not set, it will be read from the "BOUNDARY_ADDR" env var.`,
},
"token": {
Type: schema.TypeString,
@@ -52,18 +59,46 @@ func New() *schema.Provider {
Optional: true,
Description: "The auth method password for password-style auth methods",
},
"tls_insecure": {
Type: schema.TypeBool,
Optional: true,
Description: "When set to true, does not validate the Boundary API endpoint certificate",
},
"plugin_execution_dir": {
Type: schema.TypeString,
Optional: true,
Description: `Specifies a directory that the Boundary provider can use to write and execute its built-in plugins.`,
},
},
ResourcesMap: map[string]*schema.Resource{
"boundary_account": resourceAccount(),
"boundary_auth_method": resourceAuthMethod(),
"boundary_group": resourceGroup(),
"boundary_host": resourceHost(),
"boundary_host_catalog": resourceHostCatalog(),
"boundary_host_set": resourceHostset(),
"boundary_role": resourceRole(),
"boundary_scope": resourceScope(),
"boundary_target": resourceTarget(),
"boundary_user": resourceUser(),
"boundary_account": resourceAccount(),
"boundary_account_password": resourceAccountPassword(),
"boundary_account_oidc": resourceAccountOidc(),
"boundary_auth_method": resourceAuthMethod(),
"boundary_auth_method_password": resourceAuthMethodPassword(),
"boundary_auth_method_oidc": resourceAuthMethodOidc(),
"boundary_credential_library_vault": resourceCredentialLibraryVault(),
"boundary_credential_library_vault_ssh_certificate": resourceCredentialLibraryVaultSshCertificate(),
"boundary_credential_store_vault": resourceCredentialStoreVault(),
"boundary_credential_store_static": resourceCredentialStoreStatic(),
"boundary_credential_username_password": resourceCredentialUsernamePassword(),
"boundary_credential_ssh_private_key": resourceCredentialSshPrivateKey(),
"boundary_credential_json": resourceCredentialJson(),
"boundary_managed_group": resourceManagedGroup(),
"boundary_group": resourceGroup(),
"boundary_host": resourceHost(),
"boundary_host_static": resourceHostStatic(),
"boundary_host_catalog": resourceHostCatalog(),
"boundary_host_catalog_static": resourceHostCatalogStatic(),
"boundary_host_catalog_plugin": resourceHostCatalogPlugin(),
"boundary_host_set": resourceHostSet(),
"boundary_host_set_static": resourceHostSetStatic(),
"boundary_host_set_plugin": resourceHostSetPlugin(),
"boundary_role": resourceRole(),
"boundary_scope": resourceScope(),
"boundary_target": resourceTarget(),
"boundary_user": resourceUser(),
"boundary_worker": resourceWorker(),
},
}
@@ -92,16 +127,28 @@ func providerAuthenticate(ctx context.Context, d *schema.ResourceData, md *metaD
if err != nil {
return fmt.Errorf(`error reading data from "recovery_kms_hcl": %v`, err)
}
wrapper, err := wrapper.GetWrapperFromHcl(recoveryHclStr, "recovery")
opts := []pluginutil.Option{
pluginutil.WithPluginsMap(kms_plugin_assets.BuiltinKmsPlugins()),
pluginutil.WithPluginsFilesystem(kms_plugin_assets.KmsPluginPrefix, kms_plugin_assets.FileSystem()),
}
if execDir, ok := d.GetOk("plugin_execution_dir"); ok {
opts = append(opts, pluginutil.WithPluginExecutionDirectory(execDir.(string)))
}
// TODO: cleanup plugin when finished
wrapper, _, err := wrapper.GetWrapperFromHcl(
ctx,
recoveryHclStr,
"recovery",
configutil.WithPluginOptions(opts...))
if err != nil {
return fmt.Errorf(`error reading wrappers from "recovery_kms_hcl": %v`, err)
}
if wrapper == nil {
return errors.New(`No "kms" block with purpose "recovery" found in "recovery_kms_hcl"`)
}
if err := wrapper.Init(ctx); err != nil {
return fmt.Errorf("error initializing recovery kms: %v", err)
}
md.recoveryKmsWrapper = wrapper
md.client.SetRecoveryKmsWrapper(wrapper)
@@ -133,11 +180,20 @@ func providerAuthenticate(ctx context.Context, d *schema.ResourceData, md *metaD
am := authmethods.NewClient(md.client)
at, err := am.Authenticate(ctx, authMethodId.(string), credentials)
at, err := am.Authenticate(ctx, authMethodId.(string), "login", credentials)
if err != nil {
if apiErr := api.AsServerError(err); apiErr != nil {
statusCode := apiErr.Response().StatusCode()
if statusCode == http.StatusNotFound {
return fmt.Errorf("unknown auth_method_id: %s", err.Error())
}
if statusCode == http.StatusUnauthorized {
return fmt.Errorf("invalid login name or password: %s", err.Error())
}
}
return err
}
md.client.SetToken(at.Item.Token)
md.client.SetToken(at.Attributes["token"].(string))
default:
return errors.New("no suitable auth method information found")
@@ -154,12 +210,20 @@ func providerConfigure(p *schema.Provider) schema.ConfigureContextFunc {
}
if url, ok := d.GetOk("addr"); ok {
client.SetAddr(url.(string))
if err := client.SetAddr(url.(string)); err != nil {
return nil, diag.FromErr(err)
}
}
if client.Addr() == "" {
return nil, diag.Errorf(`"no valid address could be determined from "addr" or "BOUNDARY_ADDR" env var`)
}
if tlsInsecure, ok := d.GetOk("tls_insecure"); ok {
if client.SetTLSConfig(&api.TLSConfig{Insecure: tlsInsecure.(bool)}) != nil {
return nil, diag.Errorf("could not set insecure tls")
}
}
client.SetLimiter(5, 5)
md := &metaData{
+12 -10
View File
@@ -1,6 +1,10 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
"context"
"crypto/rand"
"encoding/base64"
"fmt"
@@ -8,18 +12,18 @@ import (
"testing"
"github.com/hashicorp/boundary/testing/controller"
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-kms-wrapping/wrappers/aead"
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
"github.com/hashicorp/go-kms-wrapping/v2/aead"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
var (
tcLoginName = "user"
tcLoginName = "testuser"
tcPassword = "passpass"
tcPAUM = "ampw_0000000000"
tcConfig = []controller.Option{
controller.WithDefaultAuthMethodId(tcPAUM),
controller.WithDefaultPasswordAuthMethodId(tcPAUM),
controller.WithDefaultLoginName(tcLoginName),
controller.WithDefaultPassword(tcPassword),
}
@@ -36,7 +40,7 @@ func providerFactories(p **schema.Provider) map[string]func() (*schema.Provider,
}
}
func testWrapper(t *testing.T, key string) wrapping.Wrapper {
func testWrapper(ctx context.Context, t *testing.T, key string) wrapping.Wrapper {
var keyBytes []byte
switch key {
case "":
@@ -56,15 +60,13 @@ func testWrapper(t *testing.T, key string) wrapping.Wrapper {
t.Fatal(err)
}
}
wrapper := aead.NewWrapper(nil)
wrapper := aead.NewWrapper()
_, err := wrapper.SetConfig(map[string]string{
"key_id": key,
})
_, err := wrapper.SetConfig(ctx, wrapping.WithKeyId(key))
if err != nil {
t.Fatal(err)
}
if err := wrapper.SetAESGCMKeyBytes(keyBytes); err != nil {
if err := wrapper.SetAesGcmKeyBytes(keyBytes); err != nil {
t.Fatal(err)
}
return wrapper
+55 -103
View File
@@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
@@ -10,15 +13,10 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
const (
accountTypePassword = "password"
accountLoginNameKey = "login_name"
accountPasswordKey = "password"
)
func resourceAccount() *schema.Resource {
return &schema.Resource{
Description: "The account resource allows you to configure a Boundary account.",
DeprecationMessage: "Deprecated: use `boundary_account_password` instead.",
Description: "Deprecated: use `boundary_account_password` instead.",
CreateContext: resourceAccountCreate,
ReadContext: resourceAccountRead,
@@ -62,29 +60,48 @@ func resourceAccount() *schema.Resource {
Optional: true,
},
accountPasswordKey: {
Description: "The account password.",
Description: "The account password. Only set on create, changes will not be reflected when updating account.",
Type: schema.TypeString,
Optional: true,
Sensitive: true,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
if d.Id() == "" {
// This is a new resource do not suppress password diff
return false
}
return true
},
},
},
}
}
func setFromAccountResponseMap(d *schema.ResourceData, raw map[string]interface{}) {
d.Set(NameKey, raw["name"])
d.Set(DescriptionKey, raw["description"])
d.Set(AuthMethodIdKey, raw["auth_method_id"])
d.Set(TypeKey, raw["type"])
func setFromAccountResponseMap(d *schema.ResourceData, raw map[string]interface{}) error {
if err := d.Set(NameKey, raw["name"]); err != nil {
return err
}
if err := d.Set(DescriptionKey, raw["description"]); err != nil {
return err
}
if err := d.Set(AuthMethodIdKey, raw["auth_method_id"]); err != nil {
return err
}
if err := d.Set(TypeKey, raw["type"]); err != nil {
return err
}
switch raw["type"].(string) {
case accountTypePassword:
if attrsVal, ok := raw["attributes"]; ok {
attrs := attrsVal.(map[string]interface{})
d.Set(accountLoginNameKey, attrs["login_name"])
if err := d.Set(accountLoginNameKey, attrs["login_name"]); err != nil {
return err
}
}
}
d.SetId(raw["id"].(string))
return nil
}
func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
@@ -97,49 +114,22 @@ func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, meta int
return diag.Errorf("no auth method ID provided")
}
var loginName *string
if keyVal, ok := d.GetOk(accountLoginNameKey); ok {
key := keyVal.(string)
loginName = &key
}
var password *string
if keyVal, ok := d.GetOk(accountPasswordKey); ok {
key := keyVal.(string)
password = &key
}
opts := []accounts.Option{}
var typeStr string
if typeVal, ok := d.GetOk(TypeKey); ok {
typeStr = typeVal.(string)
} else {
return diag.Errorf("no type provided")
}
switch typeStr {
case accountTypePassword:
if loginName != nil {
opts = append(opts, accounts.WithPasswordAccountLoginName(*loginName))
}
if password != nil {
opts = append(opts, accounts.WithPasswordAccountPassword(*password))
d.Set(accountPasswordKey, *password)
}
default:
return diag.Errorf("invalid type provided")
if nameVal, ok := d.GetOk(NameKey); ok {
opts = append(opts, accounts.WithName(nameVal.(string)))
}
nameVal, ok := d.GetOk(NameKey)
if ok {
nameStr := nameVal.(string)
opts = append(opts, accounts.WithName(nameStr))
if descVal, ok := d.GetOk(DescriptionKey); ok {
opts = append(opts, accounts.WithDescription(descVal.(string)))
}
descVal, ok := d.GetOk(DescriptionKey)
if ok {
descStr := descVal.(string)
opts = append(opts, accounts.WithDescription(descStr))
if name, ok := d.GetOk(accountLoginNameKey); ok {
opts = append(opts, accounts.WithPasswordAccountLoginName(name.(string)))
}
if pass, ok := d.GetOk(accountPasswordKey); ok {
opts = append(opts, accounts.WithPasswordAccountPassword(pass.(string)))
}
aClient := accounts.NewClient(md.client)
@@ -152,7 +142,9 @@ func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, meta int
return diag.Errorf("nil account after create")
}
setFromAccountResponseMap(d, acr.GetResponseMap())
if err := setFromAccountResponseMap(d, acr.GetResponse().Map); err != nil {
return diag.FromErr(err)
}
return nil
}
@@ -163,7 +155,7 @@ func resourceAccountRead(ctx context.Context, d *schema.ResourceData, meta inter
arr, err := aClient.Read(ctx, d.Id())
if err != nil {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.ResponseStatus() == http.StatusNotFound {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound {
d.SetId("")
return nil
}
@@ -173,7 +165,9 @@ func resourceAccountRead(ctx context.Context, d *schema.ResourceData, meta inter
return diag.Errorf("account nil after read")
}
setFromAccountResponseMap(d, arr.GetResponseMap())
if err := setFromAccountResponseMap(d, arr.GetResponse().Map); err != nil {
return diag.FromErr(err)
}
return nil
}
@@ -184,79 +178,37 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, meta int
opts := []accounts.Option{}
var name *string
if d.HasChange(NameKey) {
opts = append(opts, accounts.DefaultName())
nameVal, ok := d.GetOk(NameKey)
if ok {
nameStr := nameVal.(string)
name = &nameStr
opts = append(opts, accounts.WithName(nameStr))
opts = append(opts, accounts.WithName(nameVal.(string)))
}
}
var desc *string
if d.HasChange(DescriptionKey) {
opts = append(opts, accounts.DefaultDescription())
descVal, ok := d.GetOk(DescriptionKey)
if ok {
descStr := descVal.(string)
desc = &descStr
opts = append(opts, accounts.WithDescription(descStr))
opts = append(opts, accounts.WithDescription(descVal.(string)))
}
}
var loginName *string
if d.HasChange(accountLoginNameKey) {
switch d.Get(TypeKey).(string) {
case accountTypePassword:
opts = append(opts, accounts.DefaultPasswordAccountLoginName())
keyVal, ok := d.GetOk(accountLoginNameKey)
if ok {
keyStr := keyVal.(string)
loginName = &keyStr
opts = append(opts, accounts.WithPasswordAccountLoginName(keyStr))
}
default:
return diag.Errorf(`"login_name" cannot be used with this type of account`)
}
}
var password *string
if d.HasChange(accountPasswordKey) {
switch d.Get(TypeKey).(string) {
case accountTypePassword:
opts = append(opts, accounts.DefaultPasswordAccountPassword())
keyVal, ok := d.GetOk(accountPasswordKey)
if ok {
keyStr := keyVal.(string)
password = &keyStr
opts = append(opts, accounts.WithPasswordAccountPassword(keyStr))
}
default:
return diag.Errorf(`"password" cannot be used with this type of account`)
opts = append(opts, accounts.DefaultPasswordAccountLoginName())
if keyVal, ok := d.GetOk(accountLoginNameKey); ok {
opts = append(opts, accounts.WithPasswordAccountLoginName(keyVal.(string)))
}
}
if len(opts) > 0 {
opts = append(opts, accounts.WithAutomaticVersioning(true))
_, err := aClient.Update(ctx, d.Id(), 0, opts...)
aur, err := aClient.Update(ctx, d.Id(), 0, opts...)
if err != nil {
return diag.Errorf("error updating account: %v", err)
}
}
if d.HasChange(NameKey) {
d.Set(NameKey, name)
}
if d.HasChange(DescriptionKey) {
d.Set(DescriptionKey, desc)
}
if d.HasChange(accountLoginNameKey) {
d.Set(accountLoginNameKey, loginName)
}
if d.HasChange(accountPasswordKey) {
d.Set(accountPasswordKey, password)
setFromAccountResponseMap(d, aur.GetResponse().Map)
}
return nil
+205
View File
@@ -0,0 +1,205 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
"context"
"net/http"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/accounts"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
const (
accountTypeOidc = "password"
accountOidcIssuerKey = "issuer"
accountOidcSubjectKey = "subject"
)
func resourceAccountOidc() *schema.Resource {
return &schema.Resource{
Description: "The account resource allows you to configure a Boundary account.",
CreateContext: resourceAccountOidcCreate,
ReadContext: resourceAccountOidcRead,
UpdateContext: resourceAccountOidcUpdate,
DeleteContext: resourceAccountOidcDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
IDKey: {
Description: "The ID of the account.",
Type: schema.TypeString,
Computed: true,
},
NameKey: {
Description: "The account name. Defaults to the resource name.",
Type: schema.TypeString,
Optional: true,
},
DescriptionKey: {
Description: "The account description.",
Type: schema.TypeString,
Optional: true,
},
AuthMethodIdKey: {
Description: "The resource ID for the auth method.",
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
accountOidcIssuerKey: {
Description: "The OIDC issuer.",
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
accountOidcSubjectKey: {
Description: "The OIDC subject.",
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
},
}
}
func setFromAccountOidcResponseMap(d *schema.ResourceData, raw map[string]interface{}) {
d.Set(NameKey, raw["name"])
d.Set(DescriptionKey, raw["description"])
d.Set(AuthMethodIdKey, raw["auth_method_id"])
if attrsVal, ok := raw["attributes"]; ok {
attrs := attrsVal.(map[string]interface{})
d.Set(accountOidcIssuerKey, attrs["issuer"])
d.Set(accountOidcSubjectKey, attrs["subject"])
}
d.SetId(raw["id"].(string))
}
func resourceAccountOidcCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
var authMethodId string
if authMethodIdVal, ok := d.GetOk(AuthMethodIdKey); ok {
authMethodId = authMethodIdVal.(string)
} else {
return diag.Errorf("no auth method ID provided")
}
opts := []accounts.Option{}
if i, ok := d.GetOk(accountOidcIssuerKey); ok {
opts = append(opts, accounts.WithOidcAccountIssuer(i.(string)))
}
if s, ok := d.GetOk(accountOidcSubjectKey); ok {
opts = append(opts, accounts.WithOidcAccountSubject(s.(string)))
}
if n, ok := d.GetOk(NameKey); ok {
opts = append(opts, accounts.WithName(n.(string)))
}
if d, ok := d.GetOk(DescriptionKey); ok {
opts = append(opts, accounts.WithDescription(d.(string)))
}
aClient := accounts.NewClient(md.client)
acr, err := aClient.Create(ctx, authMethodId, opts...)
if err != nil {
return diag.Errorf("error creating account: %v", err)
}
if acr == nil {
return diag.Errorf("nil account after create")
}
setFromAccountOidcResponseMap(d, acr.GetResponse().Map)
return nil
}
func resourceAccountOidcRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
aClient := accounts.NewClient(md.client)
arr, err := aClient.Read(ctx, d.Id())
if err != nil {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound {
d.SetId("")
return nil
}
return diag.Errorf("error reading account: %v", err)
}
if arr == nil {
return diag.Errorf("account nil after read")
}
setFromAccountOidcResponseMap(d, arr.GetResponse().Map)
return nil
}
func resourceAccountOidcUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
aClient := accounts.NewClient(md.client)
opts := []accounts.Option{}
if d.HasChange(NameKey) {
opts = append(opts, accounts.DefaultName())
if n, ok := d.GetOk(NameKey); ok {
opts = append(opts, accounts.WithName(n.(string)))
}
}
if d.HasChange(DescriptionKey) {
opts = append(opts, accounts.DefaultDescription())
if d, ok := d.GetOk(DescriptionKey); ok {
opts = append(opts, accounts.WithDescription(d.(string)))
}
}
if d.HasChange(accountOidcIssuerKey) {
opts = append(opts, accounts.DefaultOidcAccountIssuer())
if i, ok := d.GetOk(accountOidcIssuerKey); ok {
opts = append(opts, accounts.WithOidcAccountIssuer(i.(string)))
}
}
if d.HasChange(accountOidcSubjectKey) {
opts = append(opts, accounts.DefaultOidcAccountSubject())
if i, ok := d.GetOk(accountOidcSubjectKey); ok {
opts = append(opts, accounts.WithOidcAccountSubject(i.(string)))
}
}
if len(opts) > 0 {
opts = append(opts, accounts.WithAutomaticVersioning(true))
aur, err := aClient.Update(ctx, d.Id(), 0, opts...)
if err != nil {
return diag.Errorf("error updating account: %v", err)
}
setFromAccountOidcResponseMap(d, aur.GetResponse().Map)
}
return nil
}
func resourceAccountOidcDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
aClient := accounts.NewClient(md.client)
_, err := aClient.Delete(ctx, d.Id())
if err != nil {
return diag.Errorf("error deleting account: %v", err)
}
return nil
}
@@ -0,0 +1,267 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
"context"
"net/http"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/accounts"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
const (
accountTypePassword = "password"
accountLoginNameKey = "login_name"
accountPasswordKey = "password"
)
func resourceAccountPassword() *schema.Resource {
return &schema.Resource{
Description: "The account resource allows you to configure a Boundary account.",
CreateContext: resourceAccountPasswordCreate,
ReadContext: resourceAccountPasswordRead,
UpdateContext: resourceAccountPasswordUpdate,
DeleteContext: resourceAccountPasswordDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
IDKey: {
Description: "The ID of the account.",
Type: schema.TypeString,
Computed: true,
},
NameKey: {
Description: "The account name. Defaults to the resource name.",
Type: schema.TypeString,
Optional: true,
},
DescriptionKey: {
Description: "The account description.",
Type: schema.TypeString,
Optional: true,
},
AuthMethodIdKey: {
Description: "The resource ID for the auth method.",
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
TypeKey: {
Description: "The resource type.",
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
accountLoginNameKey: {
Description: "The login name for this account.",
Type: schema.TypeString,
Optional: true,
},
accountPasswordKey: {
Description: "The account password. Only set on create, changes will not be reflected when updating account.",
Type: schema.TypeString,
Optional: true,
Sensitive: true,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
if d.Id() == "" {
// This is a new resource do not suppress password diff
return false
}
return true
},
},
},
}
}
func setFromAccountPasswordResponseMap(d *schema.ResourceData, raw map[string]interface{}) {
d.Set(NameKey, raw["name"])
d.Set(DescriptionKey, raw["description"])
d.Set(AuthMethodIdKey, raw["auth_method_id"])
d.Set(TypeKey, raw["type"])
switch raw["type"].(string) {
case accountTypePassword:
if attrsVal, ok := raw["attributes"]; ok {
attrs := attrsVal.(map[string]interface{})
d.Set(accountLoginNameKey, attrs["login_name"])
}
}
d.SetId(raw["id"].(string))
}
func resourceAccountPasswordCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
var authMethodId string
if authMethodIdVal, ok := d.GetOk(AuthMethodIdKey); ok {
authMethodId = authMethodIdVal.(string)
} else {
return diag.Errorf("no auth method ID provided")
}
var loginName *string
if keyVal, ok := d.GetOk(accountLoginNameKey); ok {
key := keyVal.(string)
loginName = &key
}
var password *string
if keyVal, ok := d.GetOk(accountPasswordKey); ok {
key := keyVal.(string)
password = &key
}
opts := []accounts.Option{}
var typeStr string
if typeVal, ok := d.GetOk(TypeKey); ok {
typeStr = typeVal.(string)
} else {
return diag.Errorf("no type provided")
}
switch typeStr {
case accountTypePassword:
if loginName != nil {
opts = append(opts, accounts.WithPasswordAccountLoginName(*loginName))
}
if password != nil {
opts = append(opts, accounts.WithPasswordAccountPassword(*password))
d.Set(accountPasswordKey, *password)
}
default:
return diag.Errorf("invalid type provided")
}
nameVal, ok := d.GetOk(NameKey)
if ok {
nameStr := nameVal.(string)
opts = append(opts, accounts.WithName(nameStr))
}
descVal, ok := d.GetOk(DescriptionKey)
if ok {
descStr := descVal.(string)
opts = append(opts, accounts.WithDescription(descStr))
}
aClient := accounts.NewClient(md.client)
acr, err := aClient.Create(ctx, authMethodId, opts...)
if err != nil {
return diag.Errorf("error creating account: %v", err)
}
if acr == nil {
return diag.Errorf("nil account after create")
}
setFromAccountPasswordResponseMap(d, acr.GetResponse().Map)
return nil
}
func resourceAccountPasswordRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
aClient := accounts.NewClient(md.client)
arr, err := aClient.Read(ctx, d.Id())
if err != nil {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound {
d.SetId("")
return nil
}
return diag.Errorf("error reading account: %v", err)
}
if arr == nil {
return diag.Errorf("account nil after read")
}
setFromAccountPasswordResponseMap(d, arr.GetResponse().Map)
return nil
}
func resourceAccountPasswordUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
aClient := accounts.NewClient(md.client)
opts := []accounts.Option{}
var name *string
if d.HasChange(NameKey) {
opts = append(opts, accounts.DefaultName())
nameVal, ok := d.GetOk(NameKey)
if ok {
nameStr := nameVal.(string)
name = &nameStr
opts = append(opts, accounts.WithName(nameStr))
}
}
var desc *string
if d.HasChange(DescriptionKey) {
opts = append(opts, accounts.DefaultDescription())
descVal, ok := d.GetOk(DescriptionKey)
if ok {
descStr := descVal.(string)
desc = &descStr
opts = append(opts, accounts.WithDescription(descStr))
}
}
var loginName *string
if d.HasChange(accountLoginNameKey) {
switch d.Get(TypeKey).(string) {
case accountTypePassword:
opts = append(opts, accounts.DefaultPasswordAccountLoginName())
keyVal, ok := d.GetOk(accountLoginNameKey)
if ok {
keyStr := keyVal.(string)
loginName = &keyStr
opts = append(opts, accounts.WithPasswordAccountLoginName(keyStr))
}
default:
return diag.Errorf(`"login_name" cannot be used with this type of account`)
}
}
if len(opts) > 0 {
opts = append(opts, accounts.WithAutomaticVersioning(true))
_, err := aClient.Update(ctx, d.Id(), 0, opts...)
if err != nil {
return diag.Errorf("error updating account: %v", err)
}
}
if d.HasChange(NameKey) {
d.Set(NameKey, name)
}
if d.HasChange(DescriptionKey) {
d.Set(DescriptionKey, desc)
}
if d.HasChange(accountLoginNameKey) {
d.Set(accountLoginNameKey, loginName)
}
return nil
}
func resourceAccountPasswordDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
aClient := accounts.NewClient(md.client)
_, err := aClient.Delete(ctx, d.Id())
if err != nil {
return diag.Errorf("error deleting account: %v", err)
}
return nil
}
@@ -0,0 +1,153 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
"context"
"fmt"
"net/http"
"testing"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/accounts"
"github.com/hashicorp/boundary/testing/controller"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)
const (
fooAccountPasswordDesc = "test account"
fooAccountPasswordDescUpdate = "test account update"
)
var (
fooAccountPassword = fmt.Sprintf(`
resource "boundary_auth_method" "foo" {
name = "test"
description = "test account"
type = "password"
scope_id = boundary_scope.org1.id
depends_on = [boundary_role.org1_admin]
}
resource "boundary_account_password" "foo" {
name = "test"
description = "%s"
type = "password"
login_name = "foo"
password = "foofoofoo"
auth_method_id = boundary_auth_method.foo.id
}`, fooAccountPasswordDesc)
fooAccountPasswordUpdate = fmt.Sprintf(`
resource "boundary_auth_method" "foo" {
name = "test"
description = "test account"
type = "password"
scope_id = boundary_scope.org1.id
depends_on = [boundary_role.org1_admin]
}
resource "boundary_account_password" "foo" {
name = "test"
description = "%s"
type = "password"
login_name = "foo"
password = "foofoofoo"
auth_method_id = boundary_auth_method.foo.id
}`, fooAccountPasswordDescUpdate)
)
func TestAccAccount(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),
CheckDestroy: testAccCheckAccountPasswordResourceDestroy(t, provider),
Steps: []resource.TestStep{
{
// create
Config: testConfig(url, fooOrg, fooAccountPassword),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("boundary_account_password.foo", "description", fooAccountPasswordDesc),
resource.TestCheckResourceAttr("boundary_account_password.foo", "name", "test"),
resource.TestCheckResourceAttr("boundary_account_password.foo", "type", "password"),
resource.TestCheckResourceAttr("boundary_account_password.foo", "login_name", "foo"),
resource.TestCheckResourceAttr("boundary_account_password.foo", "password", "foofoofoo"),
testAccCheckAccountPasswordResourceExists(provider, "boundary_account_password.foo"),
),
},
importStep("boundary_account_password.foo", "password"),
{
// update
Config: testConfig(url, fooOrg, fooAccountPasswordUpdate),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("boundary_account_password.foo", "description", fooAccountPasswordDescUpdate),
resource.TestCheckResourceAttr("boundary_account_password.foo", "name", "test"),
resource.TestCheckResourceAttr("boundary_account_password.foo", "type", "password"),
resource.TestCheckResourceAttr("boundary_account_password.foo", "login_name", "foo"),
resource.TestCheckResourceAttr("boundary_account_password.foo", "password", "foofoofoo"),
testAccCheckAccountPasswordResourceExists(provider, "boundary_account_password.foo"),
),
},
importStep("boundary_account_password.foo", "password"),
},
})
}
func testAccCheckAccountPasswordResourceExists(testProvider *schema.Provider, name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("Not found: %s", name)
}
id := rs.Primary.ID
if id == "" {
return fmt.Errorf("No ID is set")
}
md := testProvider.Meta().(*metaData)
amClient := accounts.NewClient(md.client)
if _, err := amClient.Read(context.Background(), id); err != nil {
return fmt.Errorf("Got an error when reading account %q: %v", id, err)
}
return nil
}
}
func testAccCheckAccountPasswordResourceDestroy(t *testing.T, testProvider *schema.Provider) resource.TestCheckFunc {
return func(s *terraform.State) error {
if testProvider.Meta() == nil {
t.Fatal("got nil provider metadata")
}
md := testProvider.Meta().(*metaData)
for _, rs := range s.RootModule().Resources {
switch rs.Type {
case "boundary_account_password":
id := rs.Primary.ID
amClient := accounts.NewClient(md.client)
_, err := amClient.Read(context.Background(), id)
if apiErr := api.AsServerError(err); apiErr == nil || apiErr.Response().StatusCode() != http.StatusNotFound {
return fmt.Errorf("didn't get a 404 when reading destroyed account %q: %v", id, err)
}
default:
continue
}
}
return nil
}
}
+6 -3
View File
@@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
@@ -57,7 +60,7 @@ resource "boundary_account" "foo" {
}`, fooAccountDescUpdate)
)
func TestAccAccount(t *testing.T) {
func TestAccAccountBase(t *testing.T) {
tc := controller.NewTestController(t, tcConfig...)
defer tc.Shutdown()
url := tc.ApiAddrs()[0]
@@ -69,7 +72,7 @@ func TestAccAccount(t *testing.T) {
CheckDestroy: testAccCheckAccountResourceDestroy(t, provider),
Steps: []resource.TestStep{
{
//create
// create
Config: testConfig(url, fooOrg, fooAccount),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("boundary_account.foo", "description", fooAccountDesc),
@@ -137,7 +140,7 @@ func testAccCheckAccountResourceDestroy(t *testing.T, testProvider *schema.Provi
amClient := accounts.NewClient(md.client)
_, err := amClient.Read(context.Background(), id)
if apiErr := api.AsServerError(err); apiErr == nil || apiErr.ResponseStatus() != http.StatusNotFound {
if apiErr := api.AsServerError(err); apiErr == nil || apiErr.Response().StatusCode() != http.StatusNotFound {
return fmt.Errorf("didn't get a 404 when reading destroyed account %q: %v", id, err)
}
+72 -107
View File
@@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
@@ -9,12 +12,7 @@ import (
"github.com/hashicorp/boundary/api/authmethods"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
const (
authmethodTypePassword = "password"
authmethodMinLoginNameLengthKey = "min_login_name_length"
authmethodMinPasswordLengthKey = "min_password_length"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)
func resourceAuthMethod() *schema.Resource {
@@ -56,28 +54,42 @@ func resourceAuthMethod() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
authmethodTypeOidc,
authmethodTypePassword,
}, false),
},
authmethodMinLoginNameLengthKey: {
Description: "The minimum login name length.",
Type: schema.TypeInt,
Optional: true,
Computed: true,
Deprecated: "Will be removed in favor of using attributes parameter",
},
authmethodMinPasswordLengthKey: {
Description: "The minimum password length.",
Type: schema.TypeInt,
Optional: true,
Computed: true,
Deprecated: "Will be removed in favor of using attributes parameter",
},
},
}
}
func setFromAuthMethodResponseMap(d *schema.ResourceData, raw map[string]interface{}) {
d.Set(NameKey, raw["name"])
d.Set(DescriptionKey, raw["description"])
d.Set(ScopeIdKey, raw["scope_id"])
d.Set(TypeKey, raw["type"])
func setFromAuthMethodResponseMap(d *schema.ResourceData, raw map[string]interface{}) error {
if err := d.Set(NameKey, raw["name"]); err != nil {
return err
}
if err := d.Set(DescriptionKey, raw["description"]); err != nil {
return err
}
if err := d.Set(ScopeIdKey, raw["scope_id"]); err != nil {
return err
}
if err := d.Set(TypeKey, raw["type"]); err != nil {
return err
}
switch raw["type"].(string) {
case authmethodTypePassword:
@@ -86,15 +98,19 @@ func setFromAuthMethodResponseMap(d *schema.ResourceData, raw map[string]interfa
minLoginNameLength := attrs["min_login_name_length"].(json.Number)
minLoginNameLengthInt, _ := minLoginNameLength.Int64()
d.Set(authmethodMinLoginNameLengthKey, int(minLoginNameLengthInt))
if err := d.Set(authmethodMinLoginNameLengthKey, int(minLoginNameLengthInt)); err != nil {
return err
}
minPasswordLength := attrs["min_password_length"].(json.Number)
minPasswordLengthInt, _ := minPasswordLength.Int64()
d.Set(authmethodMinPasswordLengthKey, int(minPasswordLengthInt))
if err := d.Set(authmethodMinPasswordLengthKey, int(minPasswordLengthInt)); err != nil {
return err
}
}
}
d.SetId(raw["id"].(string))
return nil
}
func resourceAuthMethodCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
@@ -107,48 +123,31 @@ func resourceAuthMethodCreate(ctx context.Context, d *schema.ResourceData, meta
return diag.Errorf("no scope ID provided")
}
var minLoginNameLength *int
if minLengthVal, ok := d.GetOk(authmethodMinLoginNameLengthKey); ok {
minLength := minLengthVal.(int)
minLoginNameLength = &minLength
}
var minPasswordLength *int
if minLengthVal, ok := d.GetOk(authmethodMinPasswordLengthKey); ok {
minLength := minLengthVal.(int)
minPasswordLength = &minLength
}
opts := []authmethods.Option{}
var typeStr string
if typeVal, ok := d.GetOk(TypeKey); ok {
typeStr = typeVal.(string)
} else {
return diag.Errorf("no type provided")
}
switch typeStr {
case authmethodTypePassword:
if minLoginNameLength != nil {
opts = append(opts, authmethods.WithPasswordAuthMethodMinLoginNameLength(uint32(*minLoginNameLength)))
}
if minPasswordLength != nil {
opts = append(opts, authmethods.WithPasswordAuthMethodMinPasswordLength(uint32(*minPasswordLength)))
}
default:
return diag.Errorf("invalid type provided")
opts := []authmethods.Option{}
if nameVal, ok := d.GetOk(NameKey); ok {
opts = append(opts, authmethods.WithName(nameVal.(string)))
}
nameVal, ok := d.GetOk(NameKey)
if ok {
nameStr := nameVal.(string)
opts = append(opts, authmethods.WithName(nameStr))
if descVal, ok := d.GetOk(DescriptionKey); ok {
opts = append(opts, authmethods.WithDescription(descVal.(string)))
}
descVal, ok := d.GetOk(DescriptionKey)
if ok {
descStr := descVal.(string)
opts = append(opts, authmethods.WithDescription(descStr))
// TODO(malnick) - deprecate
if minLengthVal, ok := d.GetOk(authmethodMinLoginNameLengthKey); ok {
opts = append(opts, authmethods.WithPasswordAuthMethodMinLoginNameLength(uint32(minLengthVal.(int))))
}
// TODO(malnick) - deprecate
if minLengthVal, ok := d.GetOk(authmethodMinPasswordLengthKey); ok {
opts = append(opts, authmethods.WithPasswordAuthMethodMinPasswordLength(uint32(minLengthVal.(int))))
}
amClient := authmethods.NewClient(md.client)
@@ -161,7 +160,9 @@ func resourceAuthMethodCreate(ctx context.Context, d *schema.ResourceData, meta
return diag.Errorf("nil auth method after create")
}
setFromAuthMethodResponseMap(d, amcr.GetResponseMap())
if err := setFromAuthMethodResponseMap(d, amcr.GetResponse().Map); err != nil {
return diag.FromErr(err)
}
return nil
}
@@ -172,7 +173,7 @@ func resourceAuthMethodRead(ctx context.Context, d *schema.ResourceData, meta in
amrr, err := amClient.Read(ctx, d.Id())
if err != nil {
if apiErr := api.AsServerError(err); apiErr.ResponseStatus() == http.StatusNotFound {
if apiErr := api.AsServerError(err); apiErr.Response().StatusCode() == http.StatusNotFound {
d.SetId("")
return nil
}
@@ -182,7 +183,9 @@ func resourceAuthMethodRead(ctx context.Context, d *schema.ResourceData, meta in
return diag.Errorf("auth method nil after read")
}
setFromAuthMethodResponseMap(d, amrr.GetResponseMap())
if err := setFromAuthMethodResponseMap(d, amrr.GetResponse().Map); err != nil {
return diag.FromErr(err)
}
return nil
}
@@ -193,81 +196,43 @@ func resourceAuthMethodUpdate(ctx context.Context, d *schema.ResourceData, meta
opts := []authmethods.Option{}
var name *string
if d.HasChange(NameKey) {
opts = append(opts, authmethods.DefaultName())
nameVal, ok := d.GetOk(NameKey)
if ok {
nameStr := nameVal.(string)
name = &nameStr
opts = append(opts, authmethods.WithName(nameStr))
if nameVal, ok := d.GetOk(NameKey); ok {
opts = append(opts, authmethods.WithName(nameVal.(string)))
}
}
var desc *string
if d.HasChange(DescriptionKey) {
opts = append(opts, authmethods.DefaultDescription())
descVal, ok := d.GetOk(DescriptionKey)
if ok {
descStr := descVal.(string)
desc = &descStr
opts = append(opts, authmethods.WithDescription(descStr))
if descVal, ok := d.GetOk(DescriptionKey); ok {
opts = append(opts, authmethods.WithDescription(descVal.(string)))
}
}
var minLoginNameLength *int
if d.HasChange(authmethodMinLoginNameLengthKey) {
switch d.Get(TypeKey).(string) {
case authmethodTypePassword:
opts = append(opts, authmethods.DefaultPasswordAuthMethodMinLoginNameLength())
minLengthVal, ok := d.GetOk(authmethodMinLoginNameLengthKey)
if ok {
minLengthInt := minLengthVal.(int)
minLoginNameLength = &minLengthInt
opts = append(opts, authmethods.WithPasswordAuthMethodMinLoginNameLength(uint32(minLengthInt)))
}
default:
return diag.Errorf(`"min_login_name_length" cannot be used with this type of auth method`)
}
}
var minPasswordLength *int
// TODO(malnick) - deprecate
if d.HasChange(authmethodMinPasswordLengthKey) {
switch d.Get(TypeKey).(string) {
case authmethodTypePassword:
opts = append(opts, authmethods.DefaultPasswordAuthMethodMinPasswordLength())
minLengthVal, ok := d.GetOk(authmethodMinPasswordLengthKey)
if ok {
minLengthInt := minLengthVal.(int)
minPasswordLength = &minLengthInt
opts = append(opts, authmethods.WithPasswordAuthMethodMinPasswordLength(uint32(minLengthInt)))
}
default:
return diag.Errorf(`"min_password_length" cannot be used with this type of auth method`)
opts = append(opts, authmethods.DefaultPasswordAuthMethodMinPasswordLength())
if minLengthVal, ok := d.GetOk(authmethodMinPasswordLengthKey); ok {
opts = append(opts, authmethods.WithPasswordAuthMethodMinPasswordLength(uint32(minLengthVal.(int))))
}
}
if len(opts) > 0 {
opts = append(opts, authmethods.WithAutomaticVersioning(true))
_, err := amClient.Update(ctx, d.Id(), 0, opts...)
if err != nil {
return diag.Errorf("error updating auth method: %v", err)
}
}
if d.HasChange(NameKey) {
d.Set(NameKey, name)
}
if d.HasChange(DescriptionKey) {
d.Set(DescriptionKey, desc)
}
// TODO(malnick) - deprecate
if d.HasChange(authmethodMinLoginNameLengthKey) {
d.Set(authmethodMinLoginNameLengthKey, minLoginNameLength)
opts = append(opts, authmethods.DefaultPasswordAuthMethodMinLoginNameLength())
if minLengthVal, ok := d.GetOk(authmethodMinLoginNameLengthKey); ok {
opts = append(opts, authmethods.WithPasswordAuthMethodMinLoginNameLength(uint32(minLengthVal.(int))))
}
}
if d.HasChange(authmethodMinPasswordLengthKey) {
d.Set(authmethodMinPasswordLengthKey, minPasswordLength)
opts = append(opts, authmethods.WithAutomaticVersioning(true))
amu, err := amClient.Update(ctx, d.Id(), 0, opts...)
if err != nil {
return diag.Errorf("error updating auth method: %v", err)
}
setFromAuthMethodResponseMap(d, amu.GetResponse().Map)
return nil
}
@@ -0,0 +1,568 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
"context"
"encoding/json"
"net/http"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/authmethods"
"github.com/hashicorp/boundary/api/scopes"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
const (
authmethodTypeOidc = "oidc"
authmethodOidcIssuerKey = "issuer"
authmethodOidcClientIdKey = "client_id"
authmethodOidcClientSecretKey = "client_secret"
authmethodOidcMaxAgeKey = "max_age"
authmethodOidcApiUrlPrefixKey = "api_url_prefix"
authmethodOidcIdpCaCertsKey = "idp_ca_certs"
authmethodOidcAllowedAudiencesKey = "allowed_audiences"
authmethodOidcDisableDiscoveredConfigValidationKey = "disable_discovered_config_validation"
authmethodOidcSigningAlgorithmsKey = "signing_algorithms"
authmethodOidcIsPrimaryAuthMethodForScope = "is_primary_for_scope"
authmethodOidcAccountClaimMapsKey = "account_claim_maps"
authmethodOidcClaimsScopesKey = "claims_scopes"
// computed-only parameters
authmethodOidcCallbackUrlKey = "callback_url"
authmethodOidcClientSecretHmacKey = "client_secret_hmac"
authmethodOidcStateKey = "state"
)
func resourceAuthMethodOidc() *schema.Resource {
return &schema.Resource{
Description: "The OIDC auth method resource allows you to configure a Boundary auth_method_oidc.",
CreateContext: resourceAuthMethodOidcCreate,
ReadContext: resourceAuthMethodOidcRead,
UpdateContext: resourceAuthMethodOidcUpdate,
DeleteContext: resourceAuthMethodOidcDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
IDKey: {
Description: "The ID of the auth method.",
Type: schema.TypeString,
Computed: true,
},
NameKey: {
Description: "The auth method name. Defaults to the resource name.",
Type: schema.TypeString,
Optional: true,
},
DescriptionKey: {
Description: "The auth method description.",
Type: schema.TypeString,
Optional: true,
},
ScopeIdKey: {
Description: "The scope ID.",
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
// OIDC specific configurable parameters
authmethodOidcAllowedAudiencesKey: {
Description: "Audiences for which the provider responses will be allowed",
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
},
authmethodOidcApiUrlPrefixKey: {
Description: "The API prefix to use when generating callback URLs for the provider. Should be set to an address at which the provider can reach back to the controller.",
Type: schema.TypeString,
Optional: true,
},
authmethodOidcIdpCaCertsKey: {
Description: "A list of CA certificates to trust when validating the IdP's token signatures.",
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
},
authmethodOidcClientIdKey: {
Description: "The client ID assigned to this auth method from the provider.",
Type: schema.TypeString,
Optional: true,
},
authmethodOidcClientSecretKey: {
Description: "The secret key assigned to this auth method from the provider. Once set, only the hash will be kept and the original value can be removed from configuration.",
Type: schema.TypeString,
Optional: true,
Sensitive: true,
},
authmethodOidcIssuerKey: {
Description: "The issuer corresponding to the provider, which must match the issuer field in generated tokens.",
Type: schema.TypeString,
Optional: true,
},
authmethodOidcDisableDiscoveredConfigValidationKey: {
Description: "Disables validation logic ensuring that the OIDC provider's information from its discovery endpoint matches the information here. The validation is only performed at create or update time.",
Type: schema.TypeBool,
Optional: true,
},
authmethodOidcMaxAgeKey: {
Description: "The max age to provide to the provider, indicating how much time is allowed to have passed since the last authentication before the user is challenged again.",
Type: schema.TypeInt,
Optional: true,
},
authmethodOidcSigningAlgorithmsKey: {
Description: "Allowed signing algorithms for the provider's issued tokens.",
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
},
authmethodOidcAccountClaimMapsKey: {
Description: "Account claim maps for the to_claim of sub.",
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
// per comment in https://github.com/hashicorp/boundary/pull/1186
ForceNew: true,
},
authmethodOidcClaimsScopesKey: {
Description: "Claims scopes.",
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
},
// OIDC specific immutable and computed parameters
authmethodOidcClientSecretHmacKey: {
Description: "The HMAC of the client secret returned by the Boundary controller, which is used for comparison after initial setting of the value.",
Type: schema.TypeString,
Optional: true,
Computed: true,
},
authmethodOidcStateKey: {
Description: "Can be one of 'inactive', 'active-private', or 'active-public'. Currently automatically set to active-public.",
Type: schema.TypeString,
Optional: true,
Computed: true,
},
authmethodOidcCallbackUrlKey: {
Description: "The URL that should be provided to the IdP for callbacks.",
Type: schema.TypeString,
Optional: true,
Computed: true,
},
authmethodOidcIsPrimaryAuthMethodForScope: {
Description: "When true, makes this auth method the primary auth method for the scope in which it resides. The primary auth method for a scope means the the user will be automatically created when they login using an OIDC account.",
Type: schema.TypeBool,
Optional: true,
},
TypeKey: {
Description: "The type of auth method; hardcoded.",
Type: schema.TypeString,
Default: authmethodTypeOidc,
Optional: true,
},
},
}
}
func setFromOidcAuthMethodResponseMap(d *schema.ResourceData, raw map[string]interface{}) diag.Diagnostics {
d.Set(NameKey, raw[NameKey])
d.Set(DescriptionKey, raw[DescriptionKey])
d.Set(ScopeIdKey, raw[ScopeIdKey])
d.Set(TypeKey, raw[TypeKey])
if attrsVal, ok := raw["attributes"]; ok {
attrs := attrsVal.(map[string]interface{})
// these are always set
d.Set(authmethodOidcStateKey, attrs[authmethodOidcStateKey].(string))
d.Set(authmethodOidcIssuerKey, attrs[authmethodOidcIssuerKey].(string))
d.Set(authmethodOidcClientIdKey, attrs[authmethodOidcClientIdKey].(string))
d.Set(authmethodOidcClientSecretHmacKey, attrs[authmethodOidcClientSecretHmacKey].(string))
if certs, ok := attrs[authmethodOidcIdpCaCertsKey]; ok {
d.Set(authmethodOidcIdpCaCertsKey, certs.([]interface{}))
}
if aud, ok := attrs[authmethodOidcAllowedAudiencesKey]; ok {
d.Set(authmethodOidcAllowedAudiencesKey, aud.([]interface{}))
}
if m, ok := attrs[authmethodOidcMaxAgeKey]; ok {
maxAge := m.(json.Number)
maxAgeInt, _ := maxAge.Int64()
d.Set(authmethodOidcMaxAgeKey, maxAgeInt)
}
if val, ok := attrs[authmethodOidcApiUrlPrefixKey]; ok {
d.Set(authmethodOidcApiUrlPrefixKey, val.(string))
}
if val, ok := attrs[authmethodOidcCallbackUrlKey]; ok {
d.Set(authmethodOidcCallbackUrlKey, val.(string))
}
if val, ok := attrs[authmethodOidcSigningAlgorithmsKey]; ok {
d.Set(authmethodOidcSigningAlgorithmsKey, val.([]interface{}))
}
if p, ok := attrs[authmethodOidcIsPrimaryAuthMethodForScope]; ok {
d.Set(authmethodOidcIsPrimaryAuthMethodForScope, p.(bool))
}
if p, ok := attrs[authmethodOidcDisableDiscoveredConfigValidationKey]; ok {
d.Set(authmethodOidcDisableDiscoveredConfigValidationKey, p.(bool))
}
if p, ok := attrs[authmethodOidcAccountClaimMapsKey]; ok {
d.Set(authmethodOidcAccountClaimMapsKey, p.([]interface{}))
}
if p, ok := attrs[authmethodOidcClaimsScopesKey]; ok {
d.Set(authmethodOidcClaimsScopesKey, p.([]interface{}))
}
}
d.SetId(raw["id"].(string))
return nil
}
func resourceAuthMethodOidcCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
var typeStr string
if typeVal, ok := d.GetOk(TypeKey); ok {
typeStr = typeVal.(string)
} else {
return diag.Errorf("no type provided")
}
opts := []authmethods.Option{}
opts = append(opts, authmethods.WithAutomaticVersioning(true))
if issuer, ok := d.GetOk(authmethodOidcIssuerKey); ok {
opts = append(opts, authmethods.WithOidcAuthMethodIssuer(issuer.(string)))
}
if clientId, ok := d.GetOk(authmethodOidcClientIdKey); ok {
opts = append(opts, authmethods.WithOidcAuthMethodClientId(clientId.(string)))
}
if clientSecret, ok := d.GetOk(authmethodOidcClientSecretKey); ok {
opts = append(opts, authmethods.WithOidcAuthMethodClientSecret(clientSecret.(string)))
}
if maxAge, ok := d.GetOk(authmethodOidcMaxAgeKey); ok {
opts = append(opts, authmethods.WithOidcAuthMethodMaxAge(uint32(maxAge.(int))))
}
if prefix, ok := d.GetOk(authmethodOidcApiUrlPrefixKey); ok {
opts = append(opts, authmethods.WithOidcAuthMethodApiUrlPrefix(prefix.(string)))
}
if certs, ok := d.GetOk(authmethodOidcIdpCaCertsKey); ok {
certList := []string{}
for _, c := range certs.([]interface{}) {
certList = append(certList, c.(string))
}
opts = append(opts, authmethods.WithOidcAuthMethodIdpCaCerts(certList))
}
if aud, ok := d.GetOk(authmethodOidcAllowedAudiencesKey); ok {
audList := []string{}
for _, c := range aud.([]interface{}) {
audList = append(audList, c.(string))
}
opts = append(opts, authmethods.WithOidcAuthMethodAllowedAudiences(audList))
}
if dis, ok := d.GetOk(authmethodOidcDisableDiscoveredConfigValidationKey); ok {
opts = append(opts, authmethods.WithOidcAuthMethodDisableDiscoveredConfigValidation(dis.(bool)))
}
if algos, ok := d.GetOk(authmethodOidcSigningAlgorithmsKey); ok {
algoList := []string{}
for _, c := range algos.([]interface{}) {
algoList = append(algoList, c.(string))
}
opts = append(opts, authmethods.WithOidcAuthMethodSigningAlgorithms(algoList))
}
if claims, ok := d.GetOk(authmethodOidcAccountClaimMapsKey); ok {
cList := []string{}
for _, c := range claims.([]interface{}) {
cList = append(cList, c.(string))
}
opts = append(opts, authmethods.WithOidcAuthMethodAccountClaimMaps(cList))
}
if claimsScopes, ok := d.GetOk(authmethodOidcClaimsScopesKey); ok {
cList := []string{}
for _, c := range claimsScopes.([]interface{}) {
cList = append(cList, c.(string))
}
opts = append(opts, authmethods.WithOidcAuthMethodClaimsScopes(cList))
}
nameVal, ok := d.GetOk(NameKey)
if ok {
nameStr := nameVal.(string)
opts = append(opts, authmethods.WithName(nameStr))
}
descVal, ok := d.GetOk(DescriptionKey)
if ok {
descStr := descVal.(string)
opts = append(opts, authmethods.WithDescription(descStr))
}
var scopeId string
if scopeIdVal, ok := d.GetOk(ScopeIdKey); ok {
scopeId = scopeIdVal.(string)
} else {
return diag.Errorf("no scope ID provided")
}
amClient := authmethods.NewClient(md.client)
amcr, err := amClient.Create(ctx, typeStr, scopeId, opts...)
if err != nil {
return diag.Errorf("error creating auth method: %v", err)
}
if amcr == nil {
return diag.Errorf("nil auth method after create")
}
// need to update state is create was successful to avoid loosing state if the change state or update
// scope step that follows errors out
if err := setFromOidcAuthMethodResponseMap(d, amcr.GetResponse().Map); err != nil {
return diag.Errorf("%v", err)
}
amid := amcr.GetResponse().Map["id"].(string)
// auto set to active-public state
_, err = amClient.ChangeState(ctx, amid, 0, "active-public", authmethods.WithAutomaticVersioning(true))
if err != nil {
return diag.Errorf("%v", err)
}
// update scope when set to primary
if p, ok := d.GetOk(authmethodOidcIsPrimaryAuthMethodForScope); ok {
if p.(bool) {
if err := updateScopeWithPrimaryAuthMethodId(ctx, scopeId, amid, meta); err != nil {
return diag.Errorf("%v", err)
}
amcr.GetResponse().Map[authmethodOidcIsPrimaryAuthMethodForScope] = true
}
}
return setFromOidcAuthMethodResponseMap(d, amcr.GetResponse().Map)
}
func updateScopeWithPrimaryAuthMethodId(ctx context.Context, scopeId, authmethodId string, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
scp := scopes.NewClient(md.client)
opts := []scopes.Option{}
opts = append(opts, scopes.WithAutomaticVersioning(true))
opts = append(opts, scopes.WithPrimaryAuthMethodId(authmethodId))
_, err := scp.Update(ctx, scopeId, 0, opts...)
if err != nil {
return diag.Errorf("error updating scope: %v", err)
}
return nil
}
func readScopeIsPrimaryAuthMethodId(ctx context.Context, scopeId, authmethodId string, meta interface{}) (diag.Diagnostics, bool) {
md := meta.(*metaData)
scp := scopes.NewClient(md.client)
srr, err := scp.Read(ctx, scopeId)
if err != nil {
return diag.Errorf("%s", err), false
}
if p, ok := srr.GetResponse().Map["primary_auth_method_id"]; ok {
if p == authmethodId {
return nil, true
}
}
return nil, false
}
func resourceAuthMethodOidcRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
amClient := authmethods.NewClient(md.client)
amrr, err := amClient.Read(ctx, d.Id())
if err != nil {
if apiErr := api.AsServerError(err); apiErr.Response().StatusCode() == http.StatusNotFound {
d.SetId("")
return nil
}
return diag.Errorf("error reading auth method: %v", err)
}
if amrr == nil {
return diag.Errorf("auth method nil after read")
}
serr, isPrimary := readScopeIsPrimaryAuthMethodId(ctx, amrr.GetResponse().Map["scope_id"].(string), amrr.GetResponse().Map["id"].(string), meta)
if err != nil {
return diag.Errorf("%v", serr)
}
if isPrimary {
amrr.GetResponse().Map[authmethodOidcIsPrimaryAuthMethodForScope] = true
}
return setFromOidcAuthMethodResponseMap(d, amrr.GetResponse().Map)
}
func resourceAuthMethodOidcUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
amClient := authmethods.NewClient(md.client)
opts := []authmethods.Option{}
if d.HasChange(NameKey) {
opts = append(opts, authmethods.DefaultName())
nameVal, ok := d.GetOk(NameKey)
if ok {
opts = append(opts, authmethods.WithName(nameVal.(string)))
}
}
if d.HasChange(DescriptionKey) {
opts = append(opts, authmethods.DefaultDescription())
descVal, ok := d.GetOk(DescriptionKey)
if ok {
opts = append(opts, authmethods.WithDescription(descVal.(string)))
}
}
if d.HasChange(authmethodOidcIssuerKey) {
if issuer, ok := d.GetOk(authmethodOidcIssuerKey); ok {
opts = append(opts, authmethods.WithOidcAuthMethodIssuer(issuer.(string)))
}
}
if d.HasChange(authmethodOidcClientIdKey) {
if clientId, ok := d.GetOk(authmethodOidcClientIdKey); ok {
opts = append(opts, authmethods.WithOidcAuthMethodClientId(clientId.(string)))
}
}
if d.HasChange(authmethodOidcClientSecretKey) {
if clientSecret, ok := d.GetOk(authmethodOidcClientSecretKey); ok {
opts = append(opts, authmethods.WithOidcAuthMethodClientSecret(clientSecret.(string)))
}
}
if d.HasChange(authmethodOidcMaxAgeKey) {
if maxAge, ok := d.GetOk(authmethodOidcMaxAgeKey); ok {
opts = append(opts, authmethods.WithOidcAuthMethodMaxAge(uint32(maxAge.(int))))
}
}
if d.HasChange(authmethodOidcSigningAlgorithmsKey) {
if algos, ok := d.GetOk(authmethodOidcSigningAlgorithmsKey); ok {
var signingAlgs []string
for _, alg := range algos.([]interface{}) {
signingAlgs = append(signingAlgs, alg.(string))
}
opts = append(opts, authmethods.WithOidcAuthMethodSigningAlgorithms(signingAlgs))
}
}
if d.HasChange(authmethodOidcApiUrlPrefixKey) {
if prefix, ok := d.GetOk(authmethodOidcApiUrlPrefixKey); ok {
opts = append(opts, authmethods.WithOidcAuthMethodApiUrlPrefix(prefix.(string)))
}
}
if d.HasChange(authmethodOidcClientSecretHmacKey) {
if sec, ok := d.GetOk(authmethodOidcClientSecretHmacKey); ok {
opts = append(opts, authmethods.WithOidcAuthMethodClientSecret(sec.(string)))
}
}
if d.HasChange(authmethodOidcAllowedAudiencesKey) {
if val, ok := d.GetOk(authmethodOidcAllowedAudiencesKey); ok {
var audiences []string
for _, aud := range val.([]interface{}) {
audiences = append(audiences, aud.(string))
}
opts = append(opts, authmethods.WithOidcAuthMethodAllowedAudiences(audiences))
}
}
if d.HasChange(authmethodOidcIdpCaCertsKey) {
if val, ok := d.GetOk(authmethodOidcIdpCaCertsKey); ok {
certs := []string{}
for _, cert := range val.([]interface{}) {
certs = append(certs, cert.(string))
}
opts = append(opts, authmethods.WithOidcAuthMethodIdpCaCerts(certs))
}
}
if d.HasChange(authmethodOidcDisableDiscoveredConfigValidationKey) {
if val, ok := d.GetOk(authmethodOidcDisableDiscoveredConfigValidationKey); ok {
opts = append(opts, authmethods.WithOidcAuthMethodDisableDiscoveredConfigValidation(val.(bool)))
}
}
if d.HasChange(authmethodOidcClaimsScopesKey) {
if val, ok := d.GetOk(authmethodOidcClaimsScopesKey); ok {
claimsScopes := []string{}
for _, c := range val.([]interface{}) {
claimsScopes = append(claimsScopes, c.(string))
}
opts = append(opts, authmethods.WithOidcAuthMethodClaimsScopes(claimsScopes))
}
}
if len(opts) > 0 {
opts = append(opts, authmethods.WithAutomaticVersioning(true))
amur, err := amClient.Update(ctx, d.Id(), 0, opts...)
if err != nil {
return diag.Errorf("error updating auth method: %v", err)
}
if d.HasChange(authmethodOidcIsPrimaryAuthMethodForScope) {
if p, ok := d.GetOk(authmethodOidcIsPrimaryAuthMethodForScope); ok {
if p.(bool) {
if err := updateScopeWithPrimaryAuthMethodId(
ctx,
amur.GetResponse().Map["scope_id"].(string),
amur.GetResponse().Map["id"].(string),
meta); err != nil {
return diag.Errorf("%v", err)
}
amur.GetResponse().Map[authmethodOidcIsPrimaryAuthMethodForScope] = true
}
}
}
return setFromOidcAuthMethodResponseMap(d, amur.GetResponse().Map)
}
return nil
}
func resourceAuthMethodOidcDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
amClient := authmethods.NewClient(md.client)
_, err := amClient.Delete(ctx, d.Id())
if err != nil {
return diag.Errorf("error deleting auth method: %v", err)
}
return nil
}
@@ -0,0 +1,289 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
"context"
"fmt"
"net/http"
"strings"
"testing"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/authmethods"
"github.com/hashicorp/boundary/api/scopes"
"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"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)
const (
fooAuthMethodOidcDesc = "test auth method oidc"
fooAuthMethodOidcDescUpdate = "test auth method oidc update"
fooAuthMethodOidcCaCerts = `-----BEGIN CERTIFICATE-----
MIIDsjCCApoCCQCslgm7fAu/VzANBgkqhkiG9w0BAQsFADCBmjELMAkGA1UEBhMC
VVMxCzAJBgNVBAgMAldBMRMwEQYDVQQHDApCZWxsaW5naGFtMRIwEAYDVQQKDAlI
YXNoaUNvcnAxETAPBgNVBAsMCEJvdW5kYXJ5MRswGQYDVQQDDBJib3VuZGFyeXBy
b2plY3QuaW8xJTAjBgkqhkiG9w0BCQEWFmptYWxuaWNrQGhhc2hpY29ycC5jb20w
HhcNMjEwNDA2MjMzNTIxWhcNMjYwNDA1MjMzNTIxWjCBmjELMAkGA1UEBhMCVVMx
CzAJBgNVBAgMAldBMRMwEQYDVQQHDApCZWxsaW5naGFtMRIwEAYDVQQKDAlIYXNo
aUNvcnAxETAPBgNVBAsMCEJvdW5kYXJ5MRswGQYDVQQDDBJib3VuZGFyeXByb2pl
Y3QuaW8xJTAjBgkqhkiG9w0BCQEWFmptYWxuaWNrQGhhc2hpY29ycC5jb20wggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUa/ZLwYhTQ2hGzlwy/sB9xY9h
dM4qzY8DUF3Sin/+J2j59q3/vXZA7PS+o1GhoG1nW3J51zgyNFOY/EKHdtxVBken
YTTG+JswzrcTxsMV7/sYDgCLq6W8dPMV72gPH/3dRi3/0KUHtA6rBOf0Shf0f6Sz
7VmgTWcNmLvXpHKOs4YkjOL/tyflTgNm5j1dOa53TtwtMyvCcpGrB7PGL8m5+E2U
qxOzQ9kWfA6zr4Gl5rIm+Us8Ez3n1yGwjwFBteexk1Fot8zWKhoy7pZ3ZjWRpjwL
hfGs5eJs4kERQVAGONt39ZIR6OzOFxAsvI9WrMvxAsdCK63RtF2k4r0X21yDAgMB
AAEwDQYJKoZIhvcNAQELBQADggEBAJZcl7Zxjya23IcOV8jZDdCHtqnbcg9TcQb+
kpX1uEKJMFJoNmNK1q//nJxG1YBn3G8t9XtO6Kc6egdGHXWnOsM37N9hbYPJ2kW1
WWAwqWkQbV3wb0cc6MuU1S9xivOqwM046ZIcjrWR4T4tEUSUfYc3I+Yd8APdapn8
vePgWnmi/aSsx9RxVOUrzmVhzgN7rQJZGwnYYnxl4cwy2jxpysmXzg/grfXCZs/V
Kkc7Y5Ph6vRQ+vPCeB7QUxHxjlr8aq+rYDIaSiZ+/4+qyme0ergfvZmMSU8A3NNS
tYIMds5s2lIqVwOoyzpBEOjWBhUThH+aZu1A5c7Cb7s1eLSRX70=
-----END CERTIFICATE-----`
)
var (
fooAuthMethodOidc = `
resource "boundary_auth_method_oidc" "foo" {
name = "test"
description = "%s"
scope_id = boundary_scope.org1.id
depends_on = [boundary_role.org1_admin]
issuer = "%s"
client_id = "foo_id"
client_secret = "foo_secret"
max_age = 10
api_url_prefix = "http://localhost:9200"
idp_ca_certs = [
<<EOT
%s
EOT
]
allowed_audiences = ["foo_aud"]
signing_algorithms = ["ES256"]
account_claim_maps = ["oid=sub"]
claims_scopes = ["profile"]
}`
fooAuthMethodOidcUpdate = `
resource "boundary_auth_method_oidc" "foo" {
name = "test"
description = "%s"
scope_id = boundary_scope.org1.id
is_primary_for_scope = true
depends_on = [boundary_role.org1_admin]
issuer = "https://test-update.com"
client_id = "foo_id_update"
client_secret = "foo_secret_update"
max_age = 1
api_url_prefix = "http://localhost:9200"
idp_ca_certs = [
<<EOT
%s
EOT
]
allowed_audiences = ["foo_aud_update"]
signing_algorithms = ["ES256"]
account_claim_maps = ["oid=sub"]
claims_scopes = ["profile"]
// we need to disable this validatin, since the updated issuer isn't discoverable
disable_discovered_config_validation = true
}`
)
func TestAccAuthMethodOidc(t *testing.T) {
tp := oidc.StartTestProvider(t)
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)
updateConfig := fmt.Sprintf(fooAuthMethodOidcUpdate, fooAuthMethodOidcDescUpdate, fooAuthMethodOidcCaCerts)
var provider *schema.Provider
resource.Test(t, resource.TestCase{
ProviderFactories: providerFactories(&provider),
CheckDestroy: testAccCheckAuthMethodOidcResourceDestroy(t, provider),
Steps: []resource.TestStep{
{
// create
Config: testConfig(url, fooOrg, createConfig),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("boundary_auth_method_oidc.foo", "description", fooAuthMethodOidcDesc),
resource.TestCheckResourceAttr("boundary_auth_method_oidc.foo", "name", "test"),
resource.TestCheckResourceAttr("boundary_auth_method_oidc.foo", authmethodOidcIssuerKey, tp.Addr()),
resource.TestCheckResourceAttr("boundary_auth_method_oidc.foo", authmethodOidcClientIdKey, "foo_id"),
testAccCheckAuthMethodOidcAttrAryValueSet(provider, "boundary_auth_method_oidc.foo", authmethodOidcIdpCaCertsKey, []string{tpCert}),
testAccCheckAuthMethodOidcAttrAryValueSet(provider, "boundary_auth_method_oidc.foo", authmethodOidcAllowedAudiencesKey, []string{"foo_aud"}),
testAccCheckAuthMethodOidcAttrAryValueSet(provider, "boundary_auth_method_oidc.foo", authmethodOidcSigningAlgorithmsKey, []string{"ES256"}),
testAccCheckAuthMethodOidcAttrAryValueSet(provider, "boundary_auth_method_oidc.foo", authmethodOidcAccountClaimMapsKey, []string{"oid=sub"}),
testAccCheckAuthMethodOidcAttrAryValueSet(provider, "boundary_auth_method_oidc.foo", authmethodOidcClaimsScopesKey, []string{"profile"}),
resource.TestCheckResourceAttr("boundary_auth_method_oidc.foo", authmethodOidcMaxAgeKey, "10"),
testAccCheckAuthMethodOidcResourceExists(provider, "boundary_auth_method_oidc.foo"),
testAccIsPrimaryForScope(provider, "boundary_auth_method_oidc.foo", false),
),
},
importStep("boundary_auth_method_oidc.foo", "client_secret", "is_primary_for_scope"),
{
// update
Config: testConfig(url, fooOrg, updateConfig),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("boundary_auth_method_oidc.foo", "description", fooAuthMethodOidcDescUpdate),
resource.TestCheckResourceAttr("boundary_auth_method_oidc.foo", "name", "test"),
resource.TestCheckResourceAttr("boundary_auth_method_oidc.foo", authmethodOidcIssuerKey, "https://test-update.com"),
resource.TestCheckResourceAttr("boundary_auth_method_oidc.foo", authmethodOidcClientIdKey, "foo_id_update"),
resource.TestCheckResourceAttr("boundary_auth_method_oidc.foo", authmethodOidcMaxAgeKey, "1"),
testAccCheckAuthMethodOidcAttrAryValueSet(provider, "boundary_auth_method_oidc.foo", authmethodOidcIdpCaCertsKey, []string{fooAuthMethodOidcCaCerts}),
testAccCheckAuthMethodOidcAttrAryValueSet(provider, "boundary_auth_method_oidc.foo", authmethodOidcAllowedAudiencesKey, []string{"foo_aud_update"}),
testAccCheckAuthMethodOidcResourceExists(provider, "boundary_auth_method_oidc.foo"),
testAccIsPrimaryForScope(provider, "boundary_auth_method_oidc.foo", true),
testAccCheckAuthMethodOidcResourceExists(provider, "boundary_auth_method_oidc.foo"),
),
},
importStep("boundary_auth_method_oidc.foo", "client_secret", "is_primary_for_scope"),
},
})
}
func testAccCheckAuthMethodOidcResourceExists(testProvider *schema.Provider, name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("Not found: %s", name)
}
id := rs.Primary.ID
if id == "" {
return fmt.Errorf("No ID is set")
}
md := testProvider.Meta().(*metaData)
amClient := authmethods.NewClient(md.client)
if _, err := amClient.Read(context.Background(), id); err != nil {
return fmt.Errorf("Got an error when reading auth method %q: %w", id, err)
}
return nil
}
}
func testAccCheckAuthMethodOidcResourceDestroy(t *testing.T, testProvider *schema.Provider) resource.TestCheckFunc {
return func(s *terraform.State) error {
if testProvider.Meta() == nil {
t.Fatal("got nil provider metadata")
}
md := testProvider.Meta().(*metaData)
for _, rs := range s.RootModule().Resources {
switch rs.Type {
case "boundary_auth_method_oidc":
id := rs.Primary.ID
amClient := authmethods.NewClient(md.client)
_, err := amClient.Read(context.Background(), id)
if apiErr := api.AsServerError(err); apiErr == nil || apiErr.Response().StatusCode() != http.StatusNotFound {
return fmt.Errorf("didn't get a 404 when reading destroyed auth method %q: %v", id, err)
}
default:
continue
}
}
return nil
}
}
func testAccCheckAuthMethodOidcAttrAryValueSet(testProvider *schema.Provider, name string, key string, strAry []string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("auth method resource not found: %s", name)
}
id := rs.Primary.ID
if id == "" {
return fmt.Errorf("auth method resource ID is not set")
}
md := testProvider.Meta().(*metaData)
amClient := authmethods.NewClient(md.client)
amr, err := amClient.Read(context.Background(), id)
if err != nil {
return fmt.Errorf("Got an error when reading auth method %q: %v", id, err)
}
for _, got := range amr.Item.Attributes[key].([]interface{}) {
ok := false
for _, expected := range strAry {
if strings.TrimSpace(got.(string)) == strings.TrimSpace(expected) {
ok = true
}
}
if !ok {
return fmt.Errorf("value not found in boundary\n %s: %s\n", key, got.(string))
}
}
return nil
}
}
func testAccIsPrimaryForScope(tp *schema.Provider, name string, shouldBePrimary bool) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("auth method resource not found: %s", name)
}
amId := rs.Primary.ID
if amId == "" {
return fmt.Errorf("auth method resource ID is not set")
}
md := tp.Meta().(*metaData)
amClient := authmethods.NewClient(md.client)
amr, err := amClient.Read(context.Background(), amId)
if err != nil {
return fmt.Errorf("Got an error when reading auth method %q: %v", amId, err)
}
amScopeId, ok := amr.GetResponse().Map["scope_id"]
if !ok {
return fmt.Errorf("scope_id unset on auth method resource")
}
scp := scopes.NewClient(md.client)
srr, err := scp.Read(context.Background(), amScopeId.(string))
if err != nil {
return err
}
primaryScopeAuthMethodId, ok := srr.GetResponse().Map["primary_auth_method_id"]
if !ok && shouldBePrimary {
return fmt.Errorf("primary_auth_method_id is not set on scope resource response")
}
if shouldBePrimary {
if primaryScopeAuthMethodId != amId {
return fmt.Errorf("auth method ('%s') should be primary for scope but scope returned '%s' for primary_auth_method_id", amId, primaryScopeAuthMethodId)
}
}
return nil
}
}
@@ -0,0 +1,243 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
"context"
"encoding/json"
"net/http"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/authmethods"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
const (
authmethodTypePassword = "password"
authmethodMinLoginNameLengthKey = "min_login_name_length"
authmethodMinPasswordLengthKey = "min_password_length"
)
func resourceAuthMethodPassword() *schema.Resource {
return &schema.Resource{
Description: "The auth method resource allows you to configure a Boundary auth_method_password.",
CreateContext: resourceAuthMethodPasswordCreate,
ReadContext: resourceAuthMethodPasswordRead,
UpdateContext: resourceAuthMethodPasswordUpdate,
DeleteContext: resourceAuthMethodPasswordDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
IDKey: {
Description: "The ID of the account.",
Type: schema.TypeString,
Computed: true,
},
NameKey: {
Description: "The auth method name. Defaults to the resource name.",
Type: schema.TypeString,
Optional: true,
},
DescriptionKey: {
Description: "The auth method description.",
Type: schema.TypeString,
Optional: true,
},
ScopeIdKey: {
Description: "The scope ID.",
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
TypeKey: {
Description: "The resource type, hardcoded per resource",
Type: schema.TypeString,
Default: authmethodTypePassword,
Optional: true,
},
authmethodMinLoginNameLengthKey: {
Description: "The minimum login name length.",
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
authmethodMinPasswordLengthKey: {
Description: "The minimum password length.",
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
},
}
}
func setFromPasswordAuthMethodResponseMap(d *schema.ResourceData, raw map[string]interface{}) diag.Diagnostics {
d.Set(NameKey, raw[NameKey])
d.Set(DescriptionKey, raw[DescriptionKey])
d.Set(ScopeIdKey, raw[ScopeIdKey])
d.Set(TypeKey, raw[TypeKey])
if attrsVal, ok := raw["attributes"]; ok {
attrs := attrsVal.(map[string]interface{})
minLoginNameLength := attrs[authmethodMinLoginNameLengthKey].(json.Number)
minLoginNameLengthInt, _ := minLoginNameLength.Int64()
d.Set(authmethodMinLoginNameLengthKey, int(minLoginNameLengthInt))
minPasswordLength := attrs[authmethodMinPasswordLengthKey].(json.Number)
minPasswordLengthInt, _ := minPasswordLength.Int64()
d.Set(authmethodMinPasswordLengthKey, int(minPasswordLengthInt))
}
d.SetId(raw["id"].(string))
return nil
}
func resourceAuthMethodPasswordCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
var typeStr string
if typeVal, ok := d.GetOk(TypeKey); ok {
typeStr = typeVal.(string)
} else {
return diag.Errorf("no type provided")
}
opts := []authmethods.Option{}
var minLoginNameLength *int
if minLengthVal, ok := d.GetOk(authmethodMinLoginNameLengthKey); ok {
minLength := minLengthVal.(int)
minLoginNameLength = &minLength
}
if minLoginNameLength != nil {
opts = append(opts, authmethods.WithPasswordAuthMethodMinLoginNameLength(uint32(*minLoginNameLength)))
}
var minPasswordLength *int
if minLengthVal, ok := d.GetOk(authmethodMinPasswordLengthKey); ok {
minLength := minLengthVal.(int)
minPasswordLength = &minLength
}
if minPasswordLength != nil {
opts = append(opts, authmethods.WithPasswordAuthMethodMinPasswordLength(uint32(*minPasswordLength)))
}
nameVal, ok := d.GetOk(NameKey)
if ok {
nameStr := nameVal.(string)
opts = append(opts, authmethods.WithName(nameStr))
}
descVal, ok := d.GetOk(DescriptionKey)
if ok {
descStr := descVal.(string)
opts = append(opts, authmethods.WithDescription(descStr))
}
var scopeId string
if scopeIdVal, ok := d.GetOk(ScopeIdKey); ok {
scopeId = scopeIdVal.(string)
} else {
return diag.Errorf("no scope ID provided")
}
amClient := authmethods.NewClient(md.client)
amcr, err := amClient.Create(ctx, typeStr, scopeId, opts...)
if err != nil {
return diag.Errorf("error creating auth method: %v", err)
}
if amcr == nil {
return diag.Errorf("nil auth method after create")
}
return setFromPasswordAuthMethodResponseMap(d, amcr.GetResponse().Map)
}
func resourceAuthMethodPasswordRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
amClient := authmethods.NewClient(md.client)
amrr, err := amClient.Read(ctx, d.Id())
if err != nil {
if apiErr := api.AsServerError(err); apiErr.Response().StatusCode() == http.StatusNotFound {
d.SetId("")
return nil
}
return diag.Errorf("error reading auth method: %v", err)
}
if amrr == nil {
return diag.Errorf("auth method nil after read")
}
return setFromPasswordAuthMethodResponseMap(d, amrr.GetResponse().Map)
}
func resourceAuthMethodPasswordUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
amClient := authmethods.NewClient(md.client)
opts := []authmethods.Option{}
if d.HasChange(NameKey) {
opts = append(opts, authmethods.DefaultName())
nameVal, ok := d.GetOk(NameKey)
if ok {
opts = append(opts, authmethods.WithName(nameVal.(string)))
}
}
if d.HasChange(DescriptionKey) {
opts = append(opts, authmethods.DefaultDescription())
descVal, ok := d.GetOk(DescriptionKey)
if ok {
opts = append(opts, authmethods.WithDescription(descVal.(string)))
}
}
if d.HasChange(authmethodMinLoginNameLengthKey) {
opts = append(opts, authmethods.DefaultPasswordAuthMethodMinLoginNameLength())
minLengthVal, ok := d.GetOk(authmethodMinLoginNameLengthKey)
if ok {
opts = append(opts, authmethods.WithPasswordAuthMethodMinLoginNameLength(uint32(minLengthVal.(int))))
}
}
if d.HasChange(authmethodMinPasswordLengthKey) {
opts = append(opts, authmethods.DefaultPasswordAuthMethodMinPasswordLength())
minLengthVal, ok := d.GetOk(authmethodMinPasswordLengthKey)
if ok {
opts = append(opts, authmethods.WithPasswordAuthMethodMinPasswordLength(uint32(minLengthVal.(int))))
}
}
if len(opts) > 0 {
opts = append(opts, authmethods.WithAutomaticVersioning(true))
amur, err := amClient.Update(ctx, d.Id(), 0, opts...)
if err != nil {
return diag.Errorf("error updating auth method: %v", err)
}
return setFromPasswordAuthMethodResponseMap(d, amur.GetResponse().Map)
}
return nil
}
func resourceAuthMethodPasswordDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
md := meta.(*metaData)
amClient := authmethods.NewClient(md.client)
_, err := amClient.Delete(ctx, d.Id())
if err != nil {
return diag.Errorf("error deleting auth method: %v", err)
}
return nil
}
@@ -0,0 +1,130 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
"context"
"fmt"
"net/http"
"testing"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/authmethods"
"github.com/hashicorp/boundary/testing/controller"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)
const (
fooAuthMethodDesc = "test auth method"
fooAuthMethodDescUpdate = "test auth method update"
)
var (
fooAuthMethod = fmt.Sprintf(`
resource "boundary_auth_method_password" "foo" {
name = "test"
description = "%s"
type = "password"
scope_id = boundary_scope.org1.id
depends_on = [boundary_role.org1_admin]
}`, fooAuthMethodDesc)
fooAuthMethodUpdate = fmt.Sprintf(`
resource "boundary_auth_method_password" "foo" {
name = "test"
description = "%s"
type = "password"
scope_id = boundary_scope.org1.id
depends_on = [boundary_role.org1_admin]
}`, fooAuthMethodDescUpdate)
)
func TestAccAuthMethodPassword(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),
CheckDestroy: testAccCheckAuthMethodResourceDestroy(t, provider),
Steps: []resource.TestStep{
{
// create
Config: testConfig(url, fooOrg, fooAuthMethod),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("boundary_auth_method_password.foo", "description", fooAuthMethodDesc),
resource.TestCheckResourceAttr("boundary_auth_method_password.foo", "name", "test"),
resource.TestCheckResourceAttr("boundary_auth_method_password.foo", "type", "password"),
testAccCheckAuthMethodResourceExists(provider, "boundary_auth_method_password.foo"),
),
},
importStep("boundary_auth_method_password.foo"),
{
// update
Config: testConfig(url, fooOrg, fooAuthMethodUpdate),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("boundary_auth_method_password.foo", "description", fooAuthMethodDescUpdate),
resource.TestCheckResourceAttr("boundary_auth_method_password.foo", "name", "test"),
resource.TestCheckResourceAttr("boundary_auth_method_password.foo", "type", "password"),
testAccCheckAuthMethodResourceExists(provider, "boundary_auth_method_password.foo"),
),
},
importStep("boundary_auth_method_password.foo"),
},
})
}
func testAccCheckAuthMethodResourceExists(testProvider *schema.Provider, name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("Not found: %s", name)
}
id := rs.Primary.ID
if id == "" {
return fmt.Errorf("No ID is set")
}
md := testProvider.Meta().(*metaData)
amClient := authmethods.NewClient(md.client)
if _, err := amClient.Read(context.Background(), id); err != nil {
return fmt.Errorf("Got an error when reading auth method %q: %w", id, err)
}
return nil
}
}
func testAccCheckAuthMethodResourceDestroy(t *testing.T, testProvider *schema.Provider) resource.TestCheckFunc {
return func(s *terraform.State) error {
if testProvider.Meta() == nil {
t.Fatal("got nil provider metadata")
}
md := testProvider.Meta().(*metaData)
for _, rs := range s.RootModule().Resources {
switch rs.Type {
case "boundary_auth_method_password":
id := rs.Primary.ID
amClient := authmethods.NewClient(md.client)
_, err := amClient.Read(context.Background(), id)
if apiErr := api.AsServerError(err); apiErr == nil || apiErr.Response().StatusCode() != http.StatusNotFound {
return fmt.Errorf("didn't get a 404 when reading destroyed auth method %q: %v", id, err)
}
default:
continue
}
}
return nil
}
}
Loaded 100 of 190 files, more files were not shown because too many files have changed in this diff. Show more