Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions mmv1/products/compute/Instance.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,34 @@ properties:
CIDR range for this alias IP range. If left
unspecified, the primary range of the subnetwork will
be used.
- name: 'aliasIpv6Ranges'
type: Array
description: |
An array of alias IPv6 ranges for this network interface. Can
only be specified for network interfaces on subnet-mode
networks.
min_version: beta
item_type:
type: NestedObject
properties:
- name: 'ipCidrRange'
type: String
description: |
The IP CIDR range represented by this alias IPv6 range.
This IP CIDR range must belong to the specified
subnetwork and cannot contain IP addresses reserved by
system or used by other network interfaces. This range
may be a single IP address (e.g. 2001:db8:1234:5678::),
a netmask (e.g. /96) or a CIDR format string
(e.g. 2001:db8:1234:5678::/96).
- name: 'subnetworkRangeName'
type: String
description: |
Optional subnetwork secondary range name specifying
the secondary range from which to allocate the IP
CIDR range for this alias IPv6 range. If left
unspecified, the primary range of the subnetwork will
be used.
- name: 'internalIpv6PrefixLength'
type: String
description: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,32 @@ func flattenAliasIpRange(d *schema.ResourceData, ranges []*compute.AliasIpRange,
return sorted
}

{{ if ne $.TargetVersionName `ga` -}}
func flattenIpv6AliasRange(d *schema.ResourceData, ranges []*compute.AliasIpRange, i int) []map[string]interface{} {
prefix := fmt.Sprintf("network_interface.%d", i)

configData := []map[string]interface{}{}
for _, item := range d.Get(prefix + ".alias_ipv6_range").([]interface{}) {
configData = append(configData, item.(map[string]interface{}))
}

apiData := make([]map[string]interface{}, 0, len(ranges))
for _, ipRange := range ranges {
apiData = append(apiData, map[string]interface{}{
"ip_cidr_range": ipRange.IpCidrRange,
"subnetwork_range_name": ipRange.SubnetworkRangeName,
})
}

//permadiff fix
sorted, err := tpgresource.SortMapsByConfigOrder(configData, apiData, "ip_cidr_range")
if err != nil {
return apiData
}
return sorted
}
{{- end }}

