github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/cloudstack/resource_cloudstack_vpc.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 resourceCloudStackVPC() *schema.Resource { 13 return &schema.Resource{ 14 Create: resourceCloudStackVPCCreate, 15 Read: resourceCloudStackVPCRead, 16 Update: resourceCloudStackVPCUpdate, 17 Delete: resourceCloudStackVPCDelete, 18 19 Schema: map[string]*schema.Schema{ 20 "name": &schema.Schema{ 21 Type: schema.TypeString, 22 Required: true, 23 }, 24 25 "display_text": &schema.Schema{ 26 Type: schema.TypeString, 27 Optional: true, 28 Computed: true, 29 }, 30 31 "cidr": &schema.Schema{ 32 Type: schema.TypeString, 33 Required: true, 34 ForceNew: true, 35 }, 36 37 "vpc_offering": &schema.Schema{ 38 Type: schema.TypeString, 39 Required: true, 40 ForceNew: true, 41 }, 42 43 "network_domain": &schema.Schema{ 44 Type: schema.TypeString, 45 Optional: true, 46 Computed: true, 47 ForceNew: true, 48 }, 49 50 "project": &schema.Schema{ 51 Type: schema.TypeString, 52 Optional: true, 53 ForceNew: true, 54 }, 55 56 "source_nat_ip": &schema.Schema{ 57 Type: schema.TypeString, 58 Computed: true, 59 }, 60 61 "zone": &schema.Schema{ 62 Type: schema.TypeString, 63 Required: true, 64 ForceNew: true, 65 }, 66 }, 67 } 68 } 69 70 func resourceCloudStackVPCCreate(d *schema.ResourceData, meta interface{}) error { 71 cs := meta.(*cloudstack.CloudStackClient) 72 73 name := d.Get("name").(string) 74 75 // Retrieve the vpc_offering ID 76 vpcofferingid, e := retrieveID(cs, "vpc_offering", d.Get("vpc_offering").(string)) 77 if e != nil { 78 return e.Error() 79 } 80 81 // Retrieve the zone ID 82 zoneid, e := retrieveID(cs, "zone", d.Get("zone").(string)) 83 if e != nil { 84 return e.Error() 85 } 86 87 // Set the display text 88 displaytext, ok := d.GetOk("display_text") 89 if !ok { 90 displaytext = name 91 } 92 93 // Create a new parameter struct 94 p := cs.VPC.NewCreateVPCParams( 95 d.Get("cidr").(string), 96 displaytext.(string), 97 name, 98 vpcofferingid, 99 zoneid, 100 ) 101 102 // If there is a network domain supplied, make sure to add it to the request 103 if networkDomain, ok := d.GetOk("network_domain"); ok { 104 // Set the network domain 105 p.SetNetworkdomain(networkDomain.(string)) 106 } 107 108 // If there is a project supplied, we retrieve and set the project id 109 if project, ok := d.GetOk("project"); ok { 110 // Retrieve the project ID 111 projectid, e := retrieveID(cs, "project", project.(string)) 112 if e != nil { 113 return e.Error() 114 } 115 // Set the default project ID 116 p.SetProjectid(projectid) 117 } 118 119 // Create the new VPC 120 r, err := cs.VPC.CreateVPC(p) 121 if err != nil { 122 return fmt.Errorf("Error creating VPC %s: %s", name, err) 123 } 124 125 d.SetId(r.Id) 126 127 return resourceCloudStackVPCRead(d, meta) 128 } 129 130 func resourceCloudStackVPCRead(d *schema.ResourceData, meta interface{}) error { 131 cs := meta.(*cloudstack.CloudStackClient) 132 133 // Get the VPC details 134 v, count, err := cs.VPC.GetVPCByID(d.Id()) 135 if err != nil { 136 if count == 0 { 137 log.Printf( 138 "[DEBUG] VPC %s does no longer exist", d.Get("name").(string)) 139 d.SetId("") 140 return nil 141 } 142 143 return err 144 } 145 146 d.Set("name", v.Name) 147 d.Set("display_text", v.Displaytext) 148 d.Set("cidr", v.Cidr) 149 d.Set("network_domain", v.Networkdomain) 150 151 // Get the VPC offering details 152 o, _, err := cs.VPC.GetVPCOfferingByID(v.Vpcofferingid) 153 if err != nil { 154 return err 155 } 156 157 setValueOrID(d, "vpc_offering", o.Name, v.Vpcofferingid) 158 setValueOrID(d, "project", v.Project, v.Projectid) 159 setValueOrID(d, "zone", v.Zonename, v.Zoneid) 160 161 // Create a new parameter struct 162 p := cs.Address.NewListPublicIpAddressesParams() 163 p.SetVpcid(d.Id()) 164 p.SetIssourcenat(true) 165 166 if _, ok := d.GetOk("project"); ok { 167 p.SetProjectid(v.Projectid) 168 } 169 170 // Get the source NAT IP assigned to the VPC 171 l, err := cs.Address.ListPublicIpAddresses(p) 172 if err != nil { 173 return err 174 } 175 176 if l.Count != 1 { 177 return fmt.Errorf("Unexpected number (%d) of source NAT IPs returned", l.Count) 178 } 179 180 d.Set("source_nat_ip", l.PublicIpAddresses[0].Ipaddress) 181 182 return nil 183 } 184 185 func resourceCloudStackVPCUpdate(d *schema.ResourceData, meta interface{}) error { 186 cs := meta.(*cloudstack.CloudStackClient) 187 188 // Check if the name or display text is changed 189 if d.HasChange("name") || d.HasChange("display_text") { 190 // Create a new parameter struct 191 p := cs.VPC.NewUpdateVPCParams(d.Id()) 192 193 // Set the display text 194 displaytext, ok := d.GetOk("display_text") 195 if !ok { 196 displaytext = d.Get("name") 197 } 198 // Set the (new) display text 199 p.SetDisplaytext(displaytext.(string)) 200 201 // Update the VPC 202 _, err := cs.VPC.UpdateVPC(p) 203 if err != nil { 204 return fmt.Errorf( 205 "Error updating VPC %s: %s", d.Get("name").(string), err) 206 } 207 } 208 209 return resourceCloudStackVPCRead(d, meta) 210 } 211 212 func resourceCloudStackVPCDelete(d *schema.ResourceData, meta interface{}) error { 213 cs := meta.(*cloudstack.CloudStackClient) 214 215 // Create a new parameter struct 216 p := cs.VPC.NewDeleteVPCParams(d.Id()) 217 218 // Delete the VPC 219 _, err := cs.VPC.DeleteVPC(p) 220 if err != nil { 221 // This is a very poor way to be told the ID does no longer exist :( 222 if strings.Contains(err.Error(), fmt.Sprintf( 223 "Invalid parameter id value=%s due to incorrect long value format, "+ 224 "or entity does not exist", d.Id())) { 225 return nil 226 } 227 228 return fmt.Errorf("Error deleting VPC %s: %s", d.Get("name").(string), err) 229 } 230 231 return nil 232 }