Skip to content

Commit bca1710

Browse files
authored
Merge pull request #103 from planetscale/joem/align-token-env-vars
chore: align service token env vars with pscale cli
2 parents 7f3c4ba + 7998965 commit bca1710

7 files changed

Lines changed: 62 additions & 30 deletions

File tree

.github/workflows/test-extensive.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ jobs:
7676
terraform_wrapper: false
7777
- run: make testacc
7878
env:
79-
PLANETSCALE_SERVICE_TOKEN_NAME: ${{ secrets.PLANETSCALE_SERVICE_TOKEN_NAME }}
79+
PLANETSCALE_SERVICE_TOKEN_ID: ${{ secrets.PLANETSCALE_SERVICE_TOKEN_ID }}
8080
PLANETSCALE_SERVICE_TOKEN: ${{ secrets.PLANETSCALE_SERVICE_TOKEN }}
8181
timeout-minutes: 10
8282

@@ -108,6 +108,6 @@ jobs:
108108
tofu_wrapper: false
109109
- run: make testacc
110110
env:
111-
PLANETSCALE_SERVICE_TOKEN_NAME: ${{ secrets.PLANETSCALE_SERVICE_TOKEN_NAME }}
111+
PLANETSCALE_SERVICE_TOKEN_ID: ${{ secrets.PLANETSCALE_SERVICE_TOKEN_ID }}
112112
PLANETSCALE_SERVICE_TOKEN: ${{ secrets.PLANETSCALE_SERVICE_TOKEN }}
113113
timeout-minutes: 10

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ terraform {
2222
}
2323
```
2424

25-
You must then configure the provider to either use a service token, or an access token. Either can be configured in the provider config block, or via env vars (`PLANETSCALE_SERVICE_TOKEN_NAME` and `PLANETSCALE_SERVICE_TOKEN`, or `PLANETSCALE_ACCESS_TOKEN`):
25+
You must then configure the provider to either use a service token, or an access token. Either can be configured in the provider config block, or via env vars (`PLANETSCALE_SERVICE_TOKEN_ID` and `PLANETSCALE_SERVICE_TOKEN`, or `PLANETSCALE_ACCESS_TOKEN`):
2626

2727
```hcl
2828
provider "planetscale" {
2929
# use a service token
30-
service_token_name = "..." # ID of the service token to use, e.g "8fbddg0zlq0r"
31-
service_token = "..." # Secret for the service token.
30+
service_token_id = "..." # ID of the service token to use, e.g "8fbddg0zlq0r"
31+
service_token = "..." # Secret for the service token.
3232
3333
# or use an access token
3434
access_token = "..." # Secret for the access token.
@@ -48,7 +48,7 @@ Contributions should follow this workflow, or integrate with it.
4848

4949
### Tests
5050

51-
You will need to set either `PLANETSCALE_ACCESS_TOKEN` or `PLANETSCALE_SERVICE_TOKEN_NAME` and `PLANETSCALE_SERVICE_TOKEN` to run acceptance tests.
51+
You will need to set either `PLANETSCALE_ACCESS_TOKEN` or `PLANETSCALE_SERVICE_TOKEN_ID` and `PLANETSCALE_SERVICE_TOKEN` to run acceptance tests.
5252

5353
The org to create resources under is currently hardcoded in the tests. You may need to change this to match your own org. Acceptance tests create real resources in your PlanetScale org.
5454

docs/index.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ description: |-
77
access token credentials, configured or stored in the environment variable PLANETSCALE_ACCESS_TOKENservice token credentials, configured or stored in the environment variables PLANETSCALE_SERVICE_TOKEN_NAME and PLANETSCALE_SERVICE_TOKEN
88
Note that the provider is not production ready and only for early testing at this time.
99
Known limitations:
10-
Support for deployments, deploy queues, deploy requests and reverts is not implemented at this time. If you have a use case for it, please let us know in the repository issues.Service tokens don't immediately have read/write access on the resources they create. For now, access must be granted via the UI or via the CLI (pscale service-token add-access)
10+
Support for deployments, deploy queues, deploy requests and reverts is not implemented at this time. If you have a use case for it, please let us know in the repository issues.When using service tokens (recommended), ensure the token has the create_databases organization-level permission. This allows terraform to create new databases and automatically grants the token all other permissions on the databases created by the token.
1111
---
1212

1313
# planetscale Provider
@@ -21,7 +21,7 @@ Note that the provider is not production ready and only for early testing at thi
2121

2222
Known limitations:
2323
- Support for deployments, deploy queues, deploy requests and reverts is not implemented at this time. If you have a use case for it, please let us know in the repository issues.
24-
- Service tokens don't immediately have read/write access on the resources they create. For now, access must be granted via the UI or via the CLI (`pscale service-token add-access`)
24+
- When using service tokens (recommended), ensure the token has the `create_databases` organization-level permission. This allows terraform to create new databases and automatically grants the token all other permissions on the databases created by the token.
2525

2626
## Example Usage
2727

@@ -47,4 +47,5 @@ provider "planetscale" {
4747
- `access_token` (String, Sensitive) Name of the service token to use. Alternatively, use `PLANETSCALE_SERVICE_TOKEN_NAME`. Mutually exclusive with `service_token_name` and `service_token`.
4848
- `endpoint` (String) If set, points the API client to a different endpoint than `https:://api.planetscale.com/v1`.
4949
- `service_token` (String, Sensitive) Value of the service token to use. Alternatively, use `PLANETSCALE_SERVICE_TOKEN`. Mutually exclusive with `access_token`.
50-
- `service_token_name` (String) Name of the service token to use. Alternatively, use `PLANETSCALE_SERVICE_TOKEN_NAME`. Mutually exclusive with `access_token`.
50+
- `service_token_id` (String) ID of the service token to use. Alternatively, use `PLANETSCALE_SERVICE_TOKEN_ID`. Mutually exclusive with `access_token`.
51+
- `service_token_name` (String, Deprecated) Name of the service token to use. Alternatively, use `PLANETSCALE_SERVICE_TOKEN_NAME`. Mutually exclusive with `access_token`. (Deprecated, use `service_token_id` instead)

docs/resources/database.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ subcategory: ""
55
description: |-
66
A PlanetScale database.
77
Known limitations:
8-
When the provider is configured with a service token, the service token needs to manually be granted permission on this database resource. This can be done in the UI or via the CLI (pscale service-token add-access).
8+
When using service tokens (recommended), ensure the token has the create_databases organization-level permission. This allows terraform to create new databases and automatically grants the token all other permissions on the databases created by the token.
99
---
1010

1111
# planetscale_database (Resource)
1212

1313
A PlanetScale database.
1414

1515
Known limitations:
16-
- When the provider is configured with a service token, the service token needs to manually be granted permission on this database resource. This can be done in the UI or via the CLI (`pscale service-token add-access`).
16+
- When using service tokens (recommended), ensure the token has the `create_databases` organization-level permission. This allows terraform to create new databases and automatically grants the token all other permissions on the databases created by the token.
1717

1818
## Example Usage
1919

internal/provider/database_resource.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ func (r *databaseResource) Schema(ctx context.Context, req resource.SchemaReques
132132
MarkdownDescription: `A PlanetScale database.
133133
134134
Known limitations:
135-
- When the provider is configured with a service token, the service token needs to manually be granted permission on this database resource. This can be done in the UI or via the CLI (` + "`pscale service-token add-access`" + `).`,
135+
- When using service tokens (recommended), ensure the token has the ` + "`create_databases`" + ` organization-level permission. This allows terraform to create new databases and automatically grants the token all other permissions on the databases created by the token.`,
136136
Attributes: map[string]schema.Attribute{
137137
"organization": schema.StringAttribute{
138138
Description: "The organization this database belongs to.",

internal/provider/provider.go

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ type PlanetScaleProviderModel struct {
3535

3636
AccessToken types.String `tfsdk:"access_token"`
3737

38-
ServiceTokenName types.String `tfsdk:"service_token_name"`
38+
ServiceTokenID types.String `tfsdk:"service_token_id"` // new preferred field
39+
ServiceTokenName types.String `tfsdk:"service_token_name"` // deprecated
3940
ServiceTokenValue types.String `tfsdk:"service_token"`
4041
}
4142

@@ -62,7 +63,7 @@ Note that the provider is not production ready and only for early testing at thi
6263
6364
Known limitations:
6465
- Support for deployments, deploy queues, deploy requests and reverts is not implemented at this time. If you have a use case for it, please let us know in the repository issues.
65-
- Service tokens don't immediately have read/write access on the resources they create. For now, access must be granted via the UI or via the CLI (` + "`pscale service-token add-access`" + `)`,
66+
- When using service tokens (recommended), ensure the token has the ` + "`create_databases`" + ` organization-level permission. This allows terraform to create new databases and automatically grants the token all other permissions on the databases created by the token.`,
6667
Attributes: map[string]schema.Attribute{
6768
"endpoint": schema.StringAttribute{
6869
MarkdownDescription: "If set, points the API client to a different endpoint than `https:://api.planetscale.com/v1`.",
@@ -74,14 +75,25 @@ Known limitations:
7475
Sensitive: true,
7576
Validators: []validator.String{
7677
stringvalidator.ConflictsWith(path.MatchRoot("service_token_name")),
78+
stringvalidator.ConflictsWith(path.MatchRoot("service_token_id")),
7779
stringvalidator.ConflictsWith(path.MatchRoot("service_token")),
7880
},
7981
},
82+
"service_token_id": schema.StringAttribute{
83+
MarkdownDescription: "ID of the service token to use. Alternatively, use `PLANETSCALE_SERVICE_TOKEN_ID`. Mutually exclusive with `access_token`.",
84+
Optional: true,
85+
Validators: []validator.String{
86+
stringvalidator.ConflictsWith(path.MatchRoot("access_token")),
87+
stringvalidator.ConflictsWith(path.MatchRoot("service_token_name")),
88+
},
89+
},
8090
"service_token_name": schema.StringAttribute{
81-
MarkdownDescription: "Name of the service token to use. Alternatively, use `PLANETSCALE_SERVICE_TOKEN_NAME`. Mutually exclusive with `access_token`.",
91+
MarkdownDescription: "Name of the service token to use. Alternatively, use `PLANETSCALE_SERVICE_TOKEN_NAME`. Mutually exclusive with `access_token`. (Deprecated, use `service_token_id` instead)",
8292
Optional: true,
93+
DeprecationMessage: "Use service_token_id instead. This field will be removed in a future version.",
8394
Validators: []validator.String{
8495
stringvalidator.ConflictsWith(path.MatchRoot("access_token")),
96+
stringvalidator.ConflictsWith(path.MatchRoot("service_token_id")),
8597
},
8698
},
8799
"service_token": schema.StringAttribute{
@@ -128,31 +140,50 @@ func (p *PlanetScaleProvider) Configure(ctx context.Context, req provider.Config
128140
}
129141
var (
130142
accessToken = stringValueOrDefault(data.AccessToken, os.Getenv("PLANETSCALE_ACCESS_TOKEN"))
143+
serviceTokenID = stringValueOrDefault(data.ServiceTokenID, os.Getenv("PLANETSCALE_SERVICE_TOKEN_ID"))
131144
serviceTokenName = stringValueOrDefault(data.ServiceTokenName, os.Getenv("PLANETSCALE_SERVICE_TOKEN_NAME"))
132145
serviceTokenValue = stringValueOrDefault(data.ServiceTokenValue, os.Getenv("PLANETSCALE_SERVICE_TOKEN"))
133146
)
147+
148+
// Warn if the deprecated PLANETSCALE_SERVICE_TOKEN_NAME env var is used.
149+
// Adding this to `resp.Diagnostics` ensures it will be printed during typical
150+
// terraform operations, whereas logging with `tflog.Warn()` will only show if the
151+
// users specifies the `TF_LOG` env var.
152+
if serviceTokenName != "" && serviceTokenID == "" {
153+
resp.Diagnostics.AddWarning(
154+
"Deprecated Configuration",
155+
"PLANETSCALE_SERVICE_TOKEN_NAME is deprecated. Please use PLANETSCALE_SERVICE_TOKEN_ID instead.",
156+
)
157+
}
158+
159+
// Use serviceTokenID if available, fall back to serviceTokenName
160+
effectiveTokenID := serviceTokenID
161+
if effectiveTokenID == "" {
162+
effectiveTokenID = serviceTokenName
163+
}
164+
134165
switch {
135-
case accessToken != "" && serviceTokenName == "" && serviceTokenValue == "":
166+
case accessToken != "" && effectiveTokenID == "" && serviceTokenValue == "":
136167
tok := &oauth2.Token{AccessToken: accessToken}
137168
rt = &oauth2.Transport{Base: initrt, Source: oauth2.StaticTokenSource(tok)}
138-
case accessToken == "" && serviceTokenName != "" && serviceTokenValue != "":
169+
case accessToken == "" && effectiveTokenID != "" && serviceTokenValue != "":
139170
rt = roundTripperFunc(func(r *http.Request) (*http.Response, error) {
140-
r.Header.Set("Authorization", serviceTokenName+":"+serviceTokenValue)
171+
r.Header.Set("Authorization", effectiveTokenID+":"+serviceTokenValue)
141172
return initrt.RoundTrip(r)
142173
})
143-
case accessToken == "" && serviceTokenName == "" && serviceTokenValue == "":
174+
case accessToken == "" && effectiveTokenID == "" && serviceTokenValue == "":
144175
resp.Diagnostics.AddError("Missing PlanetScale credentials.",
145176
"You must set either of:\n"+
146177
"- `PLANETSCALE_ACCESS_TOKEN`\n"+
147-
"- `PLANETSCALE_SERVICE_TOKEN_NAME` and `PLANETSCALE_SERVICE_TOKEN`")
148-
case accessToken == "" && serviceTokenName != "" && serviceTokenValue == "",
149-
accessToken == "" && serviceTokenName == "" && serviceTokenValue != "":
178+
"- `PLANETSCALE_SERVICE_TOKEN_ID` and `PLANETSCALE_SERVICE_TOKEN`")
179+
case accessToken == "" && effectiveTokenID != "" && serviceTokenValue == "",
180+
accessToken == "" && effectiveTokenID == "" && serviceTokenValue != "":
150181
resp.Diagnostics.AddError("Incomplete PlanetScale service token credentials.",
151-
"Both of `PLANETSCALE_SERVICE_TOKEN_NAME` and `PLANETSCALE_SERVICE_TOKEN` must be set.")
182+
"Both of `PLANETSCALE_SERVICE_TOKEN_ID` and `PLANETSCALE_SERVICE_TOKEN` must be set.")
152183
default:
153184
resp.Diagnostics.AddError("Ambiguous PlanetScale credentials.", "You must set only an access token or a service token, but not both:\n"+
154185
"- `PLANETSCALE_ACCESS_TOKEN`\n"+
155-
"- `PLANETSCALE_SERVICE_TOKEN_NAME` and `PLANETSCALE_SERVICE_TOKEN`")
186+
"- `PLANETSCALE_SERVICE_TOKEN_ID` and `PLANETSCALE_SERVICE_TOKEN`")
156187
}
157188
if resp.Diagnostics.HasError() {
158189
return

internal/provider/provider_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ var testAccAPIClient *planetscale.Client
2828
func testAccPreCheck(t *testing.T) {
2929
var (
3030
accessToken = os.Getenv("PLANETSCALE_ACCESS_TOKEN")
31-
serviceTokenName = os.Getenv("PLANETSCALE_SERVICE_TOKEN_NAME")
31+
serviceTokenID = os.Getenv("PLANETSCALE_SERVICE_TOKEN_ID")
3232
serviceTokenValue = os.Getenv("PLANETSCALE_SERVICE_TOKEN")
3333
)
3434
switch {
3535
case accessToken != "":
36-
case serviceTokenName != "" && serviceTokenValue != "":
36+
case serviceTokenID != "" && serviceTokenValue != "":
3737
default:
38-
t.Fatalf("must have either PLANETSCALE_ACCESS_TOKEN or both of (PLANETSCALE_SERVICE_TOKEN_NAME, PLANETSCALE_SERVICE_TOKEN)")
38+
t.Fatalf("must have either PLANETSCALE_ACCESS_TOKEN or both of (PLANETSCALE_SERVICE_TOKEN_ID, PLANETSCALE_SERVICE_TOKEN)")
3939
}
4040

4141
// TODO: factor client creation out of the provider.go Configure() func so we can
@@ -51,11 +51,11 @@ func testAccPreCheck(t *testing.T) {
5151
testAccAPIClient = planetscale.NewClient(&http.Client{Transport: rt}, nil)
5252
}
5353

54-
serviceTokenName := os.Getenv("PLANETSCALE_SERVICE_TOKEN_NAME")
54+
serviceTokenID := os.Getenv("PLANETSCALE_SERVICE_TOKEN_ID")
5555
serviceTokenValue := os.Getenv("PLANETSCALE_SERVICE_TOKEN")
56-
if serviceTokenName != "" && serviceTokenValue != "" {
56+
if serviceTokenID != "" && serviceTokenValue != "" {
5757
rt := roundTripperFunc(func(r *http.Request) (*http.Response, error) {
58-
r.Header.Set("Authorization", serviceTokenName+":"+serviceTokenValue)
58+
r.Header.Set("Authorization", serviceTokenID+":"+serviceTokenValue)
5959
return http.DefaultTransport.RoundTrip(r)
6060
})
6161
testAccAPIClient = planetscale.NewClient(&http.Client{Transport: rt}, nil)

0 commit comments

Comments
 (0)