github.com/gabrielperezs/terraform@v0.7.0-rc2.0.20160715084931-f7da2612946f/builtin/providers/openstack/resource_openstack_networking_network_v2.go (about)

     1  package openstack
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strconv"
     7  	"time"
     8  
     9  	"github.com/hashicorp/terraform/helper/resource"
    10  	"github.com/hashicorp/terraform/helper/schema"
    11  
    12  	"github.com/rackspace/gophercloud"
    13  	"github.com/rackspace/gophercloud/openstack/networking/v2/networks"
    14  )
    15  
    16  func resourceNetworkingNetworkV2() *schema.Resource {
    17  	return &schema.Resource{
    18  		Create: resourceNetworkingNetworkV2Create,
    19  		Read:   resourceNetworkingNetworkV2Read,
    20  		Update: resourceNetworkingNetworkV2Update,
    21  		Delete: resourceNetworkingNetworkV2Delete,
    22  		Importer: &schema.ResourceImporter{
    23  			State: schema.ImportStatePassthrough,
    24  		},
    25  
    26  		Schema: map[string]*schema.Schema{
    27  			"region": &schema.Schema{
    28  				Type:        schema.TypeString,
    29  				Required:    true,
    30  				ForceNew:    true,
    31  				DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""),
    32  			},
    33  			"name": &schema.Schema{
    34  				Type:     schema.TypeString,
    35  				Optional: true,
    36  				ForceNew: false,
    37  			},
    38  			"admin_state_up": &schema.Schema{
    39  				Type:     schema.TypeString,
    40  				Optional: true,
    41  				ForceNew: false,
    42  				Computed: true,
    43  			},
    44  			"shared": &schema.Schema{
    45  				Type:     schema.TypeString,
    46  				Optional: true,
    47  				ForceNew: false,
    48  				Computed: true,
    49  			},
    50  			"tenant_id": &schema.Schema{
    51  				Type:     schema.TypeString,
    52  				Optional: true,
    53  				ForceNew: true,
    54  				Computed: true,
    55  			},
    56  		},
    57  	}
    58  }
    59  
    60  func resourceNetworkingNetworkV2Create(d *schema.ResourceData, meta interface{}) error {
    61  	config := meta.(*Config)
    62  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
    63  	if err != nil {
    64  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
    65  	}
    66  
    67  	createOpts := networks.CreateOpts{
    68  		Name:     d.Get("name").(string),
    69  		TenantID: d.Get("tenant_id").(string),
    70  	}
    71  
    72  	asuRaw := d.Get("admin_state_up").(string)
    73  	if asuRaw != "" {
    74  		asu, err := strconv.ParseBool(asuRaw)
    75  		if err != nil {
    76  			return fmt.Errorf("admin_state_up, if provided, must be either 'true' or 'false'")
    77  		}
    78  		createOpts.AdminStateUp = &asu
    79  	}
    80  
    81  	sharedRaw := d.Get("shared").(string)
    82  	if sharedRaw != "" {
    83  		shared, err := strconv.ParseBool(sharedRaw)
    84  		if err != nil {
    85  			return fmt.Errorf("shared, if provided, must be either 'true' or 'false': %v", err)
    86  		}
    87  		createOpts.Shared = &shared
    88  	}
    89  
    90  	log.Printf("[DEBUG] Create Options: %#v", createOpts)
    91  	n, err := networks.Create(networkingClient, createOpts).Extract()
    92  	if err != nil {
    93  		return fmt.Errorf("Error creating OpenStack Neutron network: %s", err)
    94  	}
    95  	log.Printf("[INFO] Network ID: %s", n.ID)
    96  
    97  	log.Printf("[DEBUG] Waiting for Network (%s) to become available", n.ID)
    98  
    99  	stateConf := &resource.StateChangeConf{
   100  		Pending:    []string{"BUILD"},
   101  		Target:     []string{"ACTIVE"},
   102  		Refresh:    waitForNetworkActive(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 resourceNetworkingNetworkV2Read(d, meta)
   113  }
   114  
   115  func resourceNetworkingNetworkV2Read(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 := networks.Get(networkingClient, d.Id()).Extract()
   123  	if err != nil {
   124  		return CheckDeleted(d, err, "network")
   125  	}
   126  
   127  	log.Printf("[DEBUG] Retreived Network %s: %+v", d.Id(), n)
   128  
   129  	d.Set("name", n.Name)
   130  	d.Set("admin_state_up", strconv.FormatBool(n.AdminStateUp))
   131  	d.Set("shared", strconv.FormatBool(n.Shared))
   132  	d.Set("tenant_id", n.TenantID)
   133  
   134  	return nil
   135  }
   136  
   137  func resourceNetworkingNetworkV2Update(d *schema.ResourceData, meta interface{}) error {
   138  	config := meta.(*Config)
   139  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   140  	if err != nil {
   141  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   142  	}
   143  
   144  	var updateOpts networks.UpdateOpts
   145  	if d.HasChange("name") {
   146  		updateOpts.Name = d.Get("name").(string)
   147  	}
   148  	if d.HasChange("admin_state_up") {
   149  		asuRaw := d.Get("admin_state_up").(string)
   150  		if asuRaw != "" {
   151  			asu, err := strconv.ParseBool(asuRaw)
   152  			if err != nil {
   153  				return fmt.Errorf("admin_state_up, if provided, must be either 'true' or 'false'")
   154  			}
   155  			updateOpts.AdminStateUp = &asu
   156  		}
   157  	}
   158  	if d.HasChange("shared") {
   159  		sharedRaw := d.Get("shared").(string)
   160  		if sharedRaw != "" {
   161  			shared, err := strconv.ParseBool(sharedRaw)
   162  			if err != nil {
   163  				return fmt.Errorf("shared, if provided, must be either 'true' or 'false': %v", err)
   164  			}
   165  			updateOpts.Shared = &shared
   166  		}
   167  	}
   168  
   169  	log.Printf("[DEBUG] Updating Network %s with options: %+v", d.Id(), updateOpts)
   170  
   171  	_, err = networks.Update(networkingClient, d.Id(), updateOpts).Extract()
   172  	if err != nil {
   173  		return fmt.Errorf("Error updating OpenStack Neutron Network: %s", err)
   174  	}
   175  
   176  	return resourceNetworkingNetworkV2Read(d, meta)
   177  }
   178  
   179  func resourceNetworkingNetworkV2Delete(d *schema.ResourceData, meta interface{}) error {
   180  	config := meta.(*Config)
   181  	networkingClient, err := config.networkingV2Client(d.Get("region").(string))
   182  	if err != nil {
   183  		return fmt.Errorf("Error creating OpenStack networking client: %s", err)
   184  	}
   185  
   186  	stateConf := &resource.StateChangeConf{
   187  		Pending:    []string{"ACTIVE"},
   188  		Target:     []string{"DELETED"},
   189  		Refresh:    waitForNetworkDelete(networkingClient, d.Id()),
   190  		Timeout:    2 * time.Minute,
   191  		Delay:      5 * time.Second,
   192  		MinTimeout: 3 * time.Second,
   193  	}
   194  
   195  	_, err = stateConf.WaitForState()
   196  	if err != nil {
   197  		return fmt.Errorf("Error deleting OpenStack Neutron Network: %s", err)
   198  	}
   199  
   200  	d.SetId("")
   201  	return nil
   202  }
   203  
   204  func waitForNetworkActive(networkingClient *gophercloud.ServiceClient, networkId string) resource.StateRefreshFunc {
   205  	return func() (interface{}, string, error) {
   206  		n, err := networks.Get(networkingClient, networkId).Extract()
   207  		if err != nil {
   208  			return nil, "", err
   209  		}
   210  
   211  		log.Printf("[DEBUG] OpenStack Neutron Network: %+v", n)
   212  		if n.Status == "DOWN" || n.Status == "ACTIVE" {
   213  			return n, "ACTIVE", nil
   214  		}
   215  
   216  		return n, n.Status, nil
   217  	}
   218  }
   219  
   220  func waitForNetworkDelete(networkingClient *gophercloud.ServiceClient, networkId string) resource.StateRefreshFunc {
   221  	return func() (interface{}, string, error) {
   222  		log.Printf("[DEBUG] Attempting to delete OpenStack Network %s.\n", networkId)
   223  
   224  		n, err := networks.Get(networkingClient, networkId).Extract()
   225  		if err != nil {
   226  			errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError)
   227  			if !ok {
   228  				return n, "ACTIVE", err
   229  			}
   230  			if errCode.Actual == 404 {
   231  				log.Printf("[DEBUG] Successfully deleted OpenStack Network %s", networkId)
   232  				return n, "DELETED", nil
   233  			}
   234  		}
   235  
   236  		err = networks.Delete(networkingClient, networkId).ExtractErr()
   237  		if err != nil {
   238  			errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError)
   239  			if !ok {
   240  				return n, "ACTIVE", err
   241  			}
   242  			if errCode.Actual == 404 {
   243  				log.Printf("[DEBUG] Successfully deleted OpenStack Network %s", networkId)
   244  				return n, "DELETED", nil
   245  			}
   246  		}
   247  
   248  		log.Printf("[DEBUG] OpenStack Network %s still active.\n", networkId)
   249  		return n, "ACTIVE", nil
   250  	}
   251  }