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