github.com/bradfeehan/terraform@v0.7.0-rc3.0.20170529055808-34b45c5ad841/builtin/providers/ovh/resource_ovh_vrack_publiccloud_attachment.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  	"github.com/ovh/go-ovh/ovh"
    11  )
    12  
    13  func resourceVRackPublicCloudAttachment() *schema.Resource {
    14  	return &schema.Resource{
    15  		Create: resourceVRackPublicCloudAttachmentCreate,
    16  		Read:   resourceVRackPublicCloudAttachmentRead,
    17  		Delete: resourceVRackPublicCloudAttachmentDelete,
    18  
    19  		Schema: map[string]*schema.Schema{
    20  			"vrack_id": &schema.Schema{
    21  				Type:        schema.TypeString,
    22  				Required:    true,
    23  				ForceNew:    true,
    24  				DefaultFunc: schema.EnvDefaultFunc("OVH_VRACK_ID", ""),
    25  			},
    26  			"project_id": &schema.Schema{
    27  				Type:        schema.TypeString,
    28  				Required:    true,
    29  				ForceNew:    true,
    30  				DefaultFunc: schema.EnvDefaultFunc("OVH_PROJECT_ID", ""),
    31  			},
    32  		},
    33  	}
    34  }
    35  
    36  func resourceVRackPublicCloudAttachmentCreate(d *schema.ResourceData, meta interface{}) error {
    37  	config := meta.(*Config)
    38  
    39  	vrackId := d.Get("vrack_id").(string)
    40  	projectId := d.Get("project_id").(string)
    41  
    42  	if err := vrackPublicCloudAttachmentExists(vrackId, projectId, config.OVHClient); err == nil {
    43  		//set id
    44  		d.SetId(fmt.Sprintf("vrack_%s-cloudproject_%s-attach", vrackId, projectId))
    45  		return nil
    46  	}
    47  
    48  	params := &VRackAttachOpts{Project: projectId}
    49  	r := VRackAttachTaskResponse{}
    50  
    51  	log.Printf("[DEBUG] Will Attach VRack %s -> PublicCloud %s", vrackId, params.Project)
    52  	endpoint := fmt.Sprintf("/vrack/%s/cloudProject", vrackId)
    53  
    54  	err := config.OVHClient.Post(endpoint, params, &r)
    55  	if err != nil {
    56  		return fmt.Errorf("Error calling %s with params %s:\n\t %q", endpoint, params, err)
    57  	}
    58  
    59  	log.Printf("[DEBUG] Waiting for Attachement Task id %d: VRack %s ->  PublicCloud %s", r.Id, vrackId, params.Project)
    60  
    61  	stateConf := &resource.StateChangeConf{
    62  		Pending:    []string{"init", "todo", "doing"},
    63  		Target:     []string{"completed"},
    64  		Refresh:    waitForVRackTaskCompleted(config.OVHClient, vrackId, r.Id),
    65  		Timeout:    10 * time.Minute,
    66  		Delay:      10 * time.Second,
    67  		MinTimeout: 3 * time.Second,
    68  	}
    69  
    70  	_, err = stateConf.WaitForState()
    71  	if err != nil {
    72  		return fmt.Errorf("Error waiting for vrack (%s) to attach to public cloud (%s): %s", vrackId, params.Project, err)
    73  	}
    74  	log.Printf("[DEBUG] Created Attachement Task id %d: VRack %s ->  PublicCloud %s", r.Id, vrackId, params.Project)
    75  
    76  	//set id
    77  	d.SetId(fmt.Sprintf("vrack_%s-cloudproject_%s-attach", vrackId, params.Project))
    78  
    79  	return nil
    80  }
    81  
    82  func resourceVRackPublicCloudAttachmentRead(d *schema.ResourceData, meta interface{}) error {
    83  	config := meta.(*Config)
    84  
    85  	vrackId := d.Get("vrack_id").(string)
    86  	params := &VRackAttachOpts{Project: d.Get("project_id").(string)}
    87  	r := VRackAttachTaskResponse{}
    88  	endpoint := fmt.Sprintf("/vrack/%s/cloudProject/%s", vrackId, params.Project)
    89  
    90  	err := config.OVHClient.Get(endpoint, &r)
    91  	if err != nil {
    92  		return err
    93  	}
    94  	log.Printf("[DEBUG] Read VRack %s ->  PublicCloud %s", vrackId, params.Project)
    95  
    96  	return nil
    97  }
    98  
    99  func resourceVRackPublicCloudAttachmentDelete(d *schema.ResourceData, meta interface{}) error {
   100  	config := meta.(*Config)
   101  
   102  	vrackId := d.Get("vrack_id").(string)
   103  	params := &VRackAttachOpts{Project: d.Get("project_id").(string)}
   104  
   105  	r := VRackAttachTaskResponse{}
   106  	endpoint := fmt.Sprintf("/vrack/%s/cloudProject/%s", vrackId, params.Project)
   107  
   108  	err := config.OVHClient.Delete(endpoint, &r)
   109  	if err != nil {
   110  		return err
   111  	}
   112  
   113  	log.Printf("[DEBUG] Waiting for Attachment Deletion Task id %d: VRack %s ->  PublicCloud %s", r.Id, vrackId, params.Project)
   114  
   115  	stateConf := &resource.StateChangeConf{
   116  		Pending:    []string{"init", "todo", "doing"},
   117  		Target:     []string{"completed"},
   118  		Refresh:    waitForVRackTaskCompleted(config.OVHClient, vrackId, r.Id),
   119  		Timeout:    10 * time.Minute,
   120  		Delay:      10 * time.Second,
   121  		MinTimeout: 3 * time.Second,
   122  	}
   123  
   124  	_, err = stateConf.WaitForState()
   125  	if err != nil {
   126  		return fmt.Errorf("Error waiting for vrack (%s) to attach to public cloud (%s): %s", vrackId, params.Project, err)
   127  	}
   128  	log.Printf("[DEBUG] Removed Attachement id %d: VRack %s ->  PublicCloud %s", r.Id, vrackId, params.Project)
   129  
   130  	d.SetId("")
   131  	return nil
   132  }
   133  
   134  func vrackPublicCloudAttachmentExists(vrackId, projectId string, c *ovh.Client) error {
   135  	type attachResponse struct {
   136  		VRack   string `json:"vrack"`
   137  		Project string `json:"project"`
   138  	}
   139  
   140  	r := attachResponse{}
   141  
   142  	endpoint := fmt.Sprintf("/vrack/%s/cloudProject/%s", vrackId, projectId)
   143  
   144  	err := c.Get(endpoint, &r)
   145  	if err != nil {
   146  		return fmt.Errorf("Error while querying %s: %q\n", endpoint, err)
   147  	}
   148  	log.Printf("[DEBUG] Read Attachment %s -> VRack:%s, Cloud Project: %s", endpoint, r.VRack, r.Project)
   149  
   150  	return nil
   151  }
   152  
   153  // AttachmentStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch
   154  // an Attachment Task.
   155  func waitForVRackTaskCompleted(c *ovh.Client, serviceName string, taskId int) resource.StateRefreshFunc {
   156  	return func() (interface{}, string, error) {
   157  		r := VRackAttachTaskResponse{}
   158  		endpoint := fmt.Sprintf("/vrack/%s/task/%d", serviceName, taskId)
   159  		err := c.Get(endpoint, &r)
   160  		if err != nil {
   161  			if err.(*ovh.APIError).Code == 404 {
   162  				log.Printf("[DEBUG] Task id %d on VRack %s completed", taskId, serviceName)
   163  				return taskId, "completed", nil
   164  			} else {
   165  				return taskId, "", err
   166  			}
   167  		}
   168  
   169  		log.Printf("[DEBUG] Pending Task id %d on VRack %s status: %s", r.Id, serviceName, r.Status)
   170  		return taskId, r.Status, nil
   171  	}
   172  }