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