github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/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 name := d.Get("name").(string) 186 187 // Check if the name is changed 188 if d.HasChange("name") { 189 // Create a new parameter struct 190 p := cs.VPC.NewUpdateVPCParams(d.Id()) 191 192 // Set the new name 193 p.SetName(name) 194 195 // Update the VPC 196 _, err := cs.VPC.UpdateVPC(p) 197 if err != nil { 198 return fmt.Errorf( 199 "Error updating name of VPC %s: %s", name, err) 200 } 201 } 202 203 // Check if the display text is changed 204 if d.HasChange("display_text") { 205 // Create a new parameter struct 206 p := cs.VPC.NewUpdateVPCParams(d.Id()) 207 208 // Set the display text 209 displaytext, ok := d.GetOk("display_text") 210 if !ok { 211 displaytext = d.Get("name") 212 } 213 214 // Set the new display text 215 p.SetDisplaytext(displaytext.(string)) 216 217 // Update the VPC 218 _, err := cs.VPC.UpdateVPC(p) 219 if err != nil { 220 return fmt.Errorf( 221 "Error updating display test of VPC %s: %s", name, err) 222 } 223 } 224 225 return resourceCloudStackVPCRead(d, meta) 226 } 227 228 func resourceCloudStackVPCDelete(d *schema.ResourceData, meta interface{}) error { 229 cs := meta.(*cloudstack.CloudStackClient) 230 231 // Create a new parameter struct 232 p := cs.VPC.NewDeleteVPCParams(d.Id()) 233 234 // Delete the VPC 235 _, err := cs.VPC.DeleteVPC(p) 236 if err != nil { 237 // This is a very poor way to be told the ID does no longer exist :( 238 if strings.Contains(err.Error(), fmt.Sprintf( 239 "Invalid parameter id value=%s due to incorrect long value format, "+ 240 "or entity does not exist", d.Id())) { 241 return nil 242 } 243 244 return fmt.Errorf("Error deleting VPC %s: %s", d.Get("name").(string), err) 245 } 246 247 return nil 248 }