github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/ovh/resource_ovh_publiccloud_private_network.go (about)

     1  package ovh
     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/ovh/go-ovh/ovh"
    12  )
    13  
    14  func resourcePublicCloudPrivateNetwork() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourcePublicCloudPrivateNetworkCreate,
    17  		Read:   resourcePublicCloudPrivateNetworkRead,
    18  		Update: resourcePublicCloudPrivateNetworkUpdate,
    19  		Delete: resourcePublicCloudPrivateNetworkDelete,
    20  		Importer: &schema.ResourceImporter{
    21  			State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
    22  				return []*schema.ResourceData{d}, nil
    23  			},
    24  		},
    25  
    26  		Schema: map[string]*schema.Schema{
    27  			"project_id": &schema.Schema{
    28  				Type:        schema.TypeString,
    29  				Required:    true,
    30  				ForceNew:    true,
    31  				DefaultFunc: schema.EnvDefaultFunc("OVH_PROJECT_ID", nil),
    32  			},
    33  			"name": &schema.Schema{
    34  				Type:     schema.TypeString,
    35  				Required: true,
    36  				ForceNew: false,
    37  			},
    38  			"vlan_id": &schema.Schema{
    39  				Type:     schema.TypeInt,
    40  				Optional: true,
    41  				ForceNew: true,
    42  				Default:  0,
    43  			},
    44  			"regions": &schema.Schema{
    45  				Type:     schema.TypeSet,
    46  				Optional: true,
    47  				Computed: true,
    48  				ForceNew: true,
    49  				Elem:     &schema.Schema{Type: schema.TypeString},
    50  				Set:      schema.HashString,
    51  			},
    52  
    53  			"regions_status": &schema.Schema{
    54  				Type:     schema.TypeSet,
    55  				Computed: true,
    56  				Elem: &schema.Resource{
    57  					Schema: map[string]*schema.Schema{
    58  						"status": &schema.Schema{
    59  							Type:     schema.TypeString,
    60  							Required: true,
    61  						},
    62  
    63  						"region": &schema.Schema{
    64  							Type:     schema.TypeString,
    65  							Computed: true,
    66  						},
    67  					},
    68  				},
    69  			},
    70  			"status": &schema.Schema{
    71  				Type:     schema.TypeString,
    72  				Computed: true,
    73  			},
    74  			"type": &schema.Schema{
    75  				Type:     schema.TypeString,
    76  				Computed: true,
    77  			},
    78  		},
    79  	}
    80  }
    81  
    82  func resourcePublicCloudPrivateNetworkCreate(d *schema.ResourceData, meta interface{}) error {
    83  	config := meta.(*Config)
    84  
    85  	projectId := d.Get("project_id").(string)
    86  	params := &PublicCloudPrivateNetworkCreateOpts{
    87  		ProjectId: d.Get("project_id").(string),
    88  		VlanId:    d.Get("vlan_id").(int),
    89  		Name:      d.Get("name").(string),
    90  		Regions:   regionsOptsFromSchema(d),
    91  	}
    92  
    93  	r := &PublicCloudPrivateNetworkResponse{}
    94  
    95  	log.Printf("[DEBUG] Will create public cloud private network: %s", params)
    96  
    97  	endpoint := fmt.Sprintf("/cloud/project/%s/network/private", params.ProjectId)
    98  
    99  	err := config.OVHClient.Post(endpoint, params, r)
   100  	if err != nil {
   101  		return fmt.Errorf("calling %s with params %s:\n\t %q", endpoint, params, err)
   102  	}
   103  
   104  	log.Printf("[DEBUG] Waiting for Private Network %s:", r)
   105  
   106  	stateConf := &resource.StateChangeConf{
   107  		Pending:    []string{"BUILDING"},
   108  		Target:     []string{"ACTIVE"},
   109  		Refresh:    waitForPublicCloudPrivateNetworkActive(config.OVHClient, projectId, r.Id),
   110  		Timeout:    10 * time.Minute,
   111  		Delay:      10 * time.Second,
   112  		MinTimeout: 3 * time.Second,
   113  	}
   114  
   115  	_, err = stateConf.WaitForState()
   116  	if err != nil {
   117  		return fmt.Errorf("waiting for private network (%s): %s", params, err)
   118  	}
   119  	log.Printf("[DEBUG] Created Private Network %s", r)
   120  
   121  	//set id
   122  	d.SetId(r.Id)
   123  
   124  	return nil
   125  }
   126  
   127  func resourcePublicCloudPrivateNetworkRead(d *schema.ResourceData, meta interface{}) error {
   128  	config := meta.(*Config)
   129  
   130  	projectId := d.Get("project_id").(string)
   131  
   132  	r := &PublicCloudPrivateNetworkResponse{}
   133  
   134  	log.Printf("[DEBUG] Will read public cloud private network for project: %s, id: %s", projectId, d.Id())
   135  
   136  	endpoint := fmt.Sprintf("/cloud/project/%s/network/private/%s", projectId, d.Id())
   137  
   138  	d.Partial(true)
   139  	err := config.OVHClient.Get(endpoint, r)
   140  	if err != nil {
   141  		return fmt.Errorf("Error calling %s:\n\t %q", endpoint, err)
   142  	}
   143  
   144  	err = readPublicCloudPrivateNetwork(config, d, r)
   145  	if err != nil {
   146  		return err
   147  	}
   148  	d.Partial(false)
   149  
   150  	log.Printf("[DEBUG] Read Public Cloud Private Network %s", r)
   151  	return nil
   152  }
   153  
   154  func resourcePublicCloudPrivateNetworkUpdate(d *schema.ResourceData, meta interface{}) error {
   155  	config := meta.(*Config)
   156  
   157  	projectId := d.Get("project_id").(string)
   158  	params := &PublicCloudPrivateNetworkUpdateOpts{
   159  		Name: d.Get("name").(string),
   160  	}
   161  
   162  	log.Printf("[DEBUG] Will update public cloud private network: %s", params)
   163  
   164  	endpoint := fmt.Sprintf("/cloud/project/%s/network/private/%s", projectId, d.Id())
   165  
   166  	err := config.OVHClient.Put(endpoint, params, nil)
   167  	if err != nil {
   168  		return fmt.Errorf("calling %s with params %s:\n\t %q", endpoint, params, err)
   169  	}
   170  
   171  	log.Printf("[DEBUG] Updated Public cloud %s Private Network %s:", projectId, d.Id())
   172  
   173  	return resourcePublicCloudPrivateNetworkRead(d, meta)
   174  }
   175  
   176  func resourcePublicCloudPrivateNetworkDelete(d *schema.ResourceData, meta interface{}) error {
   177  	config := meta.(*Config)
   178  
   179  	projectId := d.Get("project_id").(string)
   180  	id := d.Id()
   181  
   182  	log.Printf("[DEBUG] Will delete public cloud private network for project: %s, id: %s", projectId, id)
   183  
   184  	endpoint := fmt.Sprintf("/cloud/project/%s/network/private/%s", projectId, id)
   185  
   186  	err := config.OVHClient.Delete(endpoint, nil)
   187  	if err != nil {
   188  		return fmt.Errorf("calling %s:\n\t %q", endpoint, err)
   189  	}
   190  
   191  	stateConf := &resource.StateChangeConf{
   192  		Pending:    []string{"DELETING"},
   193  		Target:     []string{"DELETED"},
   194  		Refresh:    waitForPublicCloudPrivateNetworkDelete(config.OVHClient, projectId, id),
   195  		Timeout:    10 * time.Minute,
   196  		Delay:      10 * time.Second,
   197  		MinTimeout: 3 * time.Second,
   198  	}
   199  
   200  	_, err = stateConf.WaitForState()
   201  	if err != nil {
   202  		return fmt.Errorf("deleting for private network (%s): %s", id, err)
   203  	}
   204  
   205  	d.SetId("")
   206  
   207  	log.Printf("[DEBUG] Deleted Public Cloud %s Private Network %s", projectId, id)
   208  	return nil
   209  }
   210  
   211  func regionsOptsFromSchema(d *schema.ResourceData) []string {
   212  	var regions []string
   213  	if v := d.Get("regions"); v != nil {
   214  		rs := v.(*schema.Set).List()
   215  		if len(rs) > 0 {
   216  			for _, v := range v.(*schema.Set).List() {
   217  				regions = append(regions, v.(string))
   218  			}
   219  		}
   220  	}
   221  	return regions
   222  }
   223  
   224  func readPublicCloudPrivateNetwork(config *Config, d *schema.ResourceData, r *PublicCloudPrivateNetworkResponse) error {
   225  	d.Set("name", r.Name)
   226  	d.Set("status", r.Status)
   227  	d.Set("type", r.Type)
   228  	d.Set("vlan_id", r.Vlanid)
   229  
   230  	regions_status := make([]map[string]interface{}, 0)
   231  	regions := make([]string, 0)
   232  
   233  	for i := range r.Regions {
   234  		region := make(map[string]interface{})
   235  		region["region"] = r.Regions[i].Region
   236  		region["status"] = r.Regions[i].Status
   237  		regions_status = append(regions_status, region)
   238  		regions = append(regions, fmt.Sprintf(r.Regions[i].Region))
   239  	}
   240  	d.Set("regions_status", regions_status)
   241  	d.Set("regions", regions)
   242  
   243  	d.SetId(r.Id)
   244  	return nil
   245  }
   246  
   247  func publicCloudPrivateNetworkExists(projectId, id string, c *ovh.Client) error {
   248  	r := &PublicCloudPrivateNetworkResponse{}
   249  
   250  	log.Printf("[DEBUG] Will read public cloud private network for project: %s, id: %s", projectId, id)
   251  
   252  	endpoint := fmt.Sprintf("/cloud/project/%s/network/private/%s", projectId, id)
   253  
   254  	err := c.Get(endpoint, r)
   255  	if err != nil {
   256  		return fmt.Errorf("calling %s:\n\t %q", endpoint, err)
   257  	}
   258  	log.Printf("[DEBUG] Read public cloud private network: %s", r)
   259  
   260  	return nil
   261  }
   262  
   263  // AttachmentStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch
   264  // an Attachment Task.
   265  func waitForPublicCloudPrivateNetworkActive(c *ovh.Client, projectId, PublicCloudPrivateNetworkId string) resource.StateRefreshFunc {
   266  	return func() (interface{}, string, error) {
   267  		r := &PublicCloudPrivateNetworkResponse{}
   268  		endpoint := fmt.Sprintf("/cloud/project/%s/network/private/%s", projectId, PublicCloudPrivateNetworkId)
   269  		err := c.Get(endpoint, r)
   270  		if err != nil {
   271  			return r, "", err
   272  		}
   273  
   274  		log.Printf("[DEBUG] Pending Private Network: %s", r)
   275  		return r, r.Status, nil
   276  	}
   277  }
   278  
   279  // AttachmentStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch
   280  // an Attachment Task.
   281  func waitForPublicCloudPrivateNetworkDelete(c *ovh.Client, projectId, PublicCloudPrivateNetworkId string) resource.StateRefreshFunc {
   282  	return func() (interface{}, string, error) {
   283  		r := &PublicCloudPrivateNetworkResponse{}
   284  		endpoint := fmt.Sprintf("/cloud/project/%s/network/private/%s", projectId, PublicCloudPrivateNetworkId)
   285  		err := c.Get(endpoint, r)
   286  		if err != nil {
   287  			if err.(*ovh.APIError).Code == 404 {
   288  				log.Printf("[DEBUG] private network id %s on project %s deleted", PublicCloudPrivateNetworkId, projectId)
   289  				return r, "DELETED", nil
   290  			} else {
   291  				return r, "", err
   292  			}
   293  		}
   294  		log.Printf("[DEBUG] Pending Private Network: %s", r)
   295  		return r, r.Status, nil
   296  	}
   297  }