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