provider/vsphere: Change ip_address parameter to ipv4_address and ipv6_address for ipv6 support

This commit is contained in:
Takaaki Furukawa 2015-11-24 09:53:11 +09:00
parent 73e1f4ce52
commit 68ac4bceaf
3 changed files with 106 additions and 43 deletions

View File

@ -28,11 +28,13 @@ var DefaultDNSServers = []string{
} }
type networkInterface struct { type networkInterface struct {
deviceName string deviceName string
label string label string
ipAddress string ipv4Address string
subnetMask string ipv4PrefixLength int
adapterType string // TODO: Make "adapter_type" argument ipv6Address string
ipv6PrefixLength int
adapterType string // TODO: Make "adapter_type" argument
} }
type hardDisk struct { type hardDisk struct {
@ -148,15 +150,40 @@ func resourceVSphereVirtualMachine() *schema.Resource {
}, },
"ip_address": &schema.Schema{ "ip_address": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
Deprecated: "Please use ipv4_address",
},
"subnet_mask": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
Deprecated: "Please use ipv4_prefix_length",
},
"ipv4_address": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
},
"ipv4_prefix_length": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
// TODO: Imprement ipv6 parameters to be optional
"ipv6_address": &schema.Schema{
Type: schema.TypeString,
Computed: true,
ForceNew: true, ForceNew: true,
}, },
"subnet_mask": &schema.Schema{ "ipv6_prefix_length": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeInt,
Optional: true,
Computed: true, Computed: true,
ForceNew: true, ForceNew: true,
}, },
@ -267,10 +294,23 @@ func resourceVSphereVirtualMachineCreate(d *schema.ResourceData, meta interface{
network := v.(map[string]interface{}) network := v.(map[string]interface{})
networks[i].label = network["label"].(string) networks[i].label = network["label"].(string)
if v, ok := network["ip_address"].(string); ok && v != "" { if v, ok := network["ip_address"].(string); ok && v != "" {
networks[i].ipAddress = v networks[i].ipv4Address = v
} }
if v, ok := network["subnet_mask"].(string); ok && v != "" { if v, ok := network["subnet_mask"].(string); ok && v != "" {
networks[i].subnetMask = v ip := net.ParseIP(v).To4()
if ip != nil {
mask := net.IPv4Mask(ip[0], ip[1], ip[2], ip[3])
pl, _ := mask.Size()
networks[i].ipv4PrefixLength = pl
} else {
return fmt.Errorf("subnet_mask parameter is invalid.")
}
}
if v, ok := network["ipv4_address"].(string); ok && v != "" {
networks[i].ipv4Address = v
}
if v, ok := network["ipv4_prefix_length"].(int); ok && v != 0 {
networks[i].ipv4PrefixLength = v
} }
} }
vm.networkInterfaces = networks vm.networkInterfaces = networks
@ -321,7 +361,7 @@ func resourceVSphereVirtualMachineCreate(d *schema.ResourceData, meta interface{
} }
} }
if _, ok := d.GetOk("network_interface.0.ip_address"); !ok { if _, ok := d.GetOk("network_interface.0.ipv4_address"); !ok {
if v, ok := d.GetOk("boot_delay"); ok { if v, ok := d.GetOk("boot_delay"); ok {
stateConf := &resource.StateChangeConf{ stateConf := &resource.StateChangeConf{
Pending: []string{"pending"}, Pending: []string{"pending"},
@ -377,15 +417,22 @@ func resourceVSphereVirtualMachineRead(d *schema.ResourceData, meta interface{})
log.Printf("[DEBUG] %#v", v.Network) log.Printf("[DEBUG] %#v", v.Network)
networkInterface := make(map[string]interface{}) networkInterface := make(map[string]interface{})
networkInterface["label"] = v.Network networkInterface["label"] = v.Network
if len(v.IpAddress) > 0 { for _, ip := range v.IpConfig.IpAddress {
log.Printf("[DEBUG] %#v", v.IpAddress[0]) p := net.ParseIP(ip.IpAddress)
networkInterface["ip_address"] = v.IpAddress[0] if p.To4() != nil {
log.Printf("[DEBUG] %#v", p.String())
m := net.CIDRMask(v.IpConfig.IpAddress[0].PrefixLength, 32) log.Printf("[DEBUG] %#v", ip.PrefixLength)
subnetMask := net.IPv4(m[0], m[1], m[2], m[3]) networkInterface["ipv4_address"] = p.String()
networkInterface["subnet_mask"] = subnetMask.String() networkInterface["ipv4_prefix_length"] = ip.PrefixLength
log.Printf("[DEBUG] %#v", subnetMask.String()) } else if p.To16() != nil {
log.Printf("[DEBUG] %#v", p.String())
log.Printf("[DEBUG] %#v", ip.PrefixLength)
networkInterface["ipv6_address"] = p.String()
networkInterface["ipv6_prefix_length"] = ip.PrefixLength
}
log.Printf("[DEBUG] networkInterface: %#v", networkInterface)
} }
log.Printf("[DEBUG] networkInterface: %#v", networkInterface)
networkInterfaces = append(networkInterfaces, networkInterface) networkInterfaces = append(networkInterfaces, networkInterface)
} }
} }
@ -420,14 +467,6 @@ func resourceVSphereVirtualMachineRead(d *schema.ResourceData, meta interface{})
d.Set("cpu", mvm.Summary.Config.NumCpu) d.Set("cpu", mvm.Summary.Config.NumCpu)
d.Set("datastore", rootDatastore) d.Set("datastore", rootDatastore)
// Initialize the connection info
if len(networkInterfaces) > 0 {
d.SetConnInfo(map[string]string{
"type": "ssh",
"host": networkInterfaces[0]["ip_address"].(string),
})
}
return nil return nil
} }
@ -967,23 +1006,31 @@ func (vm *virtualMachine) deployVirtualMachine(c *govmomi.Client) error {
} }
networkDevices = append(networkDevices, nd) networkDevices = append(networkDevices, nd)
// TODO: IPv6 support
var ipSetting types.CustomizationIPSettings var ipSetting types.CustomizationIPSettings
if network.ipAddress == "" { if network.ipv4Address == "" {
ipSetting = types.CustomizationIPSettings{ ipSetting = types.CustomizationIPSettings{
Ip: &types.CustomizationDhcpIpGenerator{}, Ip: &types.CustomizationDhcpIpGenerator{},
} }
} else { } else {
if network.ipv4PrefixLength == 0 {
return fmt.Errorf("Error: ipv4_prefix_length argument is empty.")
}
m := net.CIDRMask(network.ipv4PrefixLength, 32)
sm := net.IPv4(m[0], m[1], m[2], m[3])
subnetMask := sm.String()
log.Printf("[DEBUG] gateway: %v", vm.gateway) log.Printf("[DEBUG] gateway: %v", vm.gateway)
log.Printf("[DEBUG] ip address: %v", network.ipAddress) log.Printf("[DEBUG] ipv4 address: %v", network.ipv4Address)
log.Printf("[DEBUG] subnet mask: %v", network.subnetMask) log.Printf("[DEBUG] ipv4 prefix length: %v", network.ipv4PrefixLength)
log.Printf("[DEBUG] ipv4 subnet mask: %v", subnetMask)
ipSetting = types.CustomizationIPSettings{ ipSetting = types.CustomizationIPSettings{
Gateway: []string{ Gateway: []string{
vm.gateway, vm.gateway,
}, },
Ip: &types.CustomizationFixedIp{ Ip: &types.CustomizationFixedIp{
IpAddress: network.ipAddress, IpAddress: network.ipv4Address,
}, },
SubnetMask: network.subnetMask, SubnetMask: subnetMask,
} }
} }

