github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/openstack/resource_openstack_networking_network_v2.go (about) 1 package openstack 2 3 import ( 4 "fmt" 5 "log" 6 "strconv" 7 "time" 8 9 "github.com/hashicorp/terraform/helper/resource" 10 "github.com/hashicorp/terraform/helper/schema" 11 12 "github.com/rackspace/gophercloud" 13 "github.com/rackspace/gophercloud/openstack/networking/v2/networks" 14 ) 15 16 func resourceNetworkingNetworkV2() *schema.Resource { 17 return &schema.Resource{ 18 Create: resourceNetworkingNetworkV2Create, 19 Read: resourceNetworkingNetworkV2Read, 20 Update: resourceNetworkingNetworkV2Update, 21 Delete: resourceNetworkingNetworkV2Delete, 22 23 Schema: map[string]*schema.Schema{ 24 "region": &schema.Schema{ 25 Type: schema.TypeString, 26 Required: true, 27 ForceNew: true, 28 DefaultFunc: envDefaultFuncAllowMissing("OS_REGION_NAME"), 29 }, 30 "name": &schema.Schema{ 31 Type: schema.TypeString, 32 Optional: true, 33 ForceNew: false, 34 }, 35 "admin_state_up": &schema.Schema{ 36 Type: schema.TypeString, 37 Optional: true, 38 ForceNew: false, 39 Computed: true, 40 }, 41 "shared": &schema.Schema{ 42 Type: schema.TypeString, 43 Optional: true, 44 ForceNew: false, 45 Computed: true, 46 }, 47 "tenant_id": &schema.Schema{ 48 Type: schema.TypeString, 49 Optional: true, 50 ForceNew: true, 51 Computed: true, 52 }, 53 }, 54 } 55 } 56 57 func resourceNetworkingNetworkV2Create(d *schema.ResourceData, meta interface{}) error { 58 config := meta.(*Config) 59 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 60 if err != nil { 61 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 62 } 63 64 createOpts := networks.CreateOpts{ 65 Name: d.Get("name").(string), 66 TenantID: d.Get("tenant_id").(string), 67 } 68 69 asuRaw := d.Get("admin_state_up").(string) 70 if asuRaw != "" { 71 asu, err := strconv.ParseBool(asuRaw) 72 if err != nil { 73 return fmt.Errorf("admin_state_up, if provided, must be either 'true' or 'false'") 74 } 75 createOpts.AdminStateUp = &asu 76 } 77 78 sharedRaw := d.Get("shared").(string) 79 if sharedRaw != "" { 80 shared, err := strconv.ParseBool(sharedRaw) 81 if err != nil { 82 return fmt.Errorf("shared, if provided, must be either 'true' or 'false': %v", err) 83 } 84 createOpts.Shared = &shared 85 } 86 87 log.Printf("[DEBUG] Create Options: %#v", createOpts) 88 n, err := networks.Create(networkingClient, createOpts).Extract() 89 if err != nil { 90 return fmt.Errorf("Error creating OpenStack Neutron network: %s", err) 91 } 92 log.Printf("[INFO] Network ID: %s", n.ID) 93 94 log.Printf("[DEBUG] Waiting for Network (%s) to become available", n.ID) 95 96 stateConf := &resource.StateChangeConf{ 97 Pending: []string{"BUILD"}, 98 Target: "ACTIVE", 99 Refresh: waitForNetworkActive(networkingClient, n.ID), 100 Timeout: 2 * time.Minute, 101 Delay: 5 * time.Second, 102 MinTimeout: 3 * time.Second, 103 } 104 105 _, err = stateConf.WaitForState() 106 107 d.SetId(n.ID) 108 109 return resourceNetworkingNetworkV2Read(d, meta) 110 } 111 112 func resourceNetworkingNetworkV2Read(d *schema.ResourceData, meta interface{}) error { 113 config := meta.(*Config) 114 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 115 if err != nil { 116 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 117 } 118 119 n, err := networks.Get(networkingClient, d.Id()).Extract() 120 if err != nil { 121 return CheckDeleted(d, err, "network") 122 } 123 124 log.Printf("[DEBUG] Retreived Network %s: %+v", d.Id(), n) 125 126 d.Set("name", n.Name) 127 d.Set("admin_state_up", strconv.FormatBool(n.AdminStateUp)) 128 d.Set("shared", strconv.FormatBool(n.Shared)) 129 d.Set("tenant_id", n.TenantID) 130 131 return nil 132 } 133 134 func resourceNetworkingNetworkV2Update(d *schema.ResourceData, meta interface{}) error { 135 config := meta.(*Config) 136 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 137 if err != nil { 138 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 139 } 140 141 var updateOpts networks.UpdateOpts 142 if d.HasChange("name") { 143 updateOpts.Name = d.Get("name").(string) 144 } 145 if d.HasChange("admin_state_up") { 146 asuRaw := d.Get("admin_state_up").(string) 147 if asuRaw != "" { 148 asu, err := strconv.ParseBool(asuRaw) 149 if err != nil { 150 return fmt.Errorf("admin_state_up, if provided, must be either 'true' or 'false'") 151 } 152 updateOpts.AdminStateUp = &asu 153 } 154 } 155 if d.HasChange("shared") { 156 sharedRaw := d.Get("shared").(string) 157 if sharedRaw != "" { 158 shared, err := strconv.ParseBool(sharedRaw) 159 if err != nil { 160 return fmt.Errorf("shared, if provided, must be either 'true' or 'false': %v", err) 161 } 162 updateOpts.Shared = &shared 163 } 164 } 165 166 log.Printf("[DEBUG] Updating Network %s with options: %+v", d.Id(), updateOpts) 167 168 _, err = networks.Update(networkingClient, d.Id(), updateOpts).Extract() 169 if err != nil { 170 return fmt.Errorf("Error updating OpenStack Neutron Network: %s", err) 171 } 172 173 return resourceNetworkingNetworkV2Read(d, meta) 174 } 175 176 func resourceNetworkingNetworkV2Delete(d *schema.ResourceData, meta interface{}) error { 177 config := meta.(*Config) 178 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 179 if err != nil { 180 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 181 } 182 183 stateConf := &resource.StateChangeConf{ 184 Pending: []string{"ACTIVE"}, 185 Target: "DELETED", 186 Refresh: waitForNetworkDelete(networkingClient, d.Id()), 187 Timeout: 2 * time.Minute, 188 Delay: 5 * time.Second, 189 MinTimeout: 3 * time.Second, 190 } 191 192 _, err = stateConf.WaitForState() 193 if err != nil { 194 return fmt.Errorf("Error deleting OpenStack Neutron Network: %s", err) 195 } 196 197 d.SetId("") 198 return nil 199 } 200 201 func waitForNetworkActive(networkingClient *gophercloud.ServiceClient, networkId string) resource.StateRefreshFunc { 202 return func() (interface{}, string, error) { 203 n, err := networks.Get(networkingClient, networkId).Extract() 204 if err != nil { 205 return nil, "", err 206 } 207 208 log.Printf("[DEBUG] OpenStack Neutron Network: %+v", n) 209 if n.Status == "DOWN" || n.Status == "ACTIVE" { 210 return n, "ACTIVE", nil 211 } 212 213 return n, n.Status, nil 214 } 215 } 216 217 func waitForNetworkDelete(networkingClient *gophercloud.ServiceClient, networkId string) resource.StateRefreshFunc { 218 return func() (interface{}, string, error) { 219 log.Printf("[DEBUG] Attempting to delete OpenStack Network %s.\n", networkId) 220 221 n, err := networks.Get(networkingClient, networkId).Extract() 222 if err != nil { 223 errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError) 224 if !ok { 225 return n, "ACTIVE", err 226 } 227 if errCode.Actual == 404 { 228 log.Printf("[DEBUG] Successfully deleted OpenStack Network %s", networkId) 229 return n, "DELETED", nil 230 } 231 } 232 233 err = networks.Delete(networkingClient, networkId).ExtractErr() 234 if err != nil { 235 errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError) 236 if !ok { 237 return n, "ACTIVE", err 238 } 239 if errCode.Actual == 404 { 240 log.Printf("[DEBUG] Successfully deleted OpenStack Network %s", networkId) 241 return n, "DELETED", nil 242 } 243 } 244 245 log.Printf("[DEBUG] OpenStack Network %s still active.\n", networkId) 246 return n, "ACTIVE", nil 247 } 248 }