-
Notifications
You must be signed in to change notification settings - Fork 49
tailscale: add oauth client resource #500
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Pull Request Revisions
☑️ AI review skipped for r9 HelpReact with emojis to give feedback on AI-generated reviews:
We'd love to hear from you—reach out anytime at team@review.ai. |
ed1abba
to
f96b113
Compare
"tailscale.com/client/tailscale/v2" | ||
) | ||
|
||
func resourceOAuthClient() *schema.Resource { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking through the consequences of making this a separate resource from tailnet_key
.
tailnet_key
can be imported using just a key ID. In theory, tailnet_key
would allow importing what's actually an OAuth client. Could we run into some weird state inconsistencies if someone does this?
@mpminardi thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should update the tailnet_key
resource to fail if someone tries to import something that is not an auth key?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it can lead to TF state inconsistencies, or well, no inconsistencies worse than what Terraform naturally allows.
Terraform lets you to import the same external resource multiple times for different resource definitions. E.g.:
tf import tailscale_tailnet_key.import1 k1234DEVEL
tf import tailscale_tailnet_key.import2 k1234DEVEL
Is considered perfectly valid and will create 2 state entries for the same resource. So whether tailscale_tailnet_key is extended to support oauth clients or we implement it as a separate resource does not really matter wrt how imports can be misused. From a UX/doc perspective though it felt much cleaner as a distinct resource.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mcoulombe Yeah, I also like it as a separate resource. What I was getting at is that currently, you could import an OAuth client as a tailnet key resource, which feels wrong because an OAuth client is not a tailnet (auth) key. That's not a new problem, but one that's more apparent now that OAuth clients have their own resource.
I think it might be cleaner to just not let people import anything other than auth keys as a tailnet_key
resource.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, yeah lets block the import of non-auth keys. Since the API does not return the key type currently it'll require a small change to control.
We could infer it depending on if some fields like capabilities exist or not, but I'd rather add the keyType to the BE response and add that check to the provider as a follow-up PR.
For the keyType in the responses: https://github.com/tailscale/corp/issues/28133
f96b113
to
2be9ac9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally LGTM, just a few suggestions on naming. Would also be nice to have @mpminardi weigh in.
tailscale/resource_oauth_client.go
Outdated
Type: schema.TypeString, | ||
}, | ||
Optional: true, | ||
Description: "A list of tags that access tokens generated for the OAuth client will be able to assign to devices. Mandatory is the scopes include \"devices:core\" or \"auth_keys\".", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mandatory is
-> This is mandatory if
.
Description: "A list of tags that access tokens generated for the OAuth client will be able to assign to devices. Mandatory is the scopes include \"devices:core\" or \"auth_keys\".", | ||
ForceNew: true, | ||
}, | ||
"id": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The OAuth spec calls this client_id
. I think we should do the same. That also avoids confusing it with the resource's ID.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case the client_id
is the same as / being used as the actual ID of the resource. I think I would lean more towards leaving this and the key
attributes named as they are to stay more consistent with the structure of the underlying API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went for parity with the API (id/key pair). I do agree though that if we had a magic wand or V3 API we should align the field names with the oauth spec.
Computed: true, | ||
Sensitive: true, | ||
}, | ||
"key": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OAuth spec calls this client_secret
. I think we should do the same.
.gitignore
Outdated
@@ -1,2 +1,3 @@ | |||
dist/ | |||
terraform-provider-tailscale | |||
.idea/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: add newline at the end of this file
tailscale/resource_oauth_client.go
Outdated
Type: schema.TypeString, | ||
Description: "The client ID, also known as the key id. Used with the client secret to generate access tokens.", | ||
Computed: true, | ||
Sensitive: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think this needs to be sensitive! We return this in the API / show it in the UI
tailscale/resource_oauth_client.go
Outdated
"user_id": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Description: "ID of the user who created this key, or empty if not created by a user.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think it might be helpful to add some colour around when this is the case:
Description: "ID of the user who created this key, or empty if not created by a user.", | |
Description: "ID of the user who created this key, empty for OAuth clients created by other OAuth clients.", |
tailscale/resource_oauth_client.go
Outdated
return diagnosticsError(err, "Failed to set user_id") | ||
} | ||
|
||
return nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a sanity measure we usually do a read after create to protect against potential state drift issues:
return nil | |
return resourceOAuthClientRead(ctx, d, m) |
b8be59b
to
4c35cc3
Compare
Added support to manage OAuth clients via the tailscale_oauth_client resource Updates: tailscale/tailscale#9632 Signed-off-by: Max Coulombe max@tailscale.com Signed-off-by: mcoulombe <max@tailscale.com> * update client and use dedicated create oauth client method * doc and test adjustments * bump client
4c35cc3
to
aa65a0b
Compare
Added support to manage OAuth clients via the tailscale_oauth_client resource
Updates: tailscale/tailscale#9632
Acc test results on the branch:
https://github.com/tailscale/corp/actions/runs/14762878480