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  }