github.com/richardbowden/terraform@v0.6.12-0.20160901200758-30ea22c25211/builtin/providers/scaleway/resource_scaleway_volume_attachment.go (about)

     1  package scaleway
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  
     7  	"github.com/hashicorp/terraform/helper/schema"
     8  	"github.com/scaleway/scaleway-cli/pkg/api"
     9  )
    10  
    11  func resourceScalewayVolumeAttachment() *schema.Resource {
    12  	return &schema.Resource{
    13  		Create: resourceScalewayVolumeAttachmentCreate,
    14  		Read:   resourceScalewayVolumeAttachmentRead,
    15  		Delete: resourceScalewayVolumeAttachmentDelete,
    16  		Schema: map[string]*schema.Schema{
    17  			"server": &schema.Schema{
    18  				Type:     schema.TypeString,
    19  				Required: true,
    20  				ForceNew: true,
    21  			},
    22  			"volume": &schema.Schema{
    23  				Type:     schema.TypeString,
    24  				Required: true,
    25  				ForceNew: true,
    26  			},
    27  		},
    28  	}
    29  }
    30  
    31  func resourceScalewayVolumeAttachmentCreate(d *schema.ResourceData, m interface{}) error {
    32  	scaleway := m.(*Client).scaleway
    33  
    34  	var startServerAgain = false
    35  	server, err := scaleway.GetServer(d.Get("server").(string))
    36  	if err != nil {
    37  		fmt.Printf("Failed getting server: %q", err)
    38  		return err
    39  	}
    40  
    41  	// volumes can only be modified when the server is powered off
    42  	if server.State != "stopped" {
    43  		startServerAgain = true
    44  
    45  		if err := scaleway.PostServerAction(server.Identifier, "poweroff"); err != nil {
    46  			return err
    47  		}
    48  
    49  		if err := waitForServerState(scaleway, server.Identifier, "stopped"); err != nil {
    50  			return err
    51  		}
    52  	}
    53  
    54  	volumes := make(map[string]api.ScalewayVolume)
    55  	for i, volume := range server.Volumes {
    56  		volumes[i] = volume
    57  	}
    58  
    59  	vol, err := scaleway.GetVolume(d.Get("volume").(string))
    60  	if err != nil {
    61  		return err
    62  	}
    63  	volumes[fmt.Sprintf("%d", len(volumes)+1)] = *vol
    64  
    65  	// the API request requires most volume attributes to be unset to succeed
    66  	for k, v := range volumes {
    67  		v.Size = 0
    68  		v.CreationDate = ""
    69  		v.Organization = ""
    70  		v.ModificationDate = ""
    71  		v.VolumeType = ""
    72  		v.Server = nil
    73  		v.ExportURI = ""
    74  
    75  		volumes[k] = v
    76  	}
    77  
    78  	var req = api.ScalewayServerPatchDefinition{
    79  		Volumes: &volumes,
    80  	}
    81  	if err := scaleway.PatchServer(d.Get("server").(string), req); err != nil {
    82  		return fmt.Errorf("Failed attaching volume to server: %q", err)
    83  	}
    84  
    85  	if startServerAgain {
    86  		if err := scaleway.PostServerAction(d.Get("server").(string), "poweron"); err != nil {
    87  			return err
    88  		}
    89  
    90  		if err := waitForServerState(scaleway, d.Get("server").(string), "running"); err != nil {
    91  			return err
    92  		}
    93  	}
    94  
    95  	d.SetId(fmt.Sprintf("scaleway-server:%s/volume/%s", d.Get("server").(string), d.Get("volume").(string)))
    96  
    97  	return resourceScalewayVolumeAttachmentRead(d, m)
    98  }
    99  
   100  func resourceScalewayVolumeAttachmentRead(d *schema.ResourceData, m interface{}) error {
   101  	scaleway := m.(*Client).scaleway
   102  
   103  	server, err := scaleway.GetServer(d.Get("server").(string))
   104  	if err != nil {
   105  		if serr, ok := err.(api.ScalewayAPIError); ok {
   106  			log.Printf("[DEBUG] Error reading server: %q\n", serr.APIMessage)
   107  
   108  			if serr.StatusCode == 404 {
   109  				d.SetId("")
   110  				return nil
   111  			}
   112  		}
   113  		return err
   114  	}
   115  
   116  	if _, err := scaleway.GetVolume(d.Get("volume").(string)); err != nil {
   117  		if serr, ok := err.(api.ScalewayAPIError); ok {
   118  			log.Printf("[DEBUG] Error reading volume: %q\n", serr.APIMessage)
   119  
   120  			if serr.StatusCode == 404 {
   121  				d.SetId("")
   122  				return nil
   123  			}
   124  		}
   125  		return err
   126  	}
   127  
   128  	for _, volume := range server.Volumes {
   129  		if volume.Identifier == d.Get("volume").(string) {
   130  			return nil
   131  		}
   132  	}
   133  
   134  	log.Printf("[DEBUG] Volume %q not attached to server %q\n", d.Get("volume").(string), d.Get("server").(string))
   135  	d.SetId("")
   136  	return nil
   137  }
   138  
   139  func resourceScalewayVolumeAttachmentDelete(d *schema.ResourceData, m interface{}) error {
   140  	scaleway := m.(*Client).scaleway
   141  	var startServerAgain = false
   142  
   143  	server, err := scaleway.GetServer(d.Get("server").(string))
   144  	if err != nil {
   145  		return err
   146  	}
   147  
   148  	// volumes can only be modified when the server is powered off
   149  	if server.State != "stopped" {
   150  		startServerAgain = true
   151  
   152  		if err := scaleway.PostServerAction(server.Identifier, "poweroff"); err != nil {
   153  			return err
   154  		}
   155  
   156  		if err := waitForServerState(scaleway, server.Identifier, "stopped"); err != nil {
   157  			return err
   158  		}
   159  	}
   160  
   161  	volumes := make(map[string]api.ScalewayVolume)
   162  	for _, volume := range server.Volumes {
   163  		if volume.Identifier != d.Get("volume").(string) {
   164  			volumes[fmt.Sprintf("%d", len(volumes))] = volume
   165  		}
   166  	}
   167  
   168  	// the API request requires most volume attributes to be unset to succeed
   169  	for k, v := range volumes {
   170  		v.Size = 0
   171  		v.CreationDate = ""
   172  		v.Organization = ""
   173  		v.ModificationDate = ""
   174  		v.VolumeType = ""
   175  		v.Server = nil
   176  		v.ExportURI = ""
   177  
   178  		volumes[k] = v
   179  	}
   180  
   181  	var req = api.ScalewayServerPatchDefinition{
   182  		Volumes: &volumes,
   183  	}
   184  	if err := scaleway.PatchServer(d.Get("server").(string), req); err != nil {
   185  		return err
   186  	}
   187  
   188  	if startServerAgain {
   189  		if err := scaleway.PostServerAction(d.Get("server").(string), "poweron"); err != nil {
   190  			return err
   191  		}
   192  
   193  		if err := waitForServerState(scaleway, d.Get("server").(string), "running"); err != nil {
   194  			return err
   195  		}
   196  	}
   197  
   198  	d.SetId("")
   199  
   200  	return nil
   201  }