func expandScheduling(v interface{}) (*compute.Scheduling, error) {
if v == nil {
// We can't set default values for lists.
Expand Down Expand Up @@ -559,6 +585,9 @@ func flattenNetworkInterfaces(d *schema.ResourceData, config *transport_tpg.Conf
"subnetwork_project": subnet.Project,
"access_config": ac,
"alias_ip_range": flattenAliasIpRange(d, iface.AliasIpRanges, i),
{{ if ne $.TargetVersionName `ga` -}}
"alias_ipv6_range": flattenIpv6AliasRange(d, iface.AliasIpv6Ranges, i),
{{- end }}
"nic_type": iface.NicType,
"stack_type": iface.StackType,
"ipv6_access_config": flattenIpv6AccessConfigs(iface.Ipv6AccessConfigs),
Expand Down Expand Up @@ -693,6 +722,9 @@ func expandNetworkInterfaces(d tpgresource.TerraformResourceData, config *transp
Subnetwork: sf.RelativeLink(),
AccessConfigs: expandAccessConfigs(data["access_config"].([]interface{})),
AliasIpRanges: expandAliasIpRanges(data["alias_ip_range"].([]interface{})),
{{ if ne $.TargetVersionName `ga` -}}
AliasIpv6Ranges: expandAliasIpRanges(data["alias_ipv6_range"].([]interface{})),
{{- end }}
NicType: data["nic_type"].(string),
StackType: data["stack_type"].(string),
QueueCount: int64(data["queue_count"].(int)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,29 @@ func ResourceComputeInstance() *schema.Resource {
},
},

{{ if ne $.TargetVersionName `ga` -}}
"alias_ipv6_range": {
Type: schema.TypeList,
Optional: true,
Description: `An array of IPv6 alias IP ranges for this network interface.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ip_cidr_range": {
Type: schema.TypeString,
Required: true,
DiffSuppressFunc: IpCidrRangeDiffSuppress,
Description: `The IPv6 CIDR range represented by this alias IP range.`,
},
"subnetwork_range_name": {
Type: schema.TypeString,
Optional: true,
Description: `The subnetwork secondary range name specifying the secondary range from which to allocate the IP CIDR range for this alias IP range.`,
},
},
},
},
{{- end }}

"stack_type": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -2951,6 +2974,56 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err
}
}

{{ if ne $.TargetVersionName `ga` -}}
if !updateDuringStop && d.HasChange(prefix+".alias_ipv6_range") {
// Alias IPv6 ranges cannot be updated; they must be removed and then added
// unless you are changing subnetwork/network
if len(instNetworkInterface.AliasIpv6Ranges) > 0 {
ni := &compute.NetworkInterface{
Fingerprint: instNetworkInterface.Fingerprint,
ForceSendFields: []string{"AliasIpv6Ranges"},
}
if commonAliasIpv6Ranges := CheckForCommonAliasIpv6(instNetworkInterface, networkInterface); len(commonAliasIpv6Ranges) > 0 {
ni.AliasIpv6Ranges = commonAliasIpv6Ranges
}
op, err := NewClient(config, userAgent).Instances.UpdateNetworkInterface(project, zone, instance.Name, networkName, ni).Do()
if err != nil {
return errwrap.Wrapf("Error removing alias_ipv6_range: {{"{{"}}err{{"}}"}}", err)
}
opErr := ComputeOperationWaitTime(config, op, project, "updating alias ipv6 ranges", userAgent, d.Timeout(schema.TimeoutUpdate))
if opErr != nil {
return opErr
}
// re-read fingerprint
instance, err = NewClient(config, userAgent).Instances.Get(project, zone, instance.Name).Do()
if err != nil {
return err
}
instNetworkInterface = instance.NetworkInterfaces[i]
}

networkInterfacePatchObj := &compute.NetworkInterface{
AliasIpv6Ranges: networkInterface.AliasIpv6Ranges,
Fingerprint: instNetworkInterface.Fingerprint,
}
updateCall := NewClient(config, userAgent).Instances.UpdateNetworkInterface(project, zone, instance.Name, networkName, networkInterfacePatchObj).Do
op, err := updateCall()
if err != nil {
return errwrap.Wrapf("Error updating network interface: {{`{{`}}err{{`}}`}}", err)
}
opErr := ComputeOperationWaitTime(config, op, project, "network interface to update", userAgent, d.Timeout(schema.TimeoutUpdate))
if opErr != nil {
return opErr
}
// re-read fingerprint
instance, err = NewClient(config, userAgent).Instances.Get(project, zone, instance.Name).Do()
if err != nil {
return err
}
instNetworkInterface = instance.NetworkInterfaces[i]
}
{{- end }}

if !updateDuringStop && d.HasChange(prefix+".stack_type") {

networkInterfacePatchObj := &compute.NetworkInterface{
Expand Down Expand Up @@ -3097,6 +3170,9 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err
Network: networkInterface.Network,
Subnetwork: networkInterface.Subnetwork,
AliasIpRanges: networkInterface.AliasIpRanges,
{{ if ne $.TargetVersionName `ga` -}}
AliasIpv6Ranges: networkInterface.AliasIpv6Ranges,
{{- end }}
}

// network_ip can be inferred if not declared. Let's only patch if it's being changed by user
Expand Down Expand Up @@ -4471,13 +4547,23 @@ func isEmptyServiceAccountBlock(d *schema.ResourceData) bool {
// Alias ip ranges cannot be removed and created at the same time. This checks if there are any unchanged alias ip ranges
// to be kept in between the PATCH operations on Network Interface
func CheckForCommonAliasIp(old, new *compute.NetworkInterface) []*compute.AliasIpRange {
return checkForCommonAliasIpRanges(old.AliasIpRanges, new.AliasIpRanges)
}

{{ if ne $.TargetVersionName `ga` -}}
func CheckForCommonAliasIpv6(old, new *compute.NetworkInterface) []*compute.AliasIpRange {
return checkForCommonAliasIpRanges(old.AliasIpv6Ranges, new.AliasIpv6Ranges)
}
{{- end }}

func checkForCommonAliasIpRanges(old, new []*compute.AliasIpRange) []*compute.AliasIpRange {
newAliasIpMap := make(map[string]bool)
for _, ipRange := range new.AliasIpRanges {
for _, ipRange := range new {
newAliasIpMap[ipRange.IpCidrRange] = true
}

resultAliasIpRanges := make([]*compute.AliasIpRange, 0)
for _, val := range old.AliasIpRanges {
for _, val := range old {
if newAliasIpMap[val.IpCidrRange] {
resultAliasIpRanges = append(resultAliasIpRanges, val)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ fields:
field: 'network_interface.alias_ip_range.ip_cidr_range'
- api_field: 'networkInterfaces.aliasIpRanges.subnetworkRangeName'
field: 'network_interface.alias_ip_range.subnetwork_range_name'
{{- if ne $.TargetVersionName "ga" }}
- api_field: 'networkInterfaces.aliasIpv6Ranges.ipCidrRange'
field: 'network_interface.alias_ipv6_range.ip_cidr_range'
- api_field: 'networkInterfaces.aliasIpv6Ranges.subnetworkRangeName'
field: 'network_interface.alias_ipv6_range.subnetwork_range_name'
{{- end }}
- api_field: 'networkInterfaces.internalIpv6PrefixLength'
field: 'network_interface.internal_ipv6_prefix_length'
- api_field: 'networkInterfaces.ipv6AccessConfigs.externalIpv6'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ fields:
field: 'network_interface.alias_ip_range.ip_cidr_range'
- api_field: 'networkInterfaces.aliasIpRanges.subnetworkRangeName'
field: 'network_interface.alias_ip_range.subnetwork_range_name'
{{- if ne $.TargetVersionName "ga" }}
- api_field: 'networkInterfaces.aliasIpv6Ranges.ipCidrRange'
field: 'network_interface.alias_ipv6_range.ip_cidr_range'
- api_field: 'networkInterfaces.aliasIpv6Ranges.subnetworkRangeName'
field: 'network_interface.alias_ipv6_range.subnetwork_range_name'
{{- end }}
- api_field: 'networkInterfaces.internalIpv6PrefixLength'
field: 'network_interface.internal_ipv6_prefix_length'
- api_field: 'networkInterfaces.ipv6AccessConfigs.externalIpv6'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ fields:
field: 'network_interface.alias_ip_range.ip_cidr_range'
- api_field: 'networkInterfaces.aliasIpRanges.subnetworkRangeName'
field: 'network_interface.alias_ip_range.subnetwork_range_name'
{{- if ne $.TargetVersionName "ga" }}
- api_field: 'networkInterfaces.aliasIpv6Ranges.ipCidrRange'
field: 'network_interface.alias_ipv6_range.ip_cidr_range'
- api_field: 'networkInterfaces.aliasIpv6Ranges.subnetworkRangeName'
field: 'network_interface.alias_ipv6_range.subnetwork_range_name'
{{- end }}
- api_field: 'networkInterfaces.internalIpv6PrefixLength'
field: 'network_interface.internal_ipv6_prefix_length'
- api_field: 'networkInterfaces.ipv6AccessConfigs.externalIpv6'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,32 @@ Google Cloud KMS. Only one of kms_key_self_link, rsa_encrypted_key and raw_key m
},
},

{{ if ne $.TargetVersionName `ga` -}}
"alias_ipv6_range": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Description: `An array of alias IPv6 ranges for this network interface. Can only be specified for network interfaces on subnet-mode networks.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ip_cidr_range": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
DiffSuppressFunc: IpCidrRangeDiffSuppress,
Description: `The IP CIDR range represented by this alias IPv6 range. This IP CIDR range must belong to the specified subnetwork and cannot contain IP addresses reserved by system or used by other network interfaces. At the time of writing only a netmask (e.g. /96) may be supplied, with a CIDR format resulting in an API error.`,
},
"subnetwork_range_name": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Description: `The subnetwork secondary range name specifying the secondary range from which to allocate the IP CIDR range for this alias IPv6 range. If left unspecified, the primary range of the subnetwork will be used.`,
},
},
},
},
{{- end }}

