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 }