Skip to content

Commit

Permalink
Add IPv6 Resource (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
wilsontcm69 authored Oct 3, 2024
1 parent a646078 commit 96d5bda
Show file tree
Hide file tree
Showing 5 changed files with 271 additions and 0 deletions.
1 change: 1 addition & 0 deletions cdnetworks/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,5 +173,6 @@ func (p *cdnetworksProvider) Resources(_ context.Context) []func() resource.Reso
NewQueryStringUrlConfigResource,
NewHttpCodeCacheConfigResource,
NewIgnoreProtocolResource,
NewIpv6Resource,
}
}
193 changes: 193 additions & 0 deletions cdnetworks/resource_ipv6.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package cdnetworks

import (
"context"
"errors"
"time"

"github.com/cenkalti/backoff/v4"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"

"github.com/myklst/terraform-provider-st-cdnetworks/cdnetworksapi"
)

type ipv6ResourceModel struct {
DomainId types.String `tfsdk:"domain_id" json:"domain_id"`
EnableIpv6 types.Bool `tfsdk:"enable_ipv6" json:"enable_ipv6"`
}

type ipv6Resource struct {
client *cdnetworksapi.Client
}

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

func NewIpv6Resource() resource.Resource {
return &ipv6Resource{}
}

func (r *ipv6Resource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_ipv6_config"
}

func (r *ipv6Resource) Schema(_ context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "Update DNS region IP version, available value: 'V6'",
Attributes: map[string]schema.Attribute{
"domain_id": &schema.StringAttribute{
Description: "Domain id",
Required: true,
},
"enable_ipv6": &schema.BoolAttribute{
Description: "Ipv6",
Required: true,
},
},
}
}

func (r *ipv6Resource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
if req.ProviderData == nil {
return
}
r.client = req.ProviderData.(*cdnetworksapi.Client)
}

func (r *ipv6Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var model ipv6ResourceModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &model)...)
if resp.Diagnostics.HasError() {
return
}

// By Default, IPv4 is enabled
ipVersions := []string{"V4"}
if model.EnableIpv6.ValueBool() {
ipVersions = append(ipVersions, "V6")
}

addIPv6ConfigResponse, err := r.client.UpdateIPv6Config(model.DomainId.ValueString(), cdnetworksapi.UpdateIPv6ConfigRequest{
IpVersion: ipVersions,
})
if err != nil {
resp.Diagnostics.AddError("[API ERROR] Failed to Add IPv6", err.Error())
return
}

if *addIPv6ConfigResponse.Code != "0" {
resp.Diagnostics.AddError("[API ERROR] Error response non 0 code, failed to Add IPv6", *addIPv6ConfigResponse.Message)
return
}

if r.waitForIPv6Config(ctx, model) {
resp.State.Set(ctx, &model)
} else {
resp.Diagnostics.AddError("[API ERROR] Failed to Add IPv6", "Timeout")
}
}

func (r *ipv6Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var state *ipv6ResourceModel
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

queryIPv6Response, err := r.client.QueryIPv6Config(state.DomainId.ValueString())
if err != nil {
resp.Diagnostics.AddError("[API ERROR] Fail to Query IPv6", err.Error())
return
}

state.DomainId = types.StringPointerValue(queryIPv6Response.DomainId)
state.EnableIpv6 = types.BoolPointerValue(queryIPv6Response.UseIpv6)
resp.Diagnostics.Append(resp.State.Set(ctx, state)...)
}

func (r *ipv6Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var state, plan ipv6ResourceModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
return
}
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

ipVersions := []string{"V4"}
if plan.EnableIpv6.ValueBool() {
ipVersions = append(ipVersions, "V6")
}

updateIpv6Response, err := r.client.UpdateIPv6Config(state.DomainId.ValueString(), cdnetworksapi.UpdateIPv6ConfigRequest{
IpVersion: ipVersions,
})
if err != nil {
resp.Diagnostics.AddError("[API ERROR] Failed to Update IPv6", err.Error())
return
}

if *updateIpv6Response.Code != "0" {
resp.Diagnostics.AddError("[API ERROR] Failed to Update IPv6", *updateIpv6Response.Message)
return
}

