diff --git a/virtualbox/provider.go b/virtualbox/provider.go index 8c587cf..bdbf006 100644 --- a/virtualbox/provider.go +++ b/virtualbox/provider.go @@ -25,7 +25,8 @@ func init() { func Provider() terraform.ResourceProvider { return &schema.Provider{ ResourcesMap: map[string]*schema.Resource{ - "virtualbox_vm": resourceVM(), + "virtualbox_vm": resourceVM(), + "virtualbox_natnetwork": resourceNatNetwork(), }, } } diff --git a/virtualbox/resource_natnetwork.go b/virtualbox/resource_natnetwork.go new file mode 100644 index 0000000..ea04de3 --- /dev/null +++ b/virtualbox/resource_natnetwork.go @@ -0,0 +1,94 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +package virtualbox + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + vbox "github.com/terra-farm/go-virtualbox" +) + +func resourceNatNetwork() *schema.Resource { + return &schema.Resource{ + Exists: resourceNatNetworkExists, + Create: resourceNatNetworkCreate, + Read: resourceNatNetworkRead, + Update: resourceNatNetworkUpdate, + Delete: resourceNatNetworkDelete, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "dhcp": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "network": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func resourceNatNetworkExists(d *schema.ResourceData, meta interface{}) (bool, error) { + name := d.Get("name").(string) + + _, err := vbox.GetNATNetwork(name) + if err != nil { + return false, err + } + + return true, nil +} + +func resourceNatNetworkCreate(d *schema.ResourceData, meta interface{}) error { + name := d.Get("name").(string) + dhcp := d.Get("dhcp").(bool) + network := d.Get("network").(string) + + _, err := vbox.CreateNATNet(name, network, dhcp) + if err != nil { + return err + } + d.SetId(name) + return resourceNatNetworkRead(d, meta) +} + +func resourceNatNetworkRead(d *schema.ResourceData, meta interface{}) error { + natnet, err := vbox.GetNATNetwork(d.Id()) + if err != nil { + return err + } + d.Set("name", natnet.Name) + d.Set("dhcp", natnet.DHCP) + d.Set("network", natnet.IPv4.String()) + return nil +} + +func resourceNatNetworkUpdate(d *schema.ResourceData, meta interface{}) error { + natnet, err := vbox.GetNATNetwork(d.Id()) + if err != nil { + return errLogf("unable to get nat network: %v", err) + } + if err := natnet.Config(); err != nil { + return errLogf("unable to remove nat network: %v", err) + } + + return nil +} + +func resourceNatNetworkDelete(d *schema.ResourceData, meta interface{}) error { + natnet, err := vbox.GetNATNetwork(d.Id()) + if err != nil { + return errLogf("unable to get nat network: %v", err) + } + if err := natnet.Delete(); err != nil { + return errLogf("unable to remove nat network: %v", err) + } + return nil +} diff --git a/virtualbox/resource_vm.go b/virtualbox/resource_vm.go index e401679..0647a02 100644 --- a/virtualbox/resource_vm.go +++ b/virtualbox/resource_vm.go @@ -127,6 +127,11 @@ func resourceVM() *schema.Resource { Optional: true, }, + "nat_network": { + Type: schema.TypeString, + Optional: true, + }, + "status": { Type: schema.TypeString, Computed: true, @@ -543,6 +548,8 @@ func netTfToVbox(d *schema.ResourceData) ([]vbox.NIC, error) { return vbox.NICNetBridged, nil case "nat": return vbox.NICNetNAT, nil + case "natnetwork": + return vbox.NICNetNATNetwork, nil case "hostonly": return vbox.NICNetHostonly, nil case "internal": @@ -595,6 +602,15 @@ func netTfToVbox(d *schema.ResourceData) ([]vbox.NIC, error) { } } + /* 'natnetwork' network need property 'nat_network' been set */ + if adapter.Network == vbox.NICNetNATNetwork { + var ok bool + adapter.NatNetwork, ok = d.Get(prefix + "nat_network").(string) + if !ok || adapter.NatNetwork == "" { + err = fmt.Errorf("'nat_network' property not set for '#%d' network adapter", i) + } + } + if err != nil { errs = append(errs, err) continue @@ -633,6 +649,8 @@ func netVboxToTf(vm *vbox.Machine, d *schema.ResourceData) error { return "bridged" case vbox.NICNetNAT: return "nat" + case vbox.NICNetNATNetwork: + return "natnetwork" case vbox.NICNetHostonly: return "hostonly" case vbox.NICNetInternal: @@ -732,6 +750,7 @@ func netVboxToTf(vm *vbox.Machine, d *schema.ResourceData) error { out["type"] = vboxToTfNetworkType(nic.Network) out["device"] = vboxToTfVdevice(nic.Hardware) out["host_interface"] = nic.HostInterface + out["nat_network"] = nic.NatNetwork out["mac_address"] = nic.MacAddr osNic, ok := osNicMap[nic.MacAddr] diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index 0164100..f08fe54 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -40,6 +40,16 @@ resource "virtualbox_vm" "node" { type = "hostonly" host_interface = "vboxnet1" } + network_adapter { + type = "natnetwork" + nat_network = virtualbox_natnetwork.vmnet10.name + } +} + +resource "virtualbox_natnetwork" "vmnet10" { + name = "vmnet10" + dhcp = true + network = "192.168.6.0/24" } output "IPAddr" { diff --git a/website/docs/r/natnetwork.html.markdown b/website/docs/r/natnetwork.html.markdown new file mode 100644 index 0000000..870d7a1 --- /dev/null +++ b/website/docs/r/natnetwork.html.markdown @@ -0,0 +1,29 @@ +--- +layout: "virtualbox" +page_title: "Virtualbox: NAT Net" +description: | + Manages a Virtualbox NAT network +--- + +# virtualbox_natnetwork + +Creates and manages a Virtualbox NAT network + +## Example Usage + +```hcl +resource "virtualbox_natnetwork" "default_net" { + name = "NAT Network" + dhcp = true + network = "192.168.56.1/24" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `name` - (Required) The name of the virtual NAT network. + box). +- `dhcp` - (Optional) If DHCP is used for the network. +- `network` - (Required) The CIDR range used for the network.