github.com/mkuzmin/terraform@v0.3.7-0.20161118171027-ec4c00ff92a9/builtin/providers/cloudstack/resource_cloudstack_static_nat.go (about) 1 package cloudstack 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 8 "github.com/hashicorp/terraform/helper/schema" 9 "github.com/xanzy/go-cloudstack/cloudstack" 10 ) 11 12 func resourceCloudStackStaticNAT() *schema.Resource { 13 return &schema.Resource{ 14 Create: resourceCloudStackStaticNATCreate, 15 Exists: resourceCloudStackStaticNATExists, 16 Read: resourceCloudStackStaticNATRead, 17 Delete: resourceCloudStackStaticNATDelete, 18 19 Schema: map[string]*schema.Schema{ 20 "ip_address_id": &schema.Schema{ 21 Type: schema.TypeString, 22 Required: true, 23 ForceNew: true, 24 }, 25 26 "network_id": &schema.Schema{ 27 Type: schema.TypeString, 28 Optional: true, 29 ForceNew: true, 30 Deprecated: "network_id is deprecated and can be safely omitted", 31 }, 32 33 "virtual_machine_id": &schema.Schema{ 34 Type: schema.TypeString, 35 Required: true, 36 ForceNew: true, 37 }, 38 39 "vm_guest_ip": &schema.Schema{ 40 Type: schema.TypeString, 41 Optional: true, 42 Computed: true, 43 ForceNew: true, 44 }, 45 46 "project": &schema.Schema{ 47 Type: schema.TypeString, 48 Optional: true, 49 Computed: true, 50 ForceNew: true, 51 }, 52 }, 53 } 54 } 55 56 func resourceCloudStackStaticNATCreate(d *schema.ResourceData, meta interface{}) error { 57 cs := meta.(*cloudstack.CloudStackClient) 58 59 ipaddressid := d.Get("ip_address_id").(string) 60 61 vm, _, err := cs.VirtualMachine.GetVirtualMachineByID( 62 d.Get("virtual_machine_id").(string), 63 cloudstack.WithProject(d.Get("project").(string)), 64 ) 65 if err != nil { 66 return err 67 } 68 69 // Create a new parameter struct 70 p := cs.NAT.NewEnableStaticNatParams(ipaddressid, vm.Id) 71 72 if vmGuestIP, ok := d.GetOk("vm_guest_ip"); ok { 73 p.SetVmguestip(vmGuestIP.(string)) 74 75 // Set the network ID based on the guest IP, needed when the public IP address 76 // is not associated with any network yet (VPC case) 77 for _, nic := range vm.Nic { 78 if vmGuestIP.(string) == nic.Ipaddress { 79 p.SetNetworkid(nic.Networkid) 80 } 81 } 82 } else { 83 // If no guest IP is configured, use the primary NIC 84 p.SetNetworkid(vm.Nic[0].Networkid) 85 } 86 87 _, err = cs.NAT.EnableStaticNat(p) 88 if err != nil { 89 return fmt.Errorf("Error enabling static NAT: %s", err) 90 } 91 92 d.SetId(ipaddressid) 93 94 return resourceCloudStackStaticNATRead(d, meta) 95 } 96 97 func resourceCloudStackStaticNATExists(d *schema.ResourceData, meta interface{}) (bool, error) { 98 cs := meta.(*cloudstack.CloudStackClient) 99 100 // Get the IP address details 101 ip, count, err := cs.Address.GetPublicIpAddressByID( 102 d.Id(), 103 cloudstack.WithProject(d.Get("project").(string)), 104 ) 105 if err != nil { 106 if count == 0 { 107 log.Printf("[DEBUG] IP address with ID %s no longer exists", d.Id()) 108 return false, nil 109 } 110 111 return false, err 112 } 113 114 return ip.Isstaticnat, nil 115 } 116 117 func resourceCloudStackStaticNATRead(d *schema.ResourceData, meta interface{}) error { 118 cs := meta.(*cloudstack.CloudStackClient) 119 120 // Get the IP address details 121 ip, count, err := cs.Address.GetPublicIpAddressByID( 122 d.Id(), 123 cloudstack.WithProject(d.Get("project").(string)), 124 ) 125 if err != nil { 126 if count == 0 { 127 log.Printf("[DEBUG] IP address with ID %s no longer exists", d.Id()) 128 d.SetId("") 129 return nil 130 } 131 132 return err 133 } 134 135 if !ip.Isstaticnat { 136 log.Printf("[DEBUG] Static NAT is no longer enabled for IP address with ID %s", d.Id()) 137 d.SetId("") 138 return nil 139 } 140 141 d.Set("virtual_machine_id", ip.Virtualmachineid) 142 d.Set("vm_guest_ip", ip.Vmipaddress) 143 144 setValueOrID(d, "project", ip.Project, ip.Projectid) 145 146 return nil 147 } 148 149 func resourceCloudStackStaticNATDelete(d *schema.ResourceData, meta interface{}) error { 150 cs := meta.(*cloudstack.CloudStackClient) 151 152 // Create a new parameter struct 153 p := cs.NAT.NewDisableStaticNatParams(d.Id()) 154 155 // Disable static NAT 156 _, err := cs.NAT.DisableStaticNat(p) 157 if err != nil { 158 // This is a very poor way to be told the ID does no longer exist :( 159 if strings.Contains(err.Error(), fmt.Sprintf( 160 "Invalid parameter id value=%s due to incorrect long value format, "+ 161 "or entity does not exist", d.Id())) { 162 return nil 163 } 164 165 return fmt.Errorf("Error disabling static NAT: %s", err) 166 } 167 168 return nil 169 }