github.com/joshgarnett/terraform@v0.5.4-0.20160219181435-92dc20bb3594/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  			"distributed": &schema.Schema{
    41  				Type:     schema.TypeBool,
    42  				Optional: true,
    43  				ForceNew: true,
    44  				Computed: true,
    45  			},
    46  			"external_gateway": &schema.Schema{
    47  				Type:     schema.TypeString,
    48  				Optional: true,
    49  				ForceNew: false,
    50  			},
    51  			"tenant_id": &schema.Schema{
    52  				Type:     schema.TypeString,
    53  				Optional: true,
    54  				ForceNew: true,
    55  				Computed: true,
    56  			},
    57  		},
    58  	}
    59  }
    60  
    61  func resourceNetworkingRouterV2Create(d *schema.ResourceData, meta interface{}) error {
    62  	config := meta.(*Config)
    63  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
    64  	if err != nil {
    65  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
    66  	}
    67  
    68  	createOpts := routers.CreateOpts{
    69  		Name:     d.Get("name").(string),
    70  		TenantID: d.Get("tenant_id").(string),
    71  	}
    72  
    73  	if asuRaw, ok := d.GetOk("admin_state_up"); ok {
    74  		asu := asuRaw.(bool)
    75  		createOpts.AdminStateUp = &asu
    76  	}
    77  
    78  	if dRaw, ok := d.GetOk("distributed"); ok {
    79  		d := dRaw.(bool)
    80  		createOpts.Distributed = &d
    81  	}
    82  
    83  	externalGateway := d.Get("external_gateway").(string)
    84  	if externalGateway != "" {
    85  		gatewayInfo := routers.GatewayInfo{
    86  			NetworkID: externalGateway,
    87  		}
    88  		createOpts.GatewayInfo = &gatewayInfo
    89  	}
    90  
    91  	log.Printf("[DEBUG] Create Options: %#v", createOpts)
    92  	n, err := routers.Create(networkingClient, createOpts).Extract()
    93  	if err != nil {
    94  		return fmt.Errorf("Error creating OpenStack Neutron router: %s", err)
    95  	}
    96  	log.Printf("[INFO] Router ID: %s", n.ID)
    97  
    98  	log.Printf("[DEBUG] Waiting for OpenStack Neutron Router (%s) to become available", n.ID)
    99  	stateConf := &resource.StateChangeConf{
   100  		Pending:    []string{"BUILD", "PENDING_CREATE", "PENDING_UPDATE"},
   101  		Target:     []string{"ACTIVE"},
   102  		Refresh:    waitForRouterActive(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 resourceNetworkingRouterV2Read(d, meta)
   113  }
   114  
   115  func resourceNetworkingRouterV2Read(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 := routers.Get(networkingClient, d.Id()).Extract()
   123  	if err != nil {
   124  		httpError, ok := err.(*gophercloud.UnexpectedResponseCodeError)
   125  		if !ok {
   126  			return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err)
   127  		}
   128  
   129  		if httpError.Actual == 404 {
   130  			d.SetId("")
   131  			return nil
   132  		}
   133  		return fmt.Errorf("Error retrieving OpenStack Neutron Router: %s", err)
   134  	}
   135  
   136  	log.Printf("[DEBUG] Retreived Router %s: %+v", d.Id(), n)
   137  
   138  	d.Set("name", n.Name)
   139  	d.Set("admin_state_up", n.AdminStateUp)
   140  	d.Set("distributed", n.Distributed)
   141  	d.Set("tenant_id", n.TenantID)
   142  	d.Set("external_gateway", n.GatewayInfo.NetworkID)
   143  
   144  	return nil
   145  }
   146  
   147  func resourceNetworkingRouterV2Update(d *schema.ResourceData, meta interface{}) error {
   148  	config := meta.(*Config)
   149  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   150  	if err != nil {
   151  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   152  	}
   153  
   154  	var updateOpts routers.UpdateOpts
   155  	if d.HasChange("name") {
   156  		updateOpts.Name = d.Get("name").(string)
   157  	}
   158  	if d.HasChange("admin_state_up") {
   159  		asu := d.Get("admin_state_up").(bool)
   160  		updateOpts.AdminStateUp = &asu
   161  	}
   162  
   163  	log.Printf("[DEBUG] Updating Router %s with options: %+v", d.Id(), updateOpts)
   164  
   165  	_, err = routers.Update(networkingClient, d.Id(), updateOpts).Extract()
   166  	if err != nil {
   167  		return fmt.Errorf("Error updating OpenStack Neutron Router: %s", err)
   168  	}
   169  
   170  	return resourceNetworkingRouterV2Read(d, meta)
   171  }
   172  
   173  func resourceNetworkingRouterV2Delete(d *schema.ResourceData, meta interface{}) error {
   174  	config := meta.(*Config)
   175  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   176  	if err != nil {
   177  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   178  	}
   179  
   180  	stateConf := &resource.StateChangeConf{
   181  		Pending:    []string{"ACTIVE"},
   182  		Target:     []string{"DELETED"},
   183  		Refresh:    waitForRouterDelete(networkingClient, d.Id()),
   184  		Timeout:    2 * time.Minute,
   185  		Delay:      5 * time.Second,
   186  		MinTimeout: 3 * time.Second,
   187  	}
   188  
   189  	_, err = stateConf.WaitForState()
   190  	if err != nil {
   191  		return fmt.Errorf("Error deleting OpenStack Neutron Router: %s", err)
   192  	}
   193  
   194  	d.SetId("")
   195  	return nil
   196  }
   197  
   198  func waitForRouterActive(networkingClient *gophercloud.ServiceClient, routerId string) resource.StateRefreshFunc {
   199  	return func() (interface{}, string, error) {
   200  		r, err := routers.Get(networkingClient, routerId).Extract()
   201  		if err != nil {
   202  			return nil, r.Status, err
   203  		}
   204  
   205  		log.Printf("[DEBUG] OpenStack Neutron Router: %+v", r)
   206  		return r, r.Status, nil
   207  	}
   208  }
   209  
   210  func waitForRouterDelete(networkingClient *gophercloud.ServiceClient, routerId string) resource.StateRefreshFunc {
   211  	return func() (interface{}, string, error) {
   212  		log.Printf("[DEBUG] Attempting to delete OpenStack Router %s.\n", routerId)
   213  
   214  		r, err := routers.Get(networkingClient, routerId).Extract()
   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  		err = routers.Delete(networkingClient, routerId).ExtractErr()
   227  		if err != nil {
   228  			errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError)
   229  			if !ok {
   230  				return r, "ACTIVE", err
   231  			}
   232  			if errCode.Actual == 404 {
   233  				log.Printf("[DEBUG] Successfully deleted OpenStack Router %s", routerId)
   234  				return r, "DELETED", nil
   235  			}
   236  		}
   237  
   238  		log.Printf("[DEBUG] OpenStack Router %s still active.\n", routerId)
   239  		return r, "ACTIVE", nil
   240  	}
   241  }