github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/openstack/resource_openstack_networking_router_interface_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/gophercloud/gophercloud" 12 "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers" 13 "github.com/gophercloud/gophercloud/openstack/networking/v2/ports" 14 ) 15 16 func resourceNetworkingRouterInterfaceV2() *schema.Resource { 17 return &schema.Resource{ 18 Create: resourceNetworkingRouterInterfaceV2Create, 19 Read: resourceNetworkingRouterInterfaceV2Read, 20 Delete: resourceNetworkingRouterInterfaceV2Delete, 21 22 Timeouts: &schema.ResourceTimeout{ 23 Create: schema.DefaultTimeout(10 * time.Minute), 24 Delete: schema.DefaultTimeout(10 * time.Minute), 25 }, 26 27 Schema: map[string]*schema.Schema{ 28 "region": &schema.Schema{ 29 Type: schema.TypeString, 30 Required: true, 31 ForceNew: true, 32 DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""), 33 }, 34 "router_id": &schema.Schema{ 35 Type: schema.TypeString, 36 Required: true, 37 ForceNew: true, 38 }, 39 "subnet_id": &schema.Schema{ 40 Type: schema.TypeString, 41 Optional: true, 42 ForceNew: true, 43 }, 44 "port_id": &schema.Schema{ 45 Type: schema.TypeString, 46 Optional: true, 47 ForceNew: true, 48 }, 49 }, 50 } 51 } 52 53 func resourceNetworkingRouterInterfaceV2Create(d *schema.ResourceData, meta interface{}) error { 54 config := meta.(*Config) 55 networkingClient, err := config.networkingV2Client(GetRegion(d)) 56 if err != nil { 57 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 58 } 59 60 createOpts := routers.AddInterfaceOpts{ 61 SubnetID: d.Get("subnet_id").(string), 62 PortID: d.Get("port_id").(string), 63 } 64 65 log.Printf("[DEBUG] Create Options: %#v", createOpts) 66 n, err := routers.AddInterface(networkingClient, d.Get("router_id").(string), createOpts).Extract() 67 if err != nil { 68 return fmt.Errorf("Error creating OpenStack Neutron router interface: %s", err) 69 } 70 log.Printf("[INFO] Router interface Port ID: %s", n.PortID) 71 72 log.Printf("[DEBUG] Waiting for Router Interface (%s) to become available", n.PortID) 73 74 stateConf := &resource.StateChangeConf{ 75 Pending: []string{"BUILD", "PENDING_CREATE", "PENDING_UPDATE"}, 76 Target: []string{"ACTIVE"}, 77 Refresh: waitForRouterInterfaceActive(networkingClient, n.PortID), 78 Timeout: d.Timeout(schema.TimeoutCreate), 79 Delay: 5 * time.Second, 80 MinTimeout: 3 * time.Second, 81 } 82 83 _, err = stateConf.WaitForState() 84 85 d.SetId(n.PortID) 86 87 return resourceNetworkingRouterInterfaceV2Read(d, meta) 88 } 89 90 func resourceNetworkingRouterInterfaceV2Read(d *schema.ResourceData, meta interface{}) error { 91 config := meta.(*Config) 92 networkingClient, err := config.networkingV2Client(GetRegion(d)) 93 if err != nil { 94 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 95 } 96 97 n, err := ports.Get(networkingClient, d.Id()).Extract() 98 if err != nil { 99 if _, ok := err.(gophercloud.ErrDefault404); ok { 100 d.SetId("") 101 return nil 102 } 103 104 return fmt.Errorf("Error retrieving OpenStack Neutron Router Interface: %s", err) 105 } 106 107 log.Printf("[DEBUG] Retrieved Router Interface %s: %+v", d.Id(), n) 108 109 return nil 110 } 111 112 func resourceNetworkingRouterInterfaceV2Delete(d *schema.ResourceData, meta interface{}) error { 113 config := meta.(*Config) 114 networkingClient, err := config.networkingV2Client(GetRegion(d)) 115 if err != nil { 116 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 117 } 118 119 stateConf := &resource.StateChangeConf{ 120 Pending: []string{"ACTIVE"}, 121 Target: []string{"DELETED"}, 122 Refresh: waitForRouterInterfaceDelete(networkingClient, d), 123 Timeout: d.Timeout(schema.TimeoutDelete), 124 Delay: 5 * time.Second, 125 MinTimeout: 3 * time.Second, 126 } 127 128 _, err = stateConf.WaitForState() 129 if err != nil { 130 return fmt.Errorf("Error deleting OpenStack Neutron Router Interface: %s", err) 131 } 132 133 d.SetId("") 134 return nil 135 } 136 137 func waitForRouterInterfaceActive(networkingClient *gophercloud.ServiceClient, rId string) resource.StateRefreshFunc { 138 return func() (interface{}, string, error) { 139 r, err := ports.Get(networkingClient, rId).Extract() 140 if err != nil { 141 return nil, "", err 142 } 143 144 log.Printf("[DEBUG] OpenStack Neutron Router Interface: %+v", r) 145 return r, r.Status, nil 146 } 147 } 148 149 func waitForRouterInterfaceDelete(networkingClient *gophercloud.ServiceClient, d *schema.ResourceData) resource.StateRefreshFunc { 150 return func() (interface{}, string, error) { 151 routerId := d.Get("router_id").(string) 152 routerInterfaceId := d.Id() 153 154 log.Printf("[DEBUG] Attempting to delete OpenStack Router Interface %s.", routerInterfaceId) 155 156 removeOpts := routers.RemoveInterfaceOpts{ 157 SubnetID: d.Get("subnet_id").(string), 158 PortID: d.Get("port_id").(string), 159 } 160 161 r, err := ports.Get(networkingClient, routerInterfaceId).Extract() 162 if err != nil { 163 if _, ok := err.(gophercloud.ErrDefault404); ok { 164 log.Printf("[DEBUG] Successfully deleted OpenStack Router Interface %s", routerInterfaceId) 165 return r, "DELETED", nil 166 } 167 return r, "ACTIVE", err 168 } 169 170 _, err = routers.RemoveInterface(networkingClient, routerId, removeOpts).Extract() 171 if err != nil { 172 if _, ok := err.(gophercloud.ErrDefault404); ok { 173 log.Printf("[DEBUG] Successfully deleted OpenStack Router Interface %s.", routerInterfaceId) 174 return r, "DELETED", nil 175 } 176 if errCode, ok := err.(gophercloud.ErrUnexpectedResponseCode); ok { 177 if errCode.Actual == 409 { 178 log.Printf("[DEBUG] Router Interface %s is still in use.", routerInterfaceId) 179 return r, "ACTIVE", nil 180 } 181 } 182 183 return r, "ACTIVE", err 184 } 185 186 log.Printf("[DEBUG] OpenStack Router Interface %s is still active.", routerInterfaceId) 187 return r, "ACTIVE", nil 188 } 189 }