"stack_type": {
Type: schema.TypeString,
Optional: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ fields:
api_field: 'properties.networkInterfaces.aliasIpRanges.ipCidrRange'
- field: 'network_interface.alias_ip_range.subnetwork_range_name'
api_field: 'properties.networkInterfaces.aliasIpRanges.subnetworkRangeName'
{{- if ne $.TargetVersionName "ga" }}
- field: 'network_interface.alias_ipv6_range.ip_cidr_range'
api_field: 'properties.networkInterfaces.aliasIpv6Ranges.ipCidrRange'
- field: 'network_interface.alias_ipv6_range.subnetwork_range_name'
api_field: 'properties.networkInterfaces.aliasIpv6Ranges.subnetworkRangeName'
{{- end }}
- field: 'network_interface.internal_ipv6_prefix_length'
api_field: 'properties.networkInterfaces.internalIpv6PrefixLength'
- field: 'network_interface.ipv6_access_config.external_ipv6'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,35 @@ func TestAccComputeInstanceTemplate_IPv6(t *testing.T) {
})
}

{{ if ne $.TargetVersionName `ga` -}}
func TestAccComputeInstanceTemplate_aliasIpv6Range(t *testing.T) {
t.Parallel()

var instanceTemplate compute.InstanceTemplate

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccCheckComputeInstanceTemplateDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccComputeInstanceTemplate_aliasIpv6Range(acctest.RandString(t, 10)),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeInstanceTemplateExists(
t, "google_compute_instance_template.foobar", &instanceTemplate),
resource.TestCheckResourceAttr("google_compute_instance_template.foobar", "network_interface.0.alias_ipv6_range.0.ip_cidr_range", "/96"),
),
},
{
ResourceName: "google_compute_instance_template.foobar",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
{{- end }}

func TestAccComputeInstanceTemplate_networkTier(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -5665,3 +5694,48 @@ resource "google_compute_instance_template" "foobar" {
}
`, context)
}


{{ if ne $.TargetVersionName `ga` -}}
func testAccComputeInstanceTemplate_aliasIpv6Range(suffix string) string {
return fmt.Sprintf(`
resource "google_compute_network" "custom-test" {
name = "tf-test-network-%s"
auto_create_subnetworks = false
enable_ula_internal_ipv6 = true
}

resource "google_compute_subnetwork" "custom-test" {
name = "tf-test-subnetwork-%s"
region = "us-central1"
network = google_compute_network.custom-test.id
stack_type = "IPV6_ONLY"
ipv6_access_type = "INTERNAL"

secondary_ip_range {
range_name = "v6-ula"
ip_version = "IPV6"
}
}

resource "google_compute_instance_template" "foobar" {
name = "tf-test-template-%s"
machine_type = "e2-medium"

disk {
source_image = "debian-cloud/debian-11"
auto_delete = true
boot = true
}

network_interface {
subnetwork = google_compute_subnetwork.custom-test.name
stack_type = "IPV6_ONLY"
alias_ipv6_range {
ip_cidr_range = "/96"
}
}
}
`, suffix, suffix, suffix)
}
{{- end }}
Loading
Loading