Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2f64778c5 | ||
|
|
7c3959d981 |
No files matched your search
@@ -24,6 +24,9 @@ on: [workflow_dispatch, push]
|
||||
env:
|
||||
PKG_NAME: "terraform-provider-boundary"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
# Detects the Go version to use for builds.
|
||||
get-go-version:
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
Canonical reference for changes, improvements, and bugfixes for the Boundary Terraform provider.
|
||||
|
||||
## Next
|
||||
## 1.6.1 (Jul 24th, 2026)
|
||||
|
||||
### New and Improved
|
||||
|
||||
* Adds support to enable set/remove alias suffix and aliases at project scope
|
||||
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/824))
|
||||
|
||||
## 1.6.0 (Jul 8th, 2026)
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
page_title: "boundary_alias_target Resource - terraform-provider-boundary"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
The target alias resource allows you to configure a Boundary target alias.
|
||||
The target alias resource allows you to configure a Boundary target alias at project and global scopes.
|
||||
---
|
||||
|
||||
# boundary_alias_target (Resource)
|
||||
|
||||
The target alias resource allows you to configure a Boundary target alias.
|
||||
The target alias resource allows you to configure a Boundary target alias at project and global scopes.
|
||||
|
||||
## Example Usage
|
||||
|
||||
@@ -28,6 +28,16 @@ resource "boundary_scope" "project" {
|
||||
auto_create_admin_role = true
|
||||
}
|
||||
|
||||
resource "boundary_scope_alias_suffix" "org" {
|
||||
scope_id = boundary_scope.org.id
|
||||
alias_suffix = "org"
|
||||
}
|
||||
|
||||
resource "boundary_scope_alias_suffix" "project" {
|
||||
scope_id = boundary_scope.project.id
|
||||
alias_suffix = "projectone"
|
||||
}
|
||||
|
||||
resource "boundary_host_catalog_static" "foo" {
|
||||
name = "test"
|
||||
description = "test catalog"
|
||||
@@ -75,6 +85,19 @@ resource "boundary_alias_target" "example_alias_target" {
|
||||
destination_id = boundary_target.foo.id
|
||||
authorize_session_host_id = boundary_host_static.bar.id
|
||||
}
|
||||
|
||||
resource "boundary_alias_target" "example_alias_target_project" {
|
||||
name = "example_alias_target_project"
|
||||
description = "Example project-scoped alias to target foo"
|
||||
scope_id = boundary_scope.project.id
|
||||
value = "prodops.projectone.org"
|
||||
destination_id = boundary_target.foo.id
|
||||
authorize_session_host_id = boundary_host_static.bar.id
|
||||
depends_on = [
|
||||
boundary_scope_alias_suffix.org,
|
||||
boundary_scope_alias_suffix.project,
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
@@ -82,7 +105,7 @@ resource "boundary_alias_target" "example_alias_target" {
|
||||
|
||||
### Required
|
||||
|
||||
- `scope_id` (String) The scope ID.
|
||||
- `scope_id` (String) The scope ID. Org scopes are not supported for aliases.
|
||||
- `value` (String) The value of the alias.
|
||||
|
||||
### Optional
|
||||
@@ -105,4 +128,5 @@ The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/c
|
||||
|
||||
```shell
|
||||
terraform import boundary_alias_target.example_alias_target <my-id>
|
||||
terraform import boundary_alias_target.example_alias_target_project <my-id>
|
||||
```
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "boundary_scope_alias_suffix Resource - terraform-provider-boundary"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
The scope alias suffix resource allows you to set an alias suffix for an org or project scope. Global scopes are not valid for alias suffix operations.
|
||||
---
|
||||
|
||||
# boundary_scope_alias_suffix (Resource)
|
||||
|
||||
The scope alias suffix resource allows you to set an alias suffix for an org or project scope. Global scopes are not valid for alias suffix operations.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```terraform
|
||||
resource "boundary_scope" "global" {
|
||||
global_scope = true
|
||||
scope_id = "global"
|
||||
}
|
||||
|
||||
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 project"
|
||||
scope_id = boundary_scope.org.id
|
||||
auto_create_admin_role = true
|
||||
}
|
||||
|
||||
resource "boundary_scope_alias_suffix" "org_suffix" {
|
||||
scope_id = boundary_scope.org.id
|
||||
alias_suffix = "org"
|
||||
}
|
||||
|
||||
resource "boundary_scope_alias_suffix" "project_suffix" {
|
||||
scope_id = boundary_scope.project.id
|
||||
alias_suffix = "projectone"
|
||||
}
|
||||
```
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `alias_suffix` (String) The alias suffix value for this scope.
|
||||
- `scope_id` (String) The scope ID. Alias suffixes are supported for org and project scopes.
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
|
||||
## Import
|
||||
|
||||
Import is supported using the following syntax:
|
||||
|
||||
The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example:
|
||||
|
||||
```shell
|
||||
terraform import boundary_scope_alias_suffix.org_suffix <scope-id>
|
||||
```
|
||||
@@ -1 +1,2 @@
|
||||
terraform import boundary_alias_target.example_alias_target <my-id>
|
||||
terraform import boundary_alias_target.example_alias_target_project <my-id>
|
||||
@@ -13,6 +13,16 @@ resource "boundary_scope" "project" {
|
||||
auto_create_admin_role = true
|
||||
}
|
||||
|
||||
resource "boundary_scope_alias_suffix" "org" {
|
||||
scope_id = boundary_scope.org.id
|
||||
alias_suffix = "org"
|
||||
}
|
||||
|
||||
resource "boundary_scope_alias_suffix" "project" {
|
||||
scope_id = boundary_scope.project.id
|
||||
alias_suffix = "projectone"
|
||||
}
|
||||
|
||||
resource "boundary_host_catalog_static" "foo" {
|
||||
name = "test"
|
||||
description = "test catalog"
|
||||
@@ -59,4 +69,17 @@ resource "boundary_alias_target" "example_alias_target" {
|
||||
value = "example.bar.foo.boundary"
|
||||
destination_id = boundary_target.foo.id
|
||||
authorize_session_host_id = boundary_host_static.bar.id
|
||||
}
|
||||
}
|
||||
|
||||
resource "boundary_alias_target" "example_alias_target_project" {
|
||||
name = "example_alias_target_project"
|
||||
description = "Example project-scoped alias to target foo"
|
||||
scope_id = boundary_scope.project.id
|
||||
value = "prodops.projectone.org"
|
||||
destination_id = boundary_target.foo.id
|
||||
authorize_session_host_id = boundary_host_static.bar.id
|
||||
depends_on = [
|
||||
boundary_scope_alias_suffix.org,
|
||||
boundary_scope_alias_suffix.project,
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
terraform import boundary_scope_alias_suffix.org_suffix <scope-id>
|
||||
@@ -0,0 +1,29 @@
|
||||
resource "boundary_scope" "global" {
|
||||
global_scope = true
|
||||
scope_id = "global"
|
||||
}
|
||||
|
||||
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 project"
|
||||
scope_id = boundary_scope.org.id
|
||||
auto_create_admin_role = true
|
||||
}
|
||||
|
||||
resource "boundary_scope_alias_suffix" "org_suffix" {
|
||||
scope_id = boundary_scope.org.id
|
||||
alias_suffix = "org"
|
||||
}
|
||||
|
||||
resource "boundary_scope_alias_suffix" "project_suffix" {
|
||||
scope_id = boundary_scope.project.id
|
||||
alias_suffix = "projectone"
|
||||
}
|
||||
@@ -192,16 +192,16 @@ require (
|
||||
go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
||||
go.opentelemetry.io/otel v1.41.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.41.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.41.0 // indirect
|
||||
go.opentelemetry.io/otel v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.43.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect
|
||||
golang.org/x/mod v0.37.0 // indirect
|
||||
golang.org/x/net v0.56.0 // indirect
|
||||
golang.org/x/oauth2 v0.35.0 // indirect
|
||||
golang.org/x/oauth2 v0.36.0 // indirect
|
||||
golang.org/x/sync v0.22.0 // indirect
|
||||
golang.org/x/sys v0.47.0 // indirect
|
||||
golang.org/x/term v0.45.0 // indirect
|
||||
@@ -210,9 +210,9 @@ require (
|
||||
golang.org/x/tools v0.47.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect
|
||||
google.golang.org/grpc v1.79.3 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect
|
||||
google.golang.org/grpc v1.82.1 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
@@ -545,16 +545,16 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
|
||||
go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c=
|
||||
go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE=
|
||||
go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ=
|
||||
go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||
go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0=
|
||||
go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis=
|
||||
go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
|
||||
go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
|
||||
go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
|
||||
go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
|
||||
go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
|
||||
go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
|
||||
go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
|
||||
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
@@ -611,8 +611,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
|
||||
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
|
||||
golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
||||
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -685,8 +685,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
||||
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
@@ -696,17 +696,17 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4=
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
|
||||
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||
google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
|
||||
google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
|
||||
@@ -125,6 +125,7 @@ func New() *schema.Provider {
|
||||
"boundary_host_set_static": resourceHostSetStatic(),
|
||||
"boundary_host_set_plugin": resourceHostSetPlugin(),
|
||||
"boundary_policy_storage": resourcePolicyStorage(),
|
||||
"boundary_scope_alias_suffix": resourceScopeAliasSuffix(),
|
||||
"boundary_scope_policy_attachment": resourceScopePolicyAttachment(),
|
||||
"boundary_role": resourceRole(),
|
||||
"boundary_scope": resourceScope(),
|
||||
|
||||
@@ -5,7 +5,9 @@ package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/aliases"
|
||||
@@ -17,11 +19,15 @@ const (
|
||||
aliasTypeTarget = "target"
|
||||
|
||||
aliasTargetAuthorizeSessionHostIdKey = "authorize_session_host_id"
|
||||
|
||||
globalScopeId = "global"
|
||||
orgScopePrefix = "o_"
|
||||
projectScopePrefix = "p_"
|
||||
)
|
||||
|
||||
func resourceAliasTarget() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Description: "The target alias resource allows you to configure a Boundary target alias.",
|
||||
Description: "The target alias resource allows you to configure a Boundary target alias at project and global scopes.",
|
||||
|
||||
CreateContext: resourceTargetAliasCreate,
|
||||
ReadContext: resourceTargetAliasRead,
|
||||
@@ -48,7 +54,7 @@ func resourceAliasTarget() *schema.Resource {
|
||||
Optional: true,
|
||||
},
|
||||
ScopeIdKey: {
|
||||
Description: "The scope ID.",
|
||||
Description: "The scope ID. Org scopes are not supported for aliases.",
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
@@ -144,6 +150,10 @@ func resourceTargetAliasCreate(ctx context.Context, d *schema.ResourceData, meta
|
||||
return diag.Errorf("no alias value provided")
|
||||
}
|
||||
|
||||
if err := validateTargetAliasScope(scopeId); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if nameVal, ok := d.GetOk(NameKey); ok {
|
||||
opts = append(opts, aliases.WithName(nameVal.(string)))
|
||||
}
|
||||
@@ -221,7 +231,12 @@ func resourceTargetAliasUpdate(ctx context.Context, d *schema.ResourceData, meta
|
||||
|
||||
if d.HasChange(ValueKey) {
|
||||
if valVal, ok := d.GetOk(ValueKey); ok {
|
||||
opts = append(opts, aliases.WithValue(valVal.(string)))
|
||||
aliasValue := valVal.(string)
|
||||
scopeId := d.Get(ScopeIdKey).(string)
|
||||
if err := validateTargetAliasScope(scopeId); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
opts = append(opts, aliases.WithValue(aliasValue))
|
||||
} else {
|
||||
return diag.Errorf("no value provided")
|
||||
}
|
||||
@@ -267,3 +282,16 @@ func resourceTargetAliasDelete(ctx context.Context, d *schema.ResourceData, meta
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateTargetAliasScope(scopeId string) error {
|
||||
switch {
|
||||
case scopeId == globalScopeId:
|
||||
return nil
|
||||
case strings.HasPrefix(scopeId, projectScopePrefix):
|
||||
return nil
|
||||
case strings.HasPrefix(scopeId, orgScopePrefix):
|
||||
return fmt.Errorf("target aliases are not supported for org scopes; use a project or global scope ID")
|
||||
default:
|
||||
return fmt.Errorf("target aliases are supported only for project and global scopes")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright IBM Corp. 2020, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package provider
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestValidateTargetAliasScope(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
scopeId string
|
||||
wantError bool
|
||||
}{
|
||||
{
|
||||
name: "org scope rejected",
|
||||
scopeId: "o_1234567890",
|
||||
wantError: true,
|
||||
},
|
||||
{
|
||||
name: "global scope allowed",
|
||||
scopeId: globalScopeId,
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "project scope allowed",
|
||||
scopeId: "p_1234567890",
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "unknown scope type rejected",
|
||||
scopeId: "s_1234567890",
|
||||
wantError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
err := validateTargetAliasScope(tt.scopeId)
|
||||
if tt.wantError && err == nil {
|
||||
t.Fatal("expected error but got nil")
|
||||
}
|
||||
if !tt.wantError && err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
// Copyright IBM Corp. 2020, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/scopes"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
const (
|
||||
aliasSuffixKey = "alias_suffix"
|
||||
)
|
||||
|
||||
func resourceScopeAliasSuffix() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Description: "The scope alias suffix resource allows you to set an alias suffix for an org or project scope. " +
|
||||
"Global scopes are not valid for alias suffix operations.",
|
||||
|
||||
CreateContext: resourceScopeAliasSuffixCreate,
|
||||
UpdateWithoutTimeout: resourceScopeAliasSuffixUpdate,
|
||||
ReadWithoutTimeout: resourceScopeAliasSuffixRead,
|
||||
DeleteWithoutTimeout: resourceScopeAliasSuffixDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
StateContext: schema.ImportStatePassthroughContext,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
ScopeIdKey: {
|
||||
Description: "The scope ID. Alias suffixes are supported for org and project scopes.",
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
aliasSuffixKey: {
|
||||
Description: "The alias suffix value for this scope.",
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceScopeAliasSuffixCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
md := meta.(*metaData)
|
||||
scp := scopes.NewClient(md.client)
|
||||
opts := []scopes.Option{scopes.WithAutomaticVersioning(true)}
|
||||
|
||||
scopeId, err := scopeIdFromAliasSuffixResourceData(d)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if err := validateAliasSuffixScope(scopeId); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
var aliasSuffix string
|
||||
if aliasSuffixVal, ok := d.GetOk(aliasSuffixKey); ok {
|
||||
aliasSuffix = aliasSuffixVal.(string)
|
||||
} else {
|
||||
return diag.Errorf("no alias suffix provided")
|
||||
}
|
||||
|
||||
if _, err := scp.SetAliasSuffix(ctx, scopeId, 0, aliasSuffix, opts...); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if err := setScopeAliasSuffixState(d, scopeId, aliasSuffix); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceScopeAliasSuffixRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
md := meta.(*metaData)
|
||||
scp := scopes.NewClient(md.client)
|
||||
|
||||
scopeId, err := scopeIdFromAliasSuffixResourceData(d)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
s, err := scp.Read(ctx, scopeId)
|
||||
if err != nil {
|
||||
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound {
|
||||
// the scope is gone, destroy this resource
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
return diag.Errorf("error reading scope: %v", err)
|
||||
}
|
||||
if s == nil {
|
||||
return diag.Errorf("scope nil after read")
|
||||
}
|
||||
if s.GetResponse() == nil {
|
||||
return diag.Errorf("scope response nil after read")
|
||||
}
|
||||
|
||||
serverAliasSuffix, err := aliasSuffixFromScopeResponseMap(s.GetResponse().Map)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if serverAliasSuffix == "" {
|
||||
// no alias suffix is currently set on this scope, destroy this resource
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := setScopeAliasSuffixState(d, scopeId, serverAliasSuffix); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceScopeAliasSuffixUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
md := meta.(*metaData)
|
||||
scp := scopes.NewClient(md.client)
|
||||
opts := []scopes.Option{scopes.WithAutomaticVersioning(true)}
|
||||
|
||||
scopeId, err := scopeIdFromAliasSuffixResourceData(d)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if err := validateAliasSuffixScope(scopeId); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
var aliasSuffix string
|
||||
if aliasSuffixVal, ok := d.GetOk(aliasSuffixKey); ok {
|
||||
aliasSuffix = aliasSuffixVal.(string)
|
||||
} else {
|
||||
return diag.Errorf("no alias suffix provided")
|
||||
}
|
||||
|
||||
if _, err := scp.SetAliasSuffix(ctx, scopeId, 0, aliasSuffix, opts...); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if err := setScopeAliasSuffixState(d, scopeId, aliasSuffix); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceScopeAliasSuffixDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
md := meta.(*metaData)
|
||||
scp := scopes.NewClient(md.client)
|
||||
opts := []scopes.Option{scopes.WithAutomaticVersioning(true)}
|
||||
|
||||
scopeId, err := scopeIdFromAliasSuffixResourceData(d)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if err := validateAliasSuffixScope(scopeId); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if _, err := scp.RemoveAliasSuffix(ctx, scopeId, 0, opts...); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func aliasSuffixFromScopeResponseMap(raw map[string]interface{}) (string, error) {
|
||||
if raw == nil {
|
||||
return "", fmt.Errorf("scope response map nil after read")
|
||||
}
|
||||
|
||||
aliasSuffixRaw, ok := raw[aliasSuffixKey]
|
||||
if !ok || aliasSuffixRaw == nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
aliasSuffix, ok := aliasSuffixRaw.(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("alias suffix in scope response has unexpected type %T", aliasSuffixRaw)
|
||||
}
|
||||
|
||||
return aliasSuffix, nil
|
||||
}
|
||||
|
||||
func setScopeAliasSuffixState(d *schema.ResourceData, scopeId, aliasSuffix string) error {
|
||||
if err := d.Set(ScopeIdKey, scopeId); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.Set(aliasSuffixKey, aliasSuffix); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// One alias suffix may be set per scope, so scope ID is the stable TF ID.
|
||||
d.SetId(scopeId)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateAliasSuffixScope(scopeId string) error {
|
||||
switch {
|
||||
case strings.HasPrefix(scopeId, orgScopePrefix):
|
||||
return nil
|
||||
case strings.HasPrefix(scopeId, projectScopePrefix):
|
||||
return nil
|
||||
case scopeId == globalScopeId:
|
||||
return fmt.Errorf("alias suffixes are not supported for the global scope; use an org or project scope ID")
|
||||
default:
|
||||
return fmt.Errorf("alias suffixes are supported only for org and project scopes")
|
||||
}
|
||||
}
|
||||
|
||||
func scopeIdFromAliasSuffixResourceData(d *schema.ResourceData) (string, error) {
|
||||
if scopeIdVal, ok := d.GetOk(ScopeIdKey); ok {
|
||||
scopeId := scopeIdVal.(string)
|
||||
if scopeId != "" {
|
||||
return scopeId, nil
|
||||
}
|
||||
}
|
||||
|
||||
id := d.Id()
|
||||
if id == "" {
|
||||
return "", fmt.Errorf("no scope ID provided")
|
||||
}
|
||||
|
||||
// Backward-compatibility for any prior state that used alias_suffix:scope_id.
|
||||
if index := strings.LastIndex(id, ":"); index >= 0 && index < len(id)-1 {
|
||||
return id[index+1:], nil
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
// Copyright IBM Corp. 2020, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package provider
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestValidateAliasSuffixScope(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
scopeId string
|
||||
wantError bool
|
||||
}{
|
||||
{
|
||||
name: "global scope rejected",
|
||||
scopeId: globalScopeId,
|
||||
wantError: true,
|
||||
},
|
||||
{
|
||||
name: "org scope allowed",
|
||||
scopeId: "o_1234567890",
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "project scope allowed",
|
||||
scopeId: "p_1234567890",
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "unknown scope type rejected",
|
||||
scopeId: "s_1234567890",
|
||||
wantError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
err := validateAliasSuffixScope(tt.scopeId)
|
||||
if tt.wantError && err == nil {
|
||||
t.Fatal("expected error but got nil")
|
||||
}
|
||||
if !tt.wantError && err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAliasSuffixFromScopeResponseMap(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("nil map", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := aliasSuffixFromScopeResponseMap(nil)
|
||||
if err == nil {
|
||||
t.Fatal("expected error for nil map")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("missing key", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got, err := aliasSuffixFromScopeResponseMap(map[string]interface{}{})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if got != "" {
|
||||
t.Fatalf("expected empty alias suffix, got %q", got)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("nil value", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got, err := aliasSuffixFromScopeResponseMap(map[string]interface{}{aliasSuffixKey: nil})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if got != "" {
|
||||
t.Fatalf("expected empty alias suffix, got %q", got)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("wrong type", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := aliasSuffixFromScopeResponseMap(map[string]interface{}{aliasSuffixKey: 123})
|
||||
if err == nil {
|
||||
t.Fatal("expected error for non-string alias suffix")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("string value", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got, err := aliasSuffixFromScopeResponseMap(map[string]interface{}{aliasSuffixKey: "example.boundary"})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if got != "example.boundary" {
|
||||
t.Fatalf("unexpected alias suffix: %q", got)
|
||||
}
|
||||
})
|
||||
}
|
||||
+1
-1
@@ -1 +1 @@
|
||||
1.6.0
|
||||
1.6.1
|
||||
Reference in new issue
Block a user