From 4635a5d232b62708ea1fb332882ad7438d078be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=B2=9B=E5=8D=8E?= Date: Tue, 27 Jun 2023 06:21:11 +0000 Subject: [PATCH] feat: add network interface private ip address modify * feat: add network interface private ip address modify * feat: Merge branch * feat: add doc https://code.byted.org/iaasng/terraform-provider-volcengine/merge_requests/296 --- example/networkInterface/main.tf | 8 +- .../resource_volcengine_network_interface.go | 17 +- .../service_volcengine_network_interface.go | 149 +++++++++++++++++- .../docs/r/network_interface.html.markdown | 12 +- 4 files changed, 171 insertions(+), 15 deletions(-) diff --git a/example/networkInterface/main.tf b/example/networkInterface/main.tf index 57e555b3..e0d78367 100644 --- a/example/networkInterface/main.tf +++ b/example/networkInterface/main.tf @@ -1,9 +1,11 @@ resource "volcengine_network_interface" "foo" { - subnet_id = "subnet-im67x70vxla88gbssz1hy1z2" - security_group_ids = ["sg-im67wp9lx3i88gbssz3d22b2"] - primary_ip_address = "192.168.0.253" + subnet_id = "subnet-2fe79j7c8o5c059gp68ksxr93" + security_group_ids = ["sg-2fepz3c793g1s59gp67y21r34"] + primary_ip_address = "192.168.5.253" network_interface_name = "tf-test-up" description = "tf-test-up" port_security_enabled = false project_name = "default" + private_ip_address = ["192.168.5.2"] + //secondary_private_ip_address_count = 0 } \ No newline at end of file diff --git a/volcengine/vpc/network_interface/resource_volcengine_network_interface.go b/volcengine/vpc/network_interface/resource_volcengine_network_interface.go index 926fb056..493a51a0 100644 --- a/volcengine/vpc/network_interface/resource_volcengine_network_interface.go +++ b/volcengine/vpc/network_interface/resource_volcengine_network_interface.go @@ -74,17 +74,22 @@ func ResourceVolcengineNetworkInterface() *schema.Resource { Description: "Set port security enable or disable.", }, "secondary_private_ip_address_count": { - Type: schema.TypeInt, - Optional: true, - Description: "The count of secondary private ip address.", + Type: schema.TypeInt, + Optional: true, + Computed: true, + ConflictsWith: []string{"private_ip_address"}, + Description: "The count of secondary private ip address. This field conflicts with `private_ip_address`.", }, "private_ip_address": { - Type: schema.TypeSet, - Optional: true, - Description: "The list of private ip address.", + Type: schema.TypeSet, Elem: &schema.Schema{ Type: schema.TypeString, }, + Optional: true, + Computed: true, + Set: schema.HashString, + ConflictsWith: []string{"secondary_private_ip_address_count"}, + Description: "The list of private ip address. This field conflicts with `secondary_private_ip_address_count`.", }, "project_name": { Type: schema.TypeString, diff --git a/volcengine/vpc/network_interface/service_volcengine_network_interface.go b/volcengine/vpc/network_interface/service_volcengine_network_interface.go index b908d542..c6c630d4 100644 --- a/volcengine/vpc/network_interface/service_volcengine_network_interface.go +++ b/volcengine/vpc/network_interface/service_volcengine_network_interface.go @@ -3,6 +3,7 @@ package network_interface import ( "errors" "fmt" + "strconv" "time" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" @@ -46,7 +47,7 @@ func (s *VolcengineNetworkInterfaceService) ReadResources(m map[string]interface return data, err } } - + logger.Debug(logger.RespFormat, action, *resp) results, err = ve.ObtainSdkValue("Result.NetworkInterfaceSets", *resp) if err != nil { return data, err @@ -84,6 +85,22 @@ func (s *VolcengineNetworkInterfaceService) ReadResource(resourceData *schema.Re if len(data) == 0 { return data, fmt.Errorf("network_interface %s not exist ", id) } + privateIpAddress := make([]string, 0) + if privateIpMap, ok := data["PrivateIpSets"].(map[string]interface{}); ok { + if privateIpSets, ok := privateIpMap["PrivateIpSet"].([]interface{}); ok { + for _, p := range privateIpSets { + if pMap, ok := p.(map[string]interface{}); ok { + isPrimary := pMap["Primary"].(bool) + ip := pMap["PrivateIpAddress"].(string) + if !isPrimary { + privateIpAddress = append(privateIpAddress, ip) + } + } + } + } + } + data["PrivateIpAddress"] = privateIpAddress + data["SecondaryPrivateIpAddressCount"] = len(privateIpAddress) return data, err } @@ -186,11 +203,141 @@ func (s *VolcengineNetworkInterfaceService) ModifyResource(resourceData *schema. TargetField: "SecurityGroupIds", ConvertType: ve.ConvertWithN, }, + "private_ip_address": { + Ignore: true, + }, + "secondary_private_ip_address_count": { + Ignore: true, + }, }, }, } callbacks = append(callbacks, callback) + // 检查private_ip_address改变 + if resourceData.HasChange("private_ip_address") { + add, remove, _, _ := ve.GetSetDifference("private_ip_address", resourceData, schema.HashString, false) + if remove.Len() > 0 { + callback = ve.Callback{ + Call: ve.SdkCall{ + Action: "UnassignPrivateIpAddresses", + ConvertMode: ve.RequestConvertInConvert, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + (*call.SdkParam)["NetworkInterfaceId"] = d.Id() + for index, r := range remove.List() { + (*call.SdkParam)["PrivateIpAddress."+strconv.Itoa(index+1)] = r + } + return true, nil + }, + Convert: map[string]ve.RequestConvert{ + "private_ip_address": { + Ignore: true, + }, + "secondary_private_ip_address_count": { + Ignore: true, + }, + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + return s.Client.UniversalClient.DoCall(getUniversalInfo(call.Action), call.SdkParam) + }, + }, + } + callbacks = append(callbacks, callback) + } + if add.Len() > 0 { + callback = ve.Callback{ + Call: ve.SdkCall{ + Action: "AssignPrivateIpAddresses", + ConvertMode: ve.RequestConvertInConvert, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + (*call.SdkParam)["NetworkInterfaceId"] = d.Id() + for index, r := range add.List() { + (*call.SdkParam)["PrivateIpAddress."+strconv.Itoa(index+1)] = r + } + return true, nil + }, + Convert: map[string]ve.RequestConvert{ + "private_ip_address": { + Ignore: true, + }, + "secondary_private_ip_address_count": { + Ignore: true, + }, + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + return s.Client.UniversalClient.DoCall(getUniversalInfo(call.Action), call.SdkParam) + }, + }, + } + callbacks = append(callbacks, callback) + } + } + // 检查secondary_private_ip_address_count改变 + if resourceData.HasChange("secondary_private_ip_address_count") { + privateIpAddress := resourceData.Get("private_ip_address").(*schema.Set).List() + oldCount, newCount := resourceData.GetChange("secondary_private_ip_address_count") + if oldCount != nil && newCount != nil && newCount != len(privateIpAddress) { + diff := newCount.(int) - oldCount.(int) + if diff > 0 { + callback = ve.Callback{ + Call: ve.SdkCall{ + Action: "AssignPrivateIpAddresses", + ConvertMode: ve.RequestConvertInConvert, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + (*call.SdkParam)["NetworkInterfaceId"] = d.Id() + (*call.SdkParam)["SecondaryPrivateIpAddressCount"] = diff + return true, nil + }, + Convert: map[string]ve.RequestConvert{ + "private_ip_address": { + Ignore: true, + }, + "secondary_private_ip_address_count": { + Ignore: true, + }, + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + return s.Client.UniversalClient.DoCall(getUniversalInfo(call.Action), call.SdkParam) + }, + }, + } + callbacks = append(callbacks, callback) + } else { + diff *= -1 + removeIpAddress := privateIpAddress[:diff] + callback = ve.Callback{ + Call: ve.SdkCall{ + Action: "UnassignPrivateIpAddresses", + ConvertMode: ve.RequestConvertInConvert, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + (*call.SdkParam)["NetworkInterfaceId"] = d.Id() + for index, r := range removeIpAddress { + (*call.SdkParam)["PrivateIpAddress."+strconv.Itoa(index+1)] = r + } + return true, nil + }, + Convert: map[string]ve.RequestConvert{ + "private_ip_address": { + Ignore: true, + }, + "secondary_private_ip_address_count": { + Ignore: true, + }, + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + return s.Client.UniversalClient.DoCall(getUniversalInfo(call.Action), call.SdkParam) + }, + }, + } + callbacks = append(callbacks, callback) + } + } + } + // 更新Tags setResourceTagsCallbacks := ve.SetResourceTags(s.Client, "TagResources", "UntagResources", "eni", resourceData, getUniversalInfo) callbacks = append(callbacks, setResourceTagsCallbacks...) diff --git a/website/docs/r/network_interface.html.markdown b/website/docs/r/network_interface.html.markdown index ed8c24d5..9d5bb498 100644 --- a/website/docs/r/network_interface.html.markdown +++ b/website/docs/r/network_interface.html.markdown @@ -11,13 +11,15 @@ Provides a resource to manage network interface ## Example Usage ```hcl resource "volcengine_network_interface" "foo" { - subnet_id = "subnet-im67x70vxla88gbssz1hy1z2" - security_group_ids = ["sg-im67wp9lx3i88gbssz3d22b2"] - primary_ip_address = "192.168.0.253" + subnet_id = "subnet-2fe79j7c8o5c059gp68ksxr93" + security_group_ids = ["sg-2fepz3c793g1s59gp67y21r34"] + primary_ip_address = "192.168.5.253" network_interface_name = "tf-test-up" description = "tf-test-up" port_security_enabled = false project_name = "default" + private_ip_address = ["192.168.5.2"] + //secondary_private_ip_address_count = 0 } ``` ## Argument Reference @@ -28,9 +30,9 @@ The following arguments are supported: * `network_interface_name` - (Optional) The name of the ENI. * `port_security_enabled` - (Optional) Set port security enable or disable. * `primary_ip_address` - (Optional, ForceNew) The primary IP address of the ENI. -* `private_ip_address` - (Optional) The list of private ip address. +* `private_ip_address` - (Optional) The list of private ip address. This field conflicts with `secondary_private_ip_address_count`. * `project_name` - (Optional) The ProjectName of the ENI. -* `secondary_private_ip_address_count` - (Optional) The count of secondary private ip address. +* `secondary_private_ip_address_count` - (Optional) The count of secondary private ip address. This field conflicts with `private_ip_address`. * `tags` - (Optional) Tags. The `tags` object supports the following: