github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/scaleway/resource_scaleway_server.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 resourceScalewayServer() *schema.Resource {
    12  	return &schema.Resource{
    13  		Create: resourceScalewayServerCreate,
    14  		Read:   resourceScalewayServerRead,
    15  		Update: resourceScalewayServerUpdate,
    16  		Delete: resourceScalewayServerDelete,
    17  		Importer: &schema.ResourceImporter{
    18  			State: schema.ImportStatePassthrough,
    19  		},
    20  
    21  		Schema: map[string]*schema.Schema{
    22  			"name": &schema.Schema{
    23  				Type:     schema.TypeString,
    24  				Required: true,
    25  			},
    26  			"image": &schema.Schema{
    27  				Type:     schema.TypeString,
    28  				Required: true,
    29  				ForceNew: true,
    30  			},
    31  			"type": &schema.Schema{
    32  				Type:     schema.TypeString,
    33  				Required: true,
    34  				ForceNew: true,
    35  			},
    36  			"bootscript": &schema.Schema{
    37  				Type:     schema.TypeString,
    38  				Optional: true,
    39  			},
    40  			"tags": &schema.Schema{
    41  				Type: schema.TypeList,
    42  				Elem: &schema.Schema{
    43  					Type: schema.TypeString,
    44  				},
    45  				Optional: true,
    46  			},
    47  			"enable_ipv6": &schema.Schema{
    48  				Type:     schema.TypeBool,
    49  				Optional: true,
    50  				Default:  false,
    51  			},
    52  			"dynamic_ip_required": &schema.Schema{
    53  				Type:     schema.TypeBool,
    54  				Optional: true,
    55  			},
    56  			"security_group": &schema.Schema{
    57  				Type:     schema.TypeString,
    58  				Optional: true,
    59  			},
    60  			"volume": &schema.Schema{
    61  				Type:     schema.TypeList,
    62  				Optional: true,
    63  				ForceNew: true,
    64  				Elem: &schema.Resource{
    65  					Schema: map[string]*schema.Schema{
    66  						"size_in_gb": {
    67  							Type:         schema.TypeInt,
    68  							Required:     true,
    69  							ValidateFunc: validateVolumeSize,
    70  						},
    71  						"type": &schema.Schema{
    72  							Type:         schema.TypeString,
    73  							Required:     true,
    74  							ValidateFunc: validateVolumeType,
    75  						},
    76  						"volume_id": &schema.Schema{
    77  							Type:     schema.TypeString,
    78  							Computed: true,
    79  						},
    80  					},
    81  				},
    82  			},
    83  			"private_ip": &schema.Schema{
    84  				Type:     schema.TypeString,
    85  				Computed: true,
    86  			},
    87  			"public_ip": &schema.Schema{
    88  				Type:     schema.TypeString,
    89  				Computed: true,
    90  			},
    91  			"state": &schema.Schema{
    92  				Type:     schema.TypeString,
    93  				Optional: true,
    94  				Computed: true,
    95  			},
    96  			"state_detail": &schema.Schema{
    97  				Type:     schema.TypeString,
    98  				Computed: true,
    99  			},
   100  		},
   101  	}
   102  }
   103  
   104  func resourceScalewayServerCreate(d *schema.ResourceData, m interface{}) error {
   105  	scaleway := m.(*Client).scaleway
   106  
   107  	image := d.Get("image").(string)
   108  	var server = api.ScalewayServerDefinition{
   109  		Name:          d.Get("name").(string),
   110  		Image:         String(image),
   111  		Organization:  scaleway.Organization,
   112  		EnableIPV6:    d.Get("enable_ipv6").(bool),
   113  		SecurityGroup: d.Get("security_group").(string),
   114  	}
   115  
   116  	server.DynamicIPRequired = Bool(d.Get("dynamic_ip_required").(bool))
   117  	server.CommercialType = d.Get("type").(string)
   118  
   119  	if bootscript, ok := d.GetOk("bootscript"); ok {
   120  		server.Bootscript = String(bootscript.(string))
   121  	}
   122  
   123  	if vs, ok := d.GetOk("volume"); ok {
   124  		server.Volumes = make(map[string]string)
   125  
   126  		volumes := vs.([]interface{})
   127  		for i, v := range volumes {
   128  			volume := v.(map[string]interface{})
   129  
   130  			volumeID, err := scaleway.PostVolume(api.ScalewayVolumeDefinition{
   131  				Size: uint64(volume["size_in_gb"].(int)) * gb,
   132  				Type: volume["type"].(string),
   133  				Name: fmt.Sprintf("%s-%d", server.Name, volume["size_in_gb"].(int)),
   134  			})
   135  			if err != nil {
   136  				return err
   137  			}
   138  			volume["volume_id"] = volumeID
   139  			volumes[i] = volume
   140  			server.Volumes[fmt.Sprintf("%d", i+1)] = volumeID
   141  		}
   142  		d.Set("volume", volumes)
   143  	}
   144  
   145  	if raw, ok := d.GetOk("tags"); ok {
   146  		for _, tag := range raw.([]interface{}) {
   147  			server.Tags = append(server.Tags, tag.(string))
   148  		}
   149  	}
   150  
   151  	id, err := scaleway.PostServer(server)
   152  	if err != nil {
   153  		return err
   154  	}
   155  
   156  	d.SetId(id)
   157  	if d.Get("state").(string) != "stopped" {
   158  		err = scaleway.PostServerAction(id, "poweron")
   159  		if err != nil {
   160  			return err
   161  		}
   162  
   163  		err = waitForServerState(scaleway, id, "running")
   164  	}
   165  
   166  	if err != nil {
   167  		return err
   168  	}
   169  
   170  	return resourceScalewayServerRead(d, m)
   171  }
   172  
   173  func resourceScalewayServerRead(d *schema.ResourceData, m interface{}) error {
   174  	scaleway := m.(*Client).scaleway
   175  	server, err := scaleway.GetServer(d.Id())
   176  
   177  	if err != nil {
   178  		if serr, ok := err.(api.ScalewayAPIError); ok {
   179  			log.Printf("[DEBUG] Error reading server: %q\n", serr.APIMessage)
   180  
   181  			if serr.StatusCode == 404 {
   182  				d.SetId("")
   183  				return nil
   184  			}
   185  		}
   186  
   187  		return err
   188  	}
   189  
   190  	d.Set("name", server.Name)
   191  	d.Set("image", server.Image.Identifier)
   192  	d.Set("type", server.CommercialType)
   193  	d.Set("enable_ipv6", server.EnableIPV6)
   194  	d.Set("private_ip", server.PrivateIP)
   195  	d.Set("public_ip", server.PublicAddress.IP)
   196  
   197  	d.Set("state", server.State)
   198  	d.Set("state_detail", server.StateDetail)
   199  	d.Set("tags", server.Tags)
   200  
   201  	d.SetConnInfo(map[string]string{
   202  		"type": "ssh",
   203  		"host": server.PublicAddress.IP,
   204  	})
   205  
   206  	return nil
   207  }
   208  
   209  func resourceScalewayServerUpdate(d *schema.ResourceData, m interface{}) error {
   210  	scaleway := m.(*Client).scaleway
   211  
   212  	var req api.ScalewayServerPatchDefinition
   213  
   214  	if d.HasChange("name") {
   215  		name := d.Get("name").(string)
   216  		req.Name = &name
   217  	}
   218  
   219  	if d.HasChange("tags") {
   220  		if raw, ok := d.GetOk("tags"); ok {
   221  			var tags []string
   222  			for _, tag := range raw.([]interface{}) {
   223  				tags = append(tags, tag.(string))
   224  			}
   225  			req.Tags = &tags
   226  		}
   227  	}
   228  
   229  	if d.HasChange("enable_ipv6") {
   230  		req.EnableIPV6 = Bool(d.Get("enable_ipv6").(bool))
   231  	}
   232  
   233  	if d.HasChange("dynamic_ip_required") {
   234  		req.DynamicIPRequired = Bool(d.Get("dynamic_ip_required").(bool))
   235  	}
   236  
   237  	if d.HasChange("security_group") {
   238  		req.SecurityGroup = &api.ScalewaySecurityGroup{
   239  			Identifier: d.Get("security_group").(string),
   240  		}
   241  	}
   242  
   243  	if err := scaleway.PatchServer(d.Id(), req); err != nil {
   244  		return fmt.Errorf("Failed patching scaleway server: %q", err)
   245  	}
   246  
   247  	return resourceScalewayServerRead(d, m)
   248  }
   249  
   250  func resourceScalewayServerDelete(d *schema.ResourceData, m interface{}) error {
   251  	scaleway := m.(*Client).scaleway
   252  
   253  	s, err := scaleway.GetServer(d.Id())
   254  	if err != nil {
   255  		return err
   256  	}
   257  
   258  	if s.State == "stopped" {
   259  		return deleteStoppedServer(scaleway, s)
   260  	}
   261  
   262  	err = deleteRunningServer(scaleway, s)
   263  
   264  	if err == nil {
   265  		d.SetId("")
   266  	}
   267  
   268  	return err
   269  }