github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/vcd/resource_vcd_network.go (about) 1 package vcd 2 3 import ( 4 "log" 5 6 "bytes" 7 "fmt" 8 "strings" 9 10 "github.com/hashicorp/terraform/helper/hashcode" 11 "github.com/hashicorp/terraform/helper/resource" 12 "github.com/hashicorp/terraform/helper/schema" 13 types "github.com/ukcloud/govcloudair/types/v56" 14 ) 15 16 func resourceVcdNetwork() *schema.Resource { 17 return &schema.Resource{ 18 Create: resourceVcdNetworkCreate, 19 Read: resourceVcdNetworkRead, 20 Delete: resourceVcdNetworkDelete, 21 22 Schema: map[string]*schema.Schema{ 23 "name": &schema.Schema{ 24 Type: schema.TypeString, 25 Required: true, 26 ForceNew: true, 27 }, 28 29 "fence_mode": &schema.Schema{ 30 Type: schema.TypeString, 31 Optional: true, 32 ForceNew: true, 33 Default: "natRouted", 34 }, 35 36 "edge_gateway": &schema.Schema{ 37 Type: schema.TypeString, 38 Required: true, 39 ForceNew: true, 40 }, 41 42 "netmask": &schema.Schema{ 43 Type: schema.TypeString, 44 Optional: true, 45 ForceNew: true, 46 Default: "255.255.255.0", 47 }, 48 49 "gateway": &schema.Schema{ 50 Type: schema.TypeString, 51 Required: true, 52 ForceNew: true, 53 }, 54 55 "dns1": &schema.Schema{ 56 Type: schema.TypeString, 57 Optional: true, 58 ForceNew: true, 59 Default: "8.8.8.8", 60 }, 61 62 "dns2": &schema.Schema{ 63 Type: schema.TypeString, 64 Optional: true, 65 ForceNew: true, 66 Default: "8.8.4.4", 67 }, 68 69 "dns_suffix": &schema.Schema{ 70 Type: schema.TypeString, 71 Optional: true, 72 ForceNew: true, 73 }, 74 75 "href": &schema.Schema{ 76 Type: schema.TypeString, 77 Optional: true, 78 Computed: true, 79 ForceNew: true, 80 }, 81 82 "dhcp_pool": &schema.Schema{ 83 Type: schema.TypeSet, 84 Optional: true, 85 ForceNew: true, 86 Elem: &schema.Resource{ 87 Schema: map[string]*schema.Schema{ 88 "start_address": &schema.Schema{ 89 Type: schema.TypeString, 90 Required: true, 91 }, 92 93 "end_address": &schema.Schema{ 94 Type: schema.TypeString, 95 Required: true, 96 }, 97 }, 98 }, 99 Set: resourceVcdNetworkIPAddressHash, 100 }, 101 "static_ip_pool": &schema.Schema{ 102 Type: schema.TypeSet, 103 Optional: true, 104 ForceNew: true, 105 Elem: &schema.Resource{ 106 Schema: map[string]*schema.Schema{ 107 "start_address": &schema.Schema{ 108 Type: schema.TypeString, 109 Required: true, 110 }, 111 112 "end_address": &schema.Schema{ 113 Type: schema.TypeString, 114 Required: true, 115 }, 116 }, 117 }, 118 Set: resourceVcdNetworkIPAddressHash, 119 }, 120 }, 121 } 122 } 123 124 func resourceVcdNetworkCreate(d *schema.ResourceData, meta interface{}) error { 125 vcdClient := meta.(*VCDClient) 126 log.Printf("[TRACE] CLIENT: %#v", vcdClient) 127 vcdClient.Mutex.Lock() 128 defer vcdClient.Mutex.Unlock() 129 130 edgeGateway, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string)) 131 132 ipRanges := expandIPRange(d.Get("static_ip_pool").(*schema.Set).List()) 133 134 newnetwork := &types.OrgVDCNetwork{ 135 Xmlns: "http://www.vmware.com/vcloud/v1.5", 136 Name: d.Get("name").(string), 137 Configuration: &types.NetworkConfiguration{ 138 FenceMode: d.Get("fence_mode").(string), 139 IPScopes: &types.IPScopes{ 140 IPScope: types.IPScope{ 141 IsInherited: false, 142 Gateway: d.Get("gateway").(string), 143 Netmask: d.Get("netmask").(string), 144 DNS1: d.Get("dns1").(string), 145 DNS2: d.Get("dns2").(string), 146 DNSSuffix: d.Get("dns_suffix").(string), 147 IPRanges: &ipRanges, 148 }, 149 }, 150 BackwardCompatibilityMode: true, 151 }, 152 EdgeGateway: &types.Reference{ 153 HREF: edgeGateway.EdgeGateway.HREF, 154 }, 155 IsShared: false, 156 } 157 158 log.Printf("[INFO] NETWORK: %#v", newnetwork) 159 160 err = retryCall(vcdClient.MaxRetryTimeout, func() *resource.RetryError { 161 return resource.RetryableError(vcdClient.OrgVdc.CreateOrgVDCNetwork(newnetwork)) 162 }) 163 if err != nil { 164 return fmt.Errorf("Error: %#v", err) 165 } 166 167 err = vcdClient.OrgVdc.Refresh() 168 if err != nil { 169 return fmt.Errorf("Error refreshing vdc: %#v", err) 170 } 171 172 network, err := vcdClient.OrgVdc.FindVDCNetwork(d.Get("name").(string)) 173 if err != nil { 174 return fmt.Errorf("Error finding network: %#v", err) 175 } 176 177 if dhcp, ok := d.GetOk("dhcp_pool"); ok { 178 err = retryCall(vcdClient.MaxRetryTimeout, func() *resource.RetryError { 179 task, err := edgeGateway.AddDhcpPool(network.OrgVDCNetwork, dhcp.(*schema.Set).List()) 180 if err != nil { 181 return resource.RetryableError(fmt.Errorf("Error adding DHCP pool: %#v", err)) 182 } 183 184 return resource.RetryableError(task.WaitTaskCompletion()) 185 }) 186 if err != nil { 187 return fmt.Errorf("Error completing tasks: %#v", err) 188 } 189 190 } 191 192 d.SetId(d.Get("name").(string)) 193 194 return resourceVcdNetworkRead(d, meta) 195 } 196 197 func resourceVcdNetworkRead(d *schema.ResourceData, meta interface{}) error { 198 vcdClient := meta.(*VCDClient) 199 log.Printf("[DEBUG] VCD Client configuration: %#v", vcdClient) 200 log.Printf("[DEBUG] VCD Client configuration: %#v", vcdClient.OrgVdc) 201 202 err := vcdClient.OrgVdc.Refresh() 203 if err != nil { 204 return fmt.Errorf("Error refreshing vdc: %#v", err) 205 } 206 207 network, err := vcdClient.OrgVdc.FindVDCNetwork(d.Id()) 208 if err != nil { 209 log.Printf("[DEBUG] Network no longer exists. Removing from tfstate") 210 d.SetId("") 211 return nil 212 } 213 214 d.Set("name", network.OrgVDCNetwork.Name) 215 d.Set("href", network.OrgVDCNetwork.HREF) 216 if c := network.OrgVDCNetwork.Configuration; c != nil { 217 d.Set("fence_mode", c.FenceMode) 218 if c.IPScopes != nil { 219 d.Set("gateway", c.IPScopes.IPScope.Gateway) 220 d.Set("netmask", c.IPScopes.IPScope.Netmask) 221 d.Set("dns1", c.IPScopes.IPScope.DNS1) 222 d.Set("dns2", c.IPScopes.IPScope.DNS2) 223 } 224 } 225 226 return nil 227 } 228 229 func resourceVcdNetworkDelete(d *schema.ResourceData, meta interface{}) error { 230 vcdClient := meta.(*VCDClient) 231 vcdClient.Mutex.Lock() 232 defer vcdClient.Mutex.Unlock() 233 err := vcdClient.OrgVdc.Refresh() 234 if err != nil { 235 return fmt.Errorf("Error refreshing vdc: %#v", err) 236 } 237 238 network, err := vcdClient.OrgVdc.FindVDCNetwork(d.Id()) 239 if err != nil { 240 return fmt.Errorf("Error finding network: %#v", err) 241 } 242 243 err = retryCall(vcdClient.MaxRetryTimeout, func() *resource.RetryError { 244 task, err := network.Delete() 245 if err != nil { 246 return resource.RetryableError( 247 fmt.Errorf("Error Deleting Network: %#v", err)) 248 } 249 return resource.RetryableError(task.WaitTaskCompletion()) 250 }) 251 if err != nil { 252 return err 253 } 254 255 return nil 256 } 257 258 func resourceVcdNetworkIPAddressHash(v interface{}) int { 259 var buf bytes.Buffer 260 m := v.(map[string]interface{}) 261 buf.WriteString(fmt.Sprintf("%s-", 262 strings.ToLower(m["start_address"].(string)))) 263 buf.WriteString(fmt.Sprintf("%s-", 264 strings.ToLower(m["end_address"].(string)))) 265 266 return hashcode.String(buf.String()) 267 }