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