View File

@ -198,8 +198,8 @@ resource "vsphere_virtual_machine" "foo" {
gateway = "%s" gateway = "%s"
network_interface { network_interface {
label = "%s" label = "%s"
ip_address = "%s" ipv4_address = "%s"
subnet_mask = "255.255.255.0" ipv4_prefix_length = 24
} }
disk { disk {
%s %s

View File

@ -49,21 +49,37 @@ The following arguments are supported:
* `disk` - (Required) Configures virtual disks; see [Disks](#disks) below for details * `disk` - (Required) Configures virtual disks; see [Disks](#disks) below for details
* `boot_delay` - (Optional) Time in seconds to wait for machine network to be ready. * `boot_delay` - (Optional) Time in seconds to wait for machine network to be ready.
<a id="network-interfaces"></a> The `network_interface` block supports:
## Network Interfaces
Network interfaces support the following attributes:
* `label` - (Required) Label to assign to this network interface * `label` - (Required) Label to assign to this network interface
* `ip_address` - (Optional) Static IP to assign to this network interface. Interface will use DHCP if this is left blank. Currently only IPv4 IP addresses are supported. * `ipv4_address` - (Optional) Static IP to assign to this network interface. Interface will use DHCP if this is left blank. Currently only IPv4 IP addresses are supported.
* `subnet_mask` - (Optional) Subnet mask to use when statically assigning an IP. * `ipv4_prefix_length` - (Optional) prefix length to use when statically assigning an IP.
<a id="disks"></a> The following arguments are maintained for backwards compatibility and may be
## Disks removed in a future version:
Disks support the following attributes: * `ip_address` - __Deprecated, please use `ipv4_address` instead_.
* `subnet_mask` - __Deprecated, please use `ipv4_prefix_length` instead_.
The `disk` block supports:
* `template` - (Required if size not provided) Template for this disk. * `template` - (Required if size not provided) Template for this disk.
* `datastore` - (Optional) Datastore for this disk * `datastore` - (Optional) Datastore for this disk
* `size` - (Required if template not provided) Size of this disk (in GB). * `size` - (Required if template not provided) Size of this disk (in GB).
* `iops` - (Optional) Number of virtual iops to allocate for this disk. * `iops` - (Optional) Number of virtual iops to allocate for this disk.
## Attributes Reference
The following attributes are exported:
* `id` - The instance ID.
* `name` - See Argument Reference above.
* `vcpu` - See Argument Reference above.
* `memory` - See Argument Reference above.
* `datacenter` - See Argument Reference above.
* `network_interface/label` - See Argument Reference above.
* `network_interface/ipv4_address` - See Argument Reference above.
* `network_interface/ipv4_prefix_length` - See Argument Reference above.
* `network_interface/ipv6_address` - Assigned static IPv6 address.
* `network_interface/ipv6_prefix_length` - Prefix length of assigned static IPv6 address.