Skip to content

Commit

Permalink
Merge pull request #84 from volcengine/feat/supportIpv6
Browse files Browse the repository at this point in the history
Feat/support ipv6
  • Loading branch information
xuyaming0800 authored Apr 19, 2023
2 parents 8e0691e + 23f4865 commit 1d620d1
Show file tree
Hide file tree
Showing 42 changed files with 1,890 additions and 30 deletions.
11 changes: 10 additions & 1 deletion common/common_volcengine_callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,16 @@ func getAndSetSlice(pattern string, index int, value interface{}, top *map[strin
if exist != nil {
exist1, _ := ObtainSdkValue(pattern+"."+strconv.Itoa(index), *top)
if exist1 == nil {
return append(exist.([]interface{}), value)
if len(exist.([]interface{})) < index+1 {
n := make([]interface{}, index+1)
n[index] = value
for i, v := range exist.([]interface{}) {
n[i] = v
}
return n
} else {
exist.([]interface{})[index] = value
}
}
return exist.([]interface{})
}
Expand Down
2 changes: 1 addition & 1 deletion common/common_volcengine_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ package common

const (
TerraformProviderName = "terraform-provider-volcengine"
TerraformProviderVersion = "0.0.68"
TerraformProviderVersion = "0.0.69"
)
3 changes: 3 additions & 0 deletions example/dataVpcIpv6AddressBandwidths/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "volcengine_vpc_ipv6_address_bandwidths" "default" {
ids = ["eip-in2y2duvtlhc8gbssyfnhfre"]
}
3 changes: 3 additions & 0 deletions example/dataVpcIpv6Addresses/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "volcengine_vpc_ipv6_addresses" "default" {
associated_instance_id = "i-yca53yuhj6gh9zl53kav"
}
3 changes: 3 additions & 0 deletions example/dataVpcIpv6Gateways/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "volcengine_vpc_ipv6_gateways" "default" {
ids = ["ipv6gw-12bcapllb5ukg17q7y2sd3thx"]
}
1 change: 1 addition & 0 deletions example/ecsInstance/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ resource "volcengine_ecs_instance" "default" {
delete_with_instance = true
}
deployment_set_id = ""
ipv6_address_count = 1
# secondary_network_interfaces {
# subnet_id = volcengine_subnet.foo1.id
# security_group_ids = [volcengine_security_group.foo1.id]
Expand Down
13 changes: 13 additions & 0 deletions example/vpcIpv6AddressBandwidth/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
data "volcengine_ecs_instances" "dataEcs" {
ids = ["i-ycal1mtpucl8j0hjiihy"]
}

data "volcengine_vpc_ipv6_addresses" "dataIpv6" {
associated_instance_id = data.volcengine_ecs_instances.dataEcs.instances.0.instance_id
}

resource "volcengine_vpc_ipv6_address_bandwidth" "foo" {
ipv6_address = data.volcengine_vpc_ipv6_addresses.dataIpv6.ipv6_addresses.0.ipv6_address
billing_type = "PostPaidByBandwidth"
bandwidth = 5
}
5 changes: 5 additions & 0 deletions example/vpcIpv6Gateway/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "volcengine_vpc_ipv6_gateway" "foo" {
vpc_id = "vpc-12afxho4sxyio17q7y2kkp8ej"
name = "tf-test-1"
description = "test"
}
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,20 @@ func DataSourceVolcengineEcsInstances() *schema.Resource {
Computed: true,
Description: "The ID of DeploymentSet.",
},
"ipv6_address_count": {
Type: schema.TypeInt,
Computed: true,
Description: "The number of IPv6 addresses of the ECS instance.",
},
"ipv6_addresses": {
Type: schema.TypeSet,
Computed: true,
Set: schema.HashString,
Description: "The IPv6 address list of the ECS instance.",
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},
Expand Down
24 changes: 24 additions & 0 deletions volcengine/ecs/ecs_instance/resource_volcengine_ecs_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,30 @@ func ResourceVolcengineEcsInstance() *schema.Resource {
Description: "The ID of Ecs Deployment Set.",
},

"ipv6_address_count": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ForceNew: true,
Description: "The number of IPv6 addresses to be automatically assigned from within the CIDR block of the subnet that hosts the ENI. Valid values: 1 to 10.",
ValidateFunc: validation.IntBetween(1, 10),
ConflictsWith: []string{"ipv6_addresses"},
},

"ipv6_addresses": {
Type: schema.TypeSet,
MaxItems: 10,
Optional: true,
Computed: true,
ForceNew: true,
Set: schema.HashString,
Description: "One or more IPv6 addresses selected from within the CIDR block of the subnet that hosts the ENI. Support up to 10.\n You cannot specify both the ipv6_addresses and ipv6_address_count parameters.",
Elem: &schema.Schema{
Type: schema.TypeString,
},
ConflictsWith: []string{"ipv6_address_count"},
},

"data_volumes": {
Type: schema.TypeList,
Optional: true,
Expand Down
136 changes: 130 additions & 6 deletions volcengine/ecs/ecs_instance/service_volcengine_ecs_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,17 @@ func (s *VolcengineEcsService) GetClient() *ve.SdkClient {
return s.Client
}

func (s *VolcengineEcsService) ReadResources(condition map[string]interface{}) ([]interface{}, error) {
func (s *VolcengineEcsService) ReadResources(condition map[string]interface{}) (data []interface{}, err error) {
var (
resp *map[string]interface{}
results interface{}
ok bool
resp *map[string]interface{}
results interface{}
next string
ok bool
ecsInstance map[string]interface{}
networkInterfaces []interface{}
networkInterfaceId string
)
return ve.WithNextTokenQuery(condition, "MaxResults", "NextToken", 20, nil, func(m map[string]interface{}) (data []interface{}, next string, err error) {
data, err = ve.WithNextTokenQuery(condition, "MaxResults", "NextToken", 20, nil, func(m map[string]interface{}) ([]interface{}, string, error) {
ecs := s.Client.EcsClient
action := "DescribeInstances"
logger.Debug(logger.ReqFormat, action, condition)
Expand Down Expand Up @@ -107,6 +111,51 @@ func (s *VolcengineEcsService) ReadResources(condition map[string]interface{}) (
data, err = RemoveSystemTags(data)
return data, next, err
})

if err != nil {
return nil, err
}

for _, v := range data {
if ecsInstance, ok = v.(map[string]interface{}); !ok {
return data, errors.New("Value is not map ")
} else {
// query primary network interface info of the ecs instance
if networkInterfaces, ok = ecsInstance["NetworkInterfaces"].([]interface{}); !ok {
return data, errors.New("Instances.NetworkInterfaces is not Slice")
}
for _, networkInterface := range networkInterfaces {
if networkInterfaceMap, ok := networkInterface.(map[string]interface{}); ok &&
networkInterfaceMap["Type"] == "primary" {
networkInterfaceId = networkInterfaceMap["NetworkInterfaceId"].(string)
}
}

action := "DescribeNetworkInterfaces"
req := map[string]interface{}{
"NetworkInterfaceIds.1": networkInterfaceId,
}
logger.Debug(logger.ReqFormat, action, req)
res, err := s.Client.UniversalClient.DoCall(getVpcUniversalInfo(action), &req)
if err != nil {
logger.Info("DescribeNetworkInterfaces error:", err)
continue
}
logger.Debug(logger.RespFormat, action, condition, *res)

networkInterfaceInfos, err := ve.ObtainSdkValue("Result.NetworkInterfaceSets", *res)
if err != nil {
logger.Info("ObtainSdkValue Result.NetworkInterfaceSets error:", err)
continue
}
if ipv6Sets, ok := networkInterfaceInfos.([]interface{})[0].(map[string]interface{})["IPv6Sets"].([]interface{}); ok {
ecsInstance["Ipv6Addresses"] = ipv6Sets
ecsInstance["Ipv6AddressCount"] = len(ipv6Sets)
}
}
}

return data, err
}

func (s *VolcengineEcsService) ReadResource(resourceData *schema.ResourceData, instanceId string) (data map[string]interface{}, err error) {
Expand Down Expand Up @@ -378,6 +427,8 @@ func (s *VolcengineEcsService) WithResourceResponseHandlers(ecs map[string]inter
}

func (s *VolcengineEcsService) CreateResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback {
var callbacks []ve.Callback

callback := ve.Callback{
Call: ve.SdkCall{
Action: "RunInstances",
Expand Down Expand Up @@ -434,6 +485,12 @@ func (s *VolcengineEcsService) CreateResource(resourceData *schema.ResourceData,
TargetField: "Tags",
ConvertType: ve.ConvertListN,
},
"ipv6_address_count": {
Ignore: true,
},
"ipv6_addresses": {
Ignore: true,
},
},
BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) {
(*call.SdkParam)["ClientToken"] = uuid.New().String()
Expand Down Expand Up @@ -490,7 +547,65 @@ func (s *VolcengineEcsService) CreateResource(resourceData *schema.ResourceData,
},
},
}
return []ve.Callback{callback}
callbacks = append(callbacks, callback)

// 分配Ipv6
ipv6Callback := ve.Callback{
Call: ve.SdkCall{
Action: "AssignIpv6Addresses",
ConvertMode: ve.RequestConvertIgnore,
BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) {
ipv6AddressCount, ok1 := d.GetOk("ipv6_address_count")
ipv6Addresses, ok2 := d.GetOk("ipv6_addresses")
if !ok1 && !ok2 {
return false, nil
}

var (
networkInterfaceId string
networkInterfaces []interface{}
ok bool
)
ecsInstance, err := s.ReadResource(resourceData, d.Id())
if err != nil {
return false, err
}
// query primary network interface info of the ecs instance
if networkInterfaces, ok = ecsInstance["NetworkInterfaces"].([]interface{}); !ok {
return false, errors.New("Instances.NetworkInterfaces is not Slice")
}
for _, networkInterface := range networkInterfaces {
if networkInterfaceMap, ok := networkInterface.(map[string]interface{}); ok &&
networkInterfaceMap["Type"] == "primary" {
networkInterfaceId = networkInterfaceMap["NetworkInterfaceId"].(string)
}
}

(*call.SdkParam)["NetworkInterfaceId"] = networkInterfaceId
if ok1 {
(*call.SdkParam)["Ipv6AddressCount"] = ipv6AddressCount.(int)
} else if ok2 {
for index, ipv6Address := range ipv6Addresses.(*schema.Set).List() {
(*call.SdkParam)["Ipv6Address."+strconv.Itoa(index)] = ipv6Address
}
}

return true, nil
},
ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) {
logger.Debug(logger.RespFormat, call.Action, call.SdkParam)
//分配Ipv6地址
return s.Client.UniversalClient.DoCall(getVpcUniversalInfo(call.Action), call.SdkParam)
},
Refresh: &ve.StateRefresh{
Target: []string{"RUNNING"},
Timeout: resourceData.Timeout(schema.TimeoutCreate),
},
},
}
callbacks = append(callbacks, ipv6Callback)

return callbacks
}

func (s *VolcengineEcsService) ModifyResource(resourceData *schema.ResourceData, resource *schema.Resource) (callbacks []ve.Callback) {
Expand Down Expand Up @@ -1278,6 +1393,15 @@ func getUniversalInfo(actionName string) ve.UniversalInfo {
}
}

func getVpcUniversalInfo(actionName string) ve.UniversalInfo {
return ve.UniversalInfo{
ServiceName: "vpc",
Version: "2020-04-01",
HttpMethod: ve.GET,
Action: actionName,
}
}

type volumeInfo struct {
list []interface{}
}
Expand Down
46 changes: 27 additions & 19 deletions volcengine/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ import (
"github.com/volcengine/terraform-provider-volcengine/volcengine/vke/node"
"github.com/volcengine/terraform-provider-volcengine/volcengine/vke/node_pool"
"github.com/volcengine/terraform-provider-volcengine/volcengine/vke/support_addon"
"github.com/volcengine/terraform-provider-volcengine/volcengine/vpc/ipv6_address"
"github.com/volcengine/terraform-provider-volcengine/volcengine/vpc/ipv6_address_bandwidth"
"github.com/volcengine/terraform-provider-volcengine/volcengine/vpc/ipv6_gateway"
"github.com/volcengine/terraform-provider-volcengine/volcengine/vpc/network_acl"
"github.com/volcengine/terraform-provider-volcengine/volcengine/vpc/network_acl_associate"
"github.com/volcengine/terraform-provider-volcengine/volcengine/vpc/network_interface"
Expand Down Expand Up @@ -186,14 +189,17 @@ func Provider() terraform.ResourceProvider {
},
},
DataSourcesMap: map[string]*schema.Resource{
"volcengine_vpcs": vpc.DataSourceVolcengineVpcs(),
"volcengine_subnets": subnet.DataSourceVolcengineSubnets(),
"volcengine_route_tables": route_table.DataSourceVolcengineRouteTables(),
"volcengine_route_entries": route_entry.DataSourceVolcengineRouteEntries(),
"volcengine_security_groups": security_group.DataSourceVolcengineSecurityGroups(),
"volcengine_security_group_rules": security_group_rule.DataSourceVolcengineSecurityGroupRules(),
"volcengine_network_interfaces": network_interface.DataSourceVolcengineNetworkInterfaces(),
"volcengine_network_acls": network_acl.DataSourceVolcengineNetworkAcls(),
"volcengine_vpcs": vpc.DataSourceVolcengineVpcs(),
"volcengine_subnets": subnet.DataSourceVolcengineSubnets(),
"volcengine_route_tables": route_table.DataSourceVolcengineRouteTables(),
"volcengine_route_entries": route_entry.DataSourceVolcengineRouteEntries(),
"volcengine_security_groups": security_group.DataSourceVolcengineSecurityGroups(),
"volcengine_security_group_rules": security_group_rule.DataSourceVolcengineSecurityGroupRules(),
"volcengine_network_interfaces": network_interface.DataSourceVolcengineNetworkInterfaces(),
"volcengine_network_acls": network_acl.DataSourceVolcengineNetworkAcls(),
"volcengine_vpc_ipv6_gateways": ipv6_gateway.DataSourceVolcengineIpv6Gateways(),
"volcengine_vpc_ipv6_address_bandwidths": ipv6_address_bandwidth.DataSourceVolcengineIpv6AddressBandwidths(),
"volcengine_vpc_ipv6_addresses": ipv6_address.DataSourceVolcengineIpv6Addresses(),

// ================ EIP ================
"volcengine_eip_addresses": eip_address.DataSourceVolcengineEipAddresses(),
Expand Down Expand Up @@ -316,17 +322,19 @@ func Provider() terraform.ResourceProvider {
"volcengine_rds_mysql_allowlists": allowlist.DataSourceVolcengineRdsMysqlAllowLists(),
},
ResourcesMap: map[string]*schema.Resource{
"volcengine_vpc": vpc.ResourceVolcengineVpc(),
"volcengine_subnet": subnet.ResourceVolcengineSubnet(),
"volcengine_route_table": route_table.ResourceVolcengineRouteTable(),
"volcengine_route_entry": route_entry.ResourceVolcengineRouteEntry(),
"volcengine_route_table_associate": route_table_associate.ResourceVolcengineRouteTableAssociate(),
"volcengine_security_group": security_group.ResourceVolcengineSecurityGroup(),
"volcengine_network_interface": network_interface.ResourceVolcengineNetworkInterface(),
"volcengine_network_interface_attach": network_interface_attach.ResourceVolcengineNetworkInterfaceAttach(),
"volcengine_security_group_rule": security_group_rule.ResourceVolcengineSecurityGroupRule(),
"volcengine_network_acl": network_acl.ResourceVolcengineNetworkAcl(),
"volcengine_network_acl_associate": network_acl_associate.ResourceVolcengineNetworkAclAssociate(),
"volcengine_vpc": vpc.ResourceVolcengineVpc(),
"volcengine_subnet": subnet.ResourceVolcengineSubnet(),
"volcengine_route_table": route_table.ResourceVolcengineRouteTable(),
"volcengine_route_entry": route_entry.ResourceVolcengineRouteEntry(),
"volcengine_route_table_associate": route_table_associate.ResourceVolcengineRouteTableAssociate(),
"volcengine_security_group": security_group.ResourceVolcengineSecurityGroup(),
"volcengine_network_interface": network_interface.ResourceVolcengineNetworkInterface(),
"volcengine_network_interface_attach": network_interface_attach.ResourceVolcengineNetworkInterfaceAttach(),
"volcengine_security_group_rule": security_group_rule.ResourceVolcengineSecurityGroupRule(),
"volcengine_network_acl": network_acl.ResourceVolcengineNetworkAcl(),
"volcengine_network_acl_associate": network_acl_associate.ResourceVolcengineNetworkAclAssociate(),
"volcengine_vpc_ipv6_gateway": ipv6_gateway.ResourceVolcengineIpv6Gateway(),
"volcengine_vpc_ipv6_address_bandwidth": ipv6_address_bandwidth.ResourceVolcengineIpv6AddressBandwidth(),

// ================ EIP ================
"volcengine_eip_address": eip_address.ResourceVolcengineEipAddress(),
Expand Down
Loading

0 comments on commit 1d620d1

Please sign in to comment.