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