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