github.com/sixgill/terraform@v0.9.0-beta2.0.20170316214032-033f6226ae50/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  			"public_ipv6": &schema.Schema{
    92  				Type:     schema.TypeString,
    93  				Computed: true,
    94  			},
    95  			"state": &schema.Schema{
    96  				Type:     schema.TypeString,
    97  				Optional: true,
    98  				Computed: true,
    99  			},
   100  			"state_detail": &schema.Schema{
   101  				Type:     schema.TypeString,
   102  				Computed: true,
   103  			},
   104  		},
   105  	}
   106  }
   107  
   108  func resourceScalewayServerCreate(d *schema.ResourceData, m interface{}) error {
   109  	scaleway := m.(*Client).scaleway
   110  
   111  	image := d.Get("image").(string)
   112  	var server = api.ScalewayServerDefinition{
   113  		Name:          d.Get("name").(string),
   114  		Image:         String(image),
   115  		Organization:  scaleway.Organization,
   116  		EnableIPV6:    d.Get("enable_ipv6").(bool),
   117  		SecurityGroup: d.Get("security_group").(string),
   118  	}
   119  
   120  	server.DynamicIPRequired = Bool(d.Get("dynamic_ip_required").(bool))
   121  	server.CommercialType = d.Get("type").(string)
   122  
   123  	if bootscript, ok := d.GetOk("bootscript"); ok {
   124  		server.Bootscript = String(bootscript.(string))
   125  	}
   126  
   127  	if vs, ok := d.GetOk("volume"); ok {
   128  		server.Volumes = make(map[string]string)
   129  
   130  		volumes := vs.([]interface{})
   131  		for i, v := range volumes {
   132  			volume := v.(map[string]interface{})
   133  
   134  			volumeID, err := scaleway.PostVolume(api.ScalewayVolumeDefinition{
   135  				Size: uint64(volume["size_in_gb"].(int)) * gb,
   136  				Type: volume["type"].(string),
   137  				Name: fmt.Sprintf("%s-%d", server.Name, volume["size_in_gb"].(int)),
   138  			})
   139  			if err != nil {
   140  				return err
   141  			}
   142  			volume["volume_id"] = volumeID
   143  			volumes[i] = volume
   144  			server.Volumes[fmt.Sprintf("%d", i+1)] = volumeID
   145  		}
   146  		d.Set("volume", volumes)
   147  	}
   148  
   149  	if raw, ok := d.GetOk("tags"); ok {
   150  		for _, tag := range raw.([]interface{}) {
   151  			server.Tags = append(server.Tags, tag.(string))
   152  		}
   153  	}
   154  
   155  	id, err := scaleway.PostServer(server)
   156  	if err != nil {
   157  		return err
   158  	}
   159  
   160  	d.SetId(id)
   161  	if d.Get("state").(string) != "stopped" {
   162  		err = scaleway.PostServerAction(id, "poweron")
   163  		if err != nil {
   164  			return err
   165  		}
   166  
   167  		err = waitForServerState(scaleway, id, "running")
   168  	}
   169  
   170  	if err != nil {
   171  		return err
   172  	}
   173  
   174  	return resourceScalewayServerRead(d, m)
   175  }
   176  
   177  func resourceScalewayServerRead(d *schema.ResourceData, m interface{}) error {
   178  	scaleway := m.(*Client).scaleway
   179  	server, err := scaleway.GetServer(d.Id())
   180  
   181  	if err != nil {
   182  		if serr, ok := err.(api.ScalewayAPIError); ok {
   183  			log.Printf("[DEBUG] Error reading server: %q\n", serr.APIMessage)
   184  
   185  			if serr.StatusCode == 404 {
   186  				d.SetId("")
   187  				return nil
   188  			}
   189  		}
   190  
   191  		return err
   192  	}
   193  
   194  	d.Set("name", server.Name)
   195  	d.Set("image", server.Image.Identifier)
   196  	d.Set("type", server.CommercialType)
   197  	d.Set("enable_ipv6", server.EnableIPV6)
   198  	d.Set("private_ip", server.PrivateIP)
   199  	d.Set("public_ip", server.PublicAddress.IP)
   200  
   201  	if server.EnableIPV6 {
   202  		d.Set("public_ipv6", server.IPV6.Address)
   203  	}
   204  
   205  	d.Set("state", server.State)
   206  	d.Set("state_detail", server.StateDetail)
   207  	d.Set("tags", server.Tags)
   208  
   209  	d.SetConnInfo(map[string]string{
   210  		"type": "ssh",
   211  		"host": server.PublicAddress.IP,
   212  	})
   213  
   214  	return nil
   215  }
   216  
   217  func resourceScalewayServerUpdate(d *schema.ResourceData, m interface{}) error {
   218  	scaleway := m.(*Client).scaleway
   219  
   220  	var req api.ScalewayServerPatchDefinition
   221  
   222  	if d.HasChange("name") {
   223  		name := d.Get("name").(string)
   224  		req.Name = &name
   225  	}
   226  
   227  	if d.HasChange("tags") {
   228  		if raw, ok := d.GetOk("tags"); ok {
   229  			var tags []string
   230  			for _, tag := range raw.([]interface{}) {
   231  				tags = append(tags, tag.(string))
   232  			}
   233  			req.Tags = &tags
   234  		}
   235  	}
   236  
   237  	if d.HasChange("enable_ipv6") {
   238  		req.EnableIPV6 = Bool(d.Get("enable_ipv6").(bool))
   239  	}
   240  
   241  	if d.HasChange("dynamic_ip_required") {
   242  		req.DynamicIPRequired = Bool(d.Get("dynamic_ip_required").(bool))
   243  	}
   244  
   245  	if d.HasChange("security_group") {
   246  		req.SecurityGroup = &api.ScalewaySecurityGroup{
   247  			Identifier: d.Get("security_group").(string),
   248  		}
   249  	}
   250  
   251  	if err := scaleway.PatchServer(d.Id(), req); err != nil {
   252  		return fmt.Errorf("Failed patching scaleway server: %q", err)
   253  	}
   254  
   255  	return resourceScalewayServerRead(d, m)
   256  }
   257  
   258  func resourceScalewayServerDelete(d *schema.ResourceData, m interface{}) error {
   259  	scaleway := m.(*Client).scaleway
   260  
   261  	s, err := scaleway.GetServer(d.Id())
   262  	if err != nil {
   263  		return err
   264  	}
   265  
   266  	if s.State == "stopped" {
   267  		return deleteStoppedServer(scaleway, s)
   268  	}
   269  
   270  	err = deleteRunningServer(scaleway, s)
   271  
   272  	if err == nil {
   273  		d.SetId("")
   274  	}
   275  
   276  	return err
   277  }