Skip to content

Commit f3ea2af

Browse files
tongyimingmikatong
andauthored
feat: support user sso (#1004)
Co-authored-by: mikatong <mikatong@tencent.com>
1 parent d610c26 commit f3ea2af

File tree

15 files changed

+1384
-534
lines changed

15 files changed

+1384
-534
lines changed

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ require (
2222
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/api v1.0.285
2323
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/apigateway v1.0.199
2424
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/as v1.0.363
25-
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.0.357
25+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.0.389
2626
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs v1.0.199
2727
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdb v1.0.199
2828
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.199
@@ -31,7 +31,7 @@ require (
3131
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.283
3232
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cloudaudit v1.0.199
3333
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cls v1.0.377
34-
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.385
34+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.389
3535
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.385
3636
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.0.359
3737
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dayu v1.0.335

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.0.199 h1:caDwMPz
464464
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.0.199/go.mod h1:ys+65P4jdhUP5rQFSPI9O8/5s0lNcPycl5IPOTaZyVU=
465465
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.0.357 h1:USpuZLFRHacOVo4urhDJcCIH2hb6DqNx0YmLvLt+w2Y=
466466
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.0.357/go.mod h1:Whw7AWuWHNYQIdgwhl0/cf2DQ2N7JD9HUj9PvgiwRrQ=
467+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.0.389 h1:onXh7FnJW1/SKe8wnk2Eje2hwURZE9kLjywAEsWjQ3Q=
468+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.0.389/go.mod h1:tE7rJIMfrxsp1/j69qs2/0rbY028MeLUF4kyP+oYmNA=
467469
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs v1.0.199 h1:MkIdFgEGF+baYAU9Z/PUmudfuamCGtLsedQpopwyHNU=
468470
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs v1.0.199/go.mod h1:PTp058qpOV//RukBVdYQT962rZg71lIt6eHLK1zdvEc=
469471
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdb v1.0.199 h1:7ReZOKl95X+9SkPPtrAoUt4ZPJSIjiSxq4g/M54JmtU=
@@ -521,6 +523,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.383 h1:1TFC
521523
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.383/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
522524
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.385 h1:bwgb0FZJRlPcDn3uRJfA7rI7dZejg7LZS0b8rUBE2CQ=
523525
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.385/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
526+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.389 h1:Ndw52BGqx09zNotV8hFkEw8kHbWa2MG+1Txwqwv3URY=
527+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.389/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
524528
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.199 h1:ajgJogYSIQ5u1PIbiV5nsvr5K0fYpm1/T7Dy+mxEM6U=
525529
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.199/go.mod h1:AqyM/ZZMD7q5mHBqNY9YImbSpEpoEe7E/vrTbUWX+po=
526530
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.351 h1:zqJsH5pxGT57La7NAOOyMQxsuM11pupNBwV1dzXcT24=

tencentcloud/provider.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ Cloud Access Management(CAM)
166166
tencentcloud_cam_group_policy_attachment
167167
tencentcloud_cam_group_membership
168168
tencentcloud_cam_saml_provider
169+
tencentcloud_cam_oidc_sso
169170
170171
Cloud Block Storage(CBS)
171172
Data Source
@@ -1012,6 +1013,7 @@ func Provider() terraform.ResourceProvider {
10121013
"tencentcloud_cam_user_policy_attachment": resourceTencentCloudCamUserPolicyAttachment(),
10131014
"tencentcloud_cam_group_policy_attachment": resourceTencentCloudCamGroupPolicyAttachment(),
10141015
"tencentcloud_cam_group": resourceTencentCloudCamGroup(),
1016+
"tencentcloud_cam_oidc_sso": resourceTencentCloudCamOIDCSSO(),
10151017
"tencentcloud_cam_group_membership": resourceTencentCloudCamGroupMembership(),
10161018
"tencentcloud_cam_saml_provider": resourceTencentCloudCamSAMLProvider(),
10171019
"tencentcloud_scf_function": resourceTencentCloudScfFunction(),
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
/*
2+
Provides a resource to create a CAM-OIDC-SSO.
3+
4+
Example Usage
5+
6+
```hcl
7+
resource "tencentcloud_cam_oidc_sso" "foo" {
8+
authorization_endpoint="https://login.microsoftonline.com/.../oauth2/v2.0/authorize"
9+
client_id="..."
10+
identity_key="..."
11+
identity_url="https://login.microsoftonline.com/.../v2.0"
12+
mapping_filed="name"
13+
response_mode="form_post"
14+
response_type="id_token"
15+
scope=["openid", "email"]
16+
}
17+
```
18+
19+
Import
20+
21+
CAM-OIDC-SSO can be imported using the client_id or any string which can identifier resource, e.g.
22+
23+
```
24+
$ terraform import tencentcloud_cam_oidc_sso.foo xxxxxxxxxxx
25+
```
26+
*/
27+
package tencentcloud
28+
29+
import (
30+
"log"
31+
32+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
33+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
34+
cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116"
35+
"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
36+
)
37+
38+
func resourceTencentCloudCamOIDCSSO() *schema.Resource {
39+
return &schema.Resource{
40+
Create: resourceTencentCloudCamOIDCSSOCreate,
41+
Read: resourceTencentCloudCamOIDCSSORead,
42+
Update: resourceTencentCloudCamOIDCSSOUpdate,
43+
Delete: resourceTencentCloudCamOIDCSSODelete,
44+
Importer: &schema.ResourceImporter{
45+
State: schema.ImportStatePassthrough,
46+
},
47+
48+
Schema: map[string]*schema.Schema{
49+
"authorization_endpoint": {
50+
Type: schema.TypeString,
51+
Required: true,
52+
Description: "Authorization request Endpoint, OpenID Connect identity provider authorization address. Corresponds to the value of the `authorization_endpoint` field in the Openid-configuration provided by the Enterprise IdP.",
53+
},
54+
"client_id": {
55+
Type: schema.TypeString,
56+
Required: true,
57+
Description: "Client ID, the client ID registered with the OpenID Connect identity provider.",
58+
},
59+
"identity_key": {
60+
Type: schema.TypeString,
61+
Required: true,
62+
Description: "The signature public key requires base64_encode. Verify the public key signed by the OpenID Connect identity provider ID Token. For the security of your account, we recommend that you rotate the signed public key regularly.",
63+
},
64+
"identity_url": {
65+
Type: schema.TypeString,
66+
Required: true,
67+
Description: "Identity provider URL. OpenID Connect identity provider identity.Corresponds to the value of the `issuer` field in the Openid-configuration provided by the Enterprise IdP.",
68+
},
69+
"mapping_filed": {
70+
Type: schema.TypeString,
71+
Required: true,
72+
Description: "Map field names. Which field in the IdP's id_token maps to the user name of the subuser, usually the sub or name field.",
73+
},
74+
"response_mode": {
75+
Type: schema.TypeString,
76+
Required: true,
77+
Description: "Authorize the request Forsonse mode. Authorization request return mode, form_post and frogment two optional modes, recommended to select form_post mode.",
78+
},
79+
"response_type": {
80+
Type: schema.TypeString,
81+
Required: true,
82+
Description: "Authorization requests The Response type, with a fixed value id_token.",
83+
},
84+
"scope": {
85+
Type: schema.TypeSet,
86+
Optional: true,
87+
Elem: &schema.Schema{Type: schema.TypeString},
88+
Description: "Authorize the request Scope. openid; email; profile; Authorization request information scope. The default is required openid.",
89+
},
90+
},
91+
}
92+
}
93+
94+
func resourceTencentCloudCamOIDCSSOCreate(d *schema.ResourceData, meta interface{}) error {
95+
defer logElapsed("resource.tencentcloud_cam_oidc_sso.create")()
96+
97+
logId := getLogId(contextNil)
98+
99+
request := cam.NewCreateUserOIDCConfigRequest()
100+
request.IdentityUrl = helper.String(d.Get("identity_url").(string))
101+
request.IdentityKey = helper.String(d.Get("identity_key").(string))
102+
request.ClientId = helper.String(d.Get("client_id").(string))
103+
request.AuthorizationEndpoint = helper.String(d.Get("authorization_endpoint").(string))
104+
request.ResponseType = helper.String(d.Get("response_type").(string))
105+
request.ResponseMode = helper.String(d.Get("response_mode").(string))
106+
request.MappingFiled = helper.String(d.Get("mapping_filed").(string))
107+
if v, ok := d.GetOk("scope"); ok {
108+
request.Scope = helper.InterfacesStringsPoint(v.(*schema.Set).List())
109+
} else {
110+
request.Scope = helper.InterfacesStringsPoint([]interface{}{"openid"})
111+
}
112+
113+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
114+
result, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().CreateUserOIDCConfig(request)
115+
if e != nil {
116+
log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n",
117+
logId, request.GetAction(), request.ToJsonString(), e.Error())
118+
return retryError(e)
119+
} else {
120+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n",
121+
logId, request.GetAction(), request.ToJsonString(), result.ToJsonString())
122+
}
123+
return nil
124+
})
125+
if err != nil {
126+
log.Printf("[CRITAL]%s create CAM SSO failed, reason:%s\n", logId, err.Error())
127+
return err
128+
}
129+
d.SetId(d.Get("client_id").(string))
130+
return resourceTencentCloudCamOIDCSSORead(d, meta)
131+
}
132+
133+
func resourceTencentCloudCamOIDCSSORead(d *schema.ResourceData, meta interface{}) error {
134+
defer logElapsed("resource.tencentcloud_cam_oidc_sso.read")()
135+
136+
logId := getLogId(contextNil)
137+
request := cam.NewDescribeUserOIDCConfigRequest()
138+
var response *cam.DescribeUserOIDCConfigResponse
139+
err := resource.Retry(readRetryTimeout, func() *resource.RetryError {
140+
result, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().DescribeUserOIDCConfig(request)
141+
if e != nil {
142+
return retryError(e)
143+
}
144+
response = result
145+
return nil
146+
})
147+
if err != nil {
148+
log.Printf("[CRITAL]%s read CAM SSO failed, reason:%s\n", logId, err.Error())
149+
return err
150+
}
151+
152+
if response.Response == nil {
153+
d.SetId("")
154+
return nil
155+
}
156+
157+
_ = d.Set("authorization_endpoint", *response.Response.AuthorizationEndpoint)
158+
_ = d.Set("client_id", *response.Response.ClientId)
159+
_ = d.Set("identity_key", *response.Response.IdentityKey)
160+
_ = d.Set("identity_url", *response.Response.IdentityUrl)
161+
_ = d.Set("mapping_filed", *response.Response.MappingFiled)
162+
_ = d.Set("response_mode", *response.Response.ResponseMode)
163+
_ = d.Set("response_type", *response.Response.ResponseType)
164+
scope := make([]string, 0)
165+
for _, s := range response.Response.Scope {
166+
scope = append(scope, *s)
167+
}
168+
_ = d.Set("scope", scope)
169+
170+
return nil
171+
}
172+
173+
func resourceTencentCloudCamOIDCSSOUpdate(d *schema.ResourceData, meta interface{}) error {
174+
defer logElapsed("resource.tencentcloud_cam_oidc_sso.update")()
175+
logId := getLogId(contextNil)
176+
request := cam.NewUpdateUserOIDCConfigRequest()
177+
if d.HasChange("authorization_endpoint") || d.HasChange("client_id") || d.HasChange("identity_key") || d.HasChange("identity_url") || d.HasChange("mapping_filed") || d.HasChange("response_mode") || d.HasChange("response_type") || d.HasChange("scope") {
178+
request.AuthorizationEndpoint = helper.String(d.Get("authorization_endpoint").(string))
179+
request.ClientId = helper.String(d.Get("client_id").(string))
180+
request.IdentityKey = helper.String(d.Get("identity_key").(string))
181+
request.IdentityUrl = helper.String(d.Get("identity_url").(string))
182+
request.MappingFiled = helper.String(d.Get("mapping_filed").(string))
183+
request.ResponseMode = helper.String(d.Get("response_mode").(string))
184+
request.ResponseType = helper.String(d.Get("response_type").(string))
185+
if v, ok := d.GetOk("scope"); ok {
186+
request.Scope = helper.InterfacesStringsPoint(v.(*schema.Set).List())
187+
} else {
188+
request.Scope = helper.InterfacesStringsPoint([]interface{}{"openid"})
189+
}
190+
}
191+
192+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
193+
_, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().UpdateUserOIDCConfig(request)
194+
if e != nil {
195+
return retryError(e)
196+
}
197+
return nil
198+
})
199+
if err != nil {
200+
log.Printf("[CRITAL]%s update CAM OIDC SSO failed, reason:%s\n", logId, err.Error())
201+
return err
202+
}
203+
204+
return resourceTencentCloudCamOIDCSSORead(d, meta)
205+
}
206+
207+
func resourceTencentCloudCamOIDCSSODelete(d *schema.ResourceData, meta interface{}) error {
208+
defer logElapsed("resource.tencentcloud_cam_oidc_sso.delete")()
209+
logId := getLogId(contextNil)
210+
request := cam.NewDisableUserSSORequest()
211+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
212+
_, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().DisableUserSSO(request)
213+
if e != nil {
214+
return retryError(e)
215+
}
216+
return nil
217+
})
218+
if err != nil {
219+
log.Printf("[CRITAL]%s disable cam sso failed, reason:%s\n", logId, err.Error())
220+
return err
221+
}
222+
return nil
223+
}

tencentcloud/resource_tc_cam_oidc_sso_test.go

Lines changed: 139 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)