Skip to content

Commit

Permalink
Added resource group user binding. (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
ArthurEatsCode and [email protected] authored Oct 10, 2023
1 parent 16fa315 commit a19c821
Show file tree
Hide file tree
Showing 5 changed files with 278 additions and 0 deletions.
15 changes: 15 additions & 0 deletions alicloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"

alicloudAdbClient "github.com/alibabacloud-go/adb-20190315/v2/client"
alicloudDnsClient "github.com/alibabacloud-go/alidns-20150109/v4/client"
alicloudBaseClient "github.com/alibabacloud-go/bssopenapi-20171214/v3/client"
alicloudCdnClient "github.com/alibabacloud-go/cdn-20180510/v2/client"
Expand All @@ -34,6 +35,7 @@ type alicloudClients struct {
dnsClient *alicloudDnsClient.Client
ramClient *alicloudRamClient.Client
cmsClient *alicloudCmsClient.Client
adbClient *alicloudAdbClient.Client
emrClient *alicloudEmrClient.Client
}

Expand Down Expand Up @@ -293,6 +295,17 @@ func (p *alicloudProvider) Configure(ctx context.Context, req provider.Configure
return
}

// AliCloud ADB Client
adbClientConfig := clientCredentialsConfig
adbClientConfig.Endpoint = tea.String("adb.aliyuncs.com")
adbClient, err := alicloudAdbClient.NewClient(adbClientConfig)
if err != nil {
resp.Diagnostics.AddError(
"Unable to Create AliCloud ADB API Client",
"An unexpected error occurred when creating the AliCloud ADB API client. "+
"If the error is not clear, please contact the provider developers.\n\n"+
"AliCloud ADB Client Error: "+err.Error(),

// AliCloud EMR Client
emrClientConfig := clientCredentialsConfig

Check failure on line 310 in alicloud/provider.go

View workflow job for this annotation

GitHub Actions / goreleaser

syntax error: unexpected := in argument list; possibly missing comma or )
emrClientConfig.Endpoint = tea.String(fmt.Sprintf("emr.%s.aliyuncs.com", region))

Check failure on line 311 in alicloud/provider.go

View workflow job for this annotation

GitHub Actions / goreleaser

syntax error: unexpected ) at end of statement
Expand All @@ -317,6 +330,7 @@ func (p *alicloudProvider) Configure(ctx context.Context, req provider.Configure
dnsClient: dnsClient,
ramClient: ramClient,
cmsClient: cmsClient,
adbClient: adbClient,
emrClient: emrClient,
}

Expand Down Expand Up @@ -344,6 +358,7 @@ func (p *alicloudProvider) Resources(_ context.Context) []func() resource.Resour
NewAlidnsInstanceResource,
NewCmsSystemEventContactGroupAttachmentResource,
NewDdosCooWebconfigSslAttachmentResource,
NewAliadbResourceGroupBindResource,
NewEmrMetricAutoScalingRulesResource,
}
}
252 changes: 252 additions & 0 deletions alicloud/resource_aliadb_resource_group_bind_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
package alicloud

import (
"context"
"time"

"github.com/cenkalti/backoff"

util "github.com/alibabacloud-go/tea-utils/v2/service"
"github.com/alibabacloud-go/tea/tea"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/types"

alicloudAdbClient "github.com/alibabacloud-go/adb-20190315/v2/client"
)

var (
_ resource.Resource = &aliadbResourceGroupBindResource{}
_ resource.ResourceWithConfigure = &aliadbResourceGroupBindResource{}
)

func NewAliadbResourceGroupBindResource() resource.Resource {
return &aliadbResourceGroupBindResource{}
}

type aliadbResourceGroupBindResource struct {
client *alicloudAdbClient.Client
}

type aliadbResourceGroupBindResourceModel struct {
// Required
DBClusterId types.String `tfsdk:"dbcluster_id"`
GroupName types.String `tfsdk:"group_name"`
GroupUser types.String `tfsdk:"group_user"`
}

// Metadata returns the resource alicloud adb resource group association type name.
func (r *aliadbResourceGroupBindResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_aliadb_resource_group_bind_user"
}

func (r *aliadbResourceGroupBindResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "Provides a Aliadb resource group association resource.",
Attributes: map[string]schema.Attribute{
"dbcluster_id": schema.StringAttribute{
Description: "The ID of the AnalyticDB for MySQL Data Warehouse Edition (V3.0) cluster.",
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
"group_name": schema.StringAttribute{
Description: "The name of the resource group.",
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
"group_user": schema.StringAttribute{
Description: "The database account with which to associate the resource group.",
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
},
}
}

// Configure adds the provider configured client to the resource.
func (r *aliadbResourceGroupBindResource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) {
if req.ProviderData == nil {
return
}
r.client = req.ProviderData.(alicloudClients).adbClient
}

// Create a new DNS weight resource
func (r *aliadbResourceGroupBindResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
// Retrieve values from plan
var plan *aliadbResourceGroupBindResourceModel
getStateDiags := req.Plan.Get(ctx, &plan)
resp.Diagnostics.Append(getStateDiags...)
if resp.Diagnostics.HasError() {
return
}

// Bind user to resource group
err := r.bindGroupUser(plan)
if err != nil {
resp.Diagnostics.AddError(
"[API ERROR] Failed to Bind Group User.",
err.Error(),
)
return
}

// Set state items
state := &aliadbResourceGroupBindResourceModel{}
state.DBClusterId = plan.DBClusterId
state.GroupName = plan.GroupName
state.GroupUser = plan.GroupUser

// Set state to fully populated data
setStateDiags := resp.State.Set(ctx, &state)
resp.Diagnostics.Append(setStateDiags...)
if resp.Diagnostics.HasError() {
return
}
}

// Read resource group user bind resource information
func (r *aliadbResourceGroupBindResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
// Alicloud doesn't provide a SDK for describing resource group user binding, the read function will not be implemented.
}

// Update updates the DNS weight resource and sets the updated Terraform state on success.
func (r *aliadbResourceGroupBindResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var plan *aliadbResourceGroupBindResourceModel

// Retrieve values from plan
getPlanDiags := req.Plan.Get(ctx, &plan)
resp.Diagnostics.Append(getPlanDiags...)
if resp.Diagnostics.HasError() {
return
}

if err := r.unbindGroupUser(plan); err != nil {
resp.Diagnostics.AddError(
"[API ERROR] Failed to unbind resource group with user.",
err.Error(),
)
return
}

if err := r.bindGroupUser(plan); err != nil {
resp.Diagnostics.AddError(
"[API ERROR] Failed to bind resource group with user.",
err.Error(),
)
return
}

// Set state values
state := &aliadbResourceGroupBindResourceModel{}
state.DBClusterId = plan.DBClusterId
state.GroupName = plan.GroupName
state.GroupUser = plan.GroupUser

// Set state to plan data
setStateDiags := resp.State.Set(ctx, &state)
resp.Diagnostics.Append(setStateDiags...)
if resp.Diagnostics.HasError() {
return
}
}

// Delete the resource group user bind resource and removes the Terraform state on success.
func (r *aliadbResourceGroupBindResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
// Retrieve values from state
var state *aliadbResourceGroupBindResourceModel
diags := req.State.Get(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

if err := r.unbindGroupUser(state); err != nil {
resp.Diagnostics.AddError(
"[API ERROR] Failed to unbind resource group with user.",
err.Error(),
)
return
}
}

func (r *aliadbResourceGroupBindResource) bindGroupUser(plan *aliadbResourceGroupBindResourceModel) error {
bindGroupUser := func() error {
runtime := &util.RuntimeOptions{}

// Look for SubDomain Name
bindDBResourceGroupWithUserRequest := &alicloudAdbClient.BindDBResourceGroupWithUserRequest{
DBClusterId: tea.String(plan.DBClusterId.ValueString()),
GroupName: tea.String(plan.GroupName.ValueString()),
GroupUser: tea.String(plan.GroupUser.ValueString()),
}

_, err := r.client.BindDBResourceGroupWithUserWithOptions(bindDBResourceGroupWithUserRequest, runtime)
if err != nil {
if _t, ok := err.(*tea.SDKError); ok {
if isAbleToRetry(*_t.Code) {
return err
} else {
return backoff.Permanent(err)
}
} else {
return err
}
}

return nil
}

// Retry backoff
reconnectBackoff := backoff.NewExponentialBackOff()
reconnectBackoff.MaxElapsedTime = 30 * time.Second
err := backoff.Retry(bindGroupUser, reconnectBackoff)
if err != nil {
return err
}
return nil
}

func (r *aliadbResourceGroupBindResource) unbindGroupUser(plan *aliadbResourceGroupBindResourceModel) error {
setRecordWeight := func() error {
runtime := &util.RuntimeOptions{}

unbindDBResourceGroupWithUserRequest := &alicloudAdbClient.UnbindDBResourceGroupWithUserRequest{
DBClusterId: tea.String(plan.DBClusterId.ValueString()),
GroupName: tea.String(plan.GroupName.ValueString()),
GroupUser: tea.String(plan.GroupUser.ValueString()),
}

_, err := r.client.UnbindDBResourceGroupWithUserWithOptions(unbindDBResourceGroupWithUserRequest, runtime)
if err != nil {
if _t, ok := err.(*tea.SDKError); ok {
if isAbleToRetry(*_t.Code) {
return err
} else {
return backoff.Permanent(err)
}
} else {
return err
}
}

return nil
}

// Retry backoff
reconnectBackoff := backoff.NewExponentialBackOff()
reconnectBackoff.MaxElapsedTime = 30 * time.Second
err := backoff.Retry(setRecordWeight, reconnectBackoff)
if err != nil {
return err
}
return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "st-alicloud_aliadb_resource_group_bind_user" "bind_user" {
dbcluster_id = "am-3ns9eg3ntm1g7y0m3"
group_name = "TEST"
group_user = "dts"
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ require (
)

require (
github.com/alibabacloud-go/adb-20190315/v2 v2.1.2
github.com/alibabacloud-go/bssopenapi-20171214/v3 v3.0.2
github.com/alibabacloud-go/slb-20140515/v4 v4.0.1
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/google/uuid v1.3.0
github.com/hashicorp/terraform-plugin-docs v0.14.1
)
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C6
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/alibabacloud-go/adb-20190315/v2 v2.1.2 h1:6ZjJxgW7ayR4D6NpTc+TxIjmkk2KQ/09SqVmOZdQXwQ=
github.com/alibabacloud-go/adb-20190315/v2 v2.1.2/go.mod h1:0tUGicl9MOgEVR9AGPZI+YzCSXMGto2ZY+6H6/ifRN0=
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 h1:iC9YFYKDGEy3n/FtqJnOkZsene9olVspKmkX5A2YBEo=
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
github.com/alibabacloud-go/alidns-20150109/v4 v4.0.1 h1:f2XaKw15BKg+lfBTe6cTxRlJY8jdHaMAAcOhjfzgHys=
Expand Down Expand Up @@ -73,6 +75,8 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
Expand Down

0 comments on commit a19c821

Please sign in to comment.