if r.waitForIPv6Config(ctx, plan) {
state.DomainId = plan.DomainId
state.EnableIpv6 = plan.EnableIpv6
resp.State.Set(ctx, state)
} else {
resp.Diagnostics.AddError("[API ERROR] Failed to Add IPv6", "Timeout")
}
}

func (r *ipv6Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
var model ipv6ResourceModel
diags := req.State.Get(ctx, &model)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

// Due to only have Update() func, force it revert to ipv4 only.
deleteIPv6Response, err := r.client.UpdateIPv6Config(model.DomainId.ValueString(), cdnetworksapi.UpdateIPv6ConfigRequest{
IpVersion: []string{"V4"},
})
if err != nil {
resp.Diagnostics.AddError("[API ERROR] Failed to Del IPv6", err.Error())
return
}

if *deleteIPv6Response.Code != "0" {
resp.Diagnostics.AddError("[API ERROR] Failed to Del IPv6", *deleteIPv6Response.Message)
return
}
}

func (r *ipv6Resource) waitForIPv6Config(ctx context.Context, model ipv6ResourceModel) bool {
checkStatus := func() error {
queryIPv6Response, err := r.client.QueryIPv6Config(model.DomainId.ValueString())
if err != nil {
return err
}

if *queryIPv6Response.UseIpv6 == model.EnableIpv6.ValueBool() {
return nil
}

return errors.New("deployment is in progress")
}

s := backoff.NewExponentialBackOff()
s.InitialInterval = 10 * time.Second
s.MaxElapsedTime = 5 * time.Minute

err := backoff.Retry(checkStatus, s)
return err == nil
}
44 changes: 44 additions & 0 deletions cdnetworksapi/domain_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,50 @@ func (c *Client) UpdateBackToOriginRewriteConfig(domainId string, request Update
return
}

////////////////////////////////////////////////////////////////////////////////
// IPv6 Config
////////////////////////////////////////////////////////////////////////////////

// QueryIPv6Config 查询域名是否使用ipv6资源

type QueryIPv6ConfigResponse struct {
DomainId *string `json:"domain-id" xml:"domain-id"`
DomainName *string `json:"domain-name" xml:"domain-name"`
UseIpv6 *bool `json:"use-ipv6" xml:"use-ipv6"`
}

func (c *Client) QueryIPv6Config(domainId string) (response QueryIPv6ConfigResponse, err error) {
var baseResp *BaseResponse
baseResp, err = c.DoXmlApiRequest(Request{
Method: HttpGet,
Path: "/api/domain/ipv6/" + domainId,
}, &response)
_ = baseResp
return
}

// UpdateIPv6Config 修改域名是否使用IPv6配置

type UpdateIPv6ConfigRequest struct {
XMLName xml.Name `json:"-" xml:"domain"`
IpVersion []string `json:"ipVersion,omitempty" xml:"ipVersion,omitempty"`
}

type UpdateIPv6ConfigResponse struct {
Code *string `json:"code" xml:"code"`
Message *string `json:"message" xml:"message"`
}

// In Version 2024-09-20 16:30:05, the API only supports JSON format.
func (c *Client) UpdateIPv6Config(domainId string, request UpdateIPv6ConfigRequest) (response UpdateIPv6ConfigResponse, err error) {
_, err = c.DoJsonApiRequest(Request{
Method: HttpPut,
Path: "/api/config/ipversion/" + domainId,
Body: request,
}, &response)
return
}

////////////////////////////////////////////////////////////////////////////////
// Http2 Settings
////////////////////////////////////////////////////////////////////////////////
Expand Down
29 changes: 29 additions & 0 deletions docs/resources/ipv6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "st-cdnetworks_ipv6_config Resource - st-cdnetworks"
subcategory: ""
description: |-
The resource control the IPv6 protocol for domain
---

# st-cdnetworks_ssl_certificate (Resource)

The resource control the IPv6 protocol for domain

## Example Usage

```terraform
resource "st-cdnetworks_ipv6_config" "test" {
domain_id = "5048000"
enable_ipv6 = true
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `domain_id` (String) Domain ID
- `enable_ipv6` (Boolean) Enable IPv6.

4 changes: 4 additions & 0 deletions examples/resources/st-cdnetworks_ipv6_config/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
resource "st-cdnetworks_ipv6_config" "test" {
domain_id = "5048000"
enable_ipv6 = true
}

0 comments on commit 96d5bda

Please sign in to comment.