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