github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/rancher/resource_rancher_host.go (about)

     1  package rancher
     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  	rancher "github.com/rancher/go-rancher/client"
    11  )
    12  
    13  // ro_labels are used internally by Rancher
    14  // They are not documented and should not be set in Terraform
    15  var ro_labels = []string{
    16  	"io.rancher.host.agent_image",
    17  	"io.rancher.host.docker_version",
    18  	"io.rancher.host.kvm",
    19  	"io.rancher.host.linux_kernel_version",
    20  }
    21  
    22  func resourceRancherHost() *schema.Resource {
    23  	return &schema.Resource{
    24  		Create: resourceRancherHostCreate,
    25  		Read:   resourceRancherHostRead,
    26  		Update: resourceRancherHostUpdate,
    27  		Delete: resourceRancherHostDelete,
    28  		Importer: &schema.ResourceImporter{
    29  			State: schema.ImportStatePassthrough,
    30  		},
    31  
    32  		Schema: map[string]*schema.Schema{
    33  			"id": &schema.Schema{
    34  				Type:     schema.TypeString,
    35  				Computed: true,
    36  			},
    37  			"name": &schema.Schema{
    38  				Type:     schema.TypeString,
    39  				Required: true,
    40  			},
    41  			"description": &schema.Schema{
    42  				Type:     schema.TypeString,
    43  				Optional: true,
    44  			},
    45  			"environment_id": &schema.Schema{
    46  				Type:     schema.TypeString,
    47  				Required: true,
    48  			},
    49  			"hostname": &schema.Schema{
    50  				Type:     schema.TypeString,
    51  				Required: true,
    52  			},
    53  			"labels": {
    54  				Type:     schema.TypeMap,
    55  				Optional: true,
    56  			},
    57  		},
    58  	}
    59  }
    60  
    61  func resourceRancherHostCreate(d *schema.ResourceData, meta interface{}) error {
    62  	log.Printf("[INFO][rancher] Creating Host: %s", d.Id())
    63  	client, err := meta.(*Config).EnvironmentClient(d.Get("environment_id").(string))
    64  	if err != nil {
    65  		return err
    66  	}
    67  
    68  	hosts, _ := client.Host.List(NewListOpts())
    69  	hostname := d.Get("hostname").(string)
    70  	var host rancher.Host
    71  
    72  	for _, h := range hosts.Data {
    73  		if h.Hostname == hostname {
    74  			host = h
    75  			break
    76  		}
    77  	}
    78  
    79  	if host.Hostname == "" {
    80  		return fmt.Errorf("Failed to find host %s", hostname)
    81  	}
    82  
    83  	d.SetId(host.Id)
    84  
    85  	return resourceRancherHostUpdate(d, meta)
    86  }
    87  
    88  func resourceRancherHostRead(d *schema.ResourceData, meta interface{}) error {
    89  	log.Printf("[INFO] Refreshing Host: %s", d.Id())
    90  	client, err := meta.(*Config).EnvironmentClient(d.Get("environment_id").(string))
    91  	if err != nil {
    92  		return err
    93  	}
    94  
    95  	host, err := client.Host.ById(d.Id())
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	log.Printf("[INFO] Host Name: %s", host.Name)
   101  
   102  	d.Set("description", host.Description)
   103  	d.Set("name", host.Name)
   104  	d.Set("hostname", host.Hostname)
   105  
   106  	labels := host.Labels
   107  	// Remove read-only labels
   108  	for _, lbl := range ro_labels {
   109  		delete(labels, lbl)
   110  	}
   111  	d.Set("labels", host.Labels)
   112  
   113  	return nil
   114  }
   115  
   116  func resourceRancherHostUpdate(d *schema.ResourceData, meta interface{}) error {
   117  	log.Printf("[INFO] Updating Host: %s", d.Id())
   118  	client, err := meta.(*Config).EnvironmentClient(d.Get("environment_id").(string))
   119  	if err != nil {
   120  		return err
   121  	}
   122  
   123  	name := d.Get("name").(string)
   124  	description := d.Get("description").(string)
   125  
   126  	// Process labels: merge ro_labels into new labels
   127  	labels := d.Get("labels").(map[string]interface{})
   128  	host, err := client.Host.ById(d.Id())
   129  	if err != nil {
   130  		return err
   131  	}
   132  	for _, lbl := range ro_labels {
   133  		labels[lbl] = host.Labels[lbl]
   134  	}
   135  
   136  	data := map[string]interface{}{
   137  		"name":        &name,
   138  		"description": &description,
   139  		"labels":      &labels,
   140  	}
   141  
   142  	var newHost rancher.Host
   143  	if err := client.Update("host", &host.Resource, data, &newHost); err != nil {
   144  		return err
   145  	}
   146  
   147  	return resourceRancherHostRead(d, meta)
   148  }
   149  
   150  func resourceRancherHostDelete(d *schema.ResourceData, meta interface{}) error {
   151  	log.Printf("[INFO] Deleting Host: %s", d.Id())
   152  	id := d.Id()
   153  	client, err := meta.(*Config).EnvironmentClient(d.Get("environment_id").(string))
   154  	if err != nil {
   155  		return err
   156  	}
   157  
   158  	host, err := client.Host.ById(id)
   159  	if err != nil {
   160  		return err
   161  	}
   162  
   163  	if err := client.Host.Delete(host); err != nil {
   164  		return fmt.Errorf("Error deleting Host: %s", err)
   165  	}
   166  
   167  	log.Printf("[DEBUG] Waiting for host (%s) to be removed", id)
   168  
   169  	stateConf := &resource.StateChangeConf{
   170  		Pending:    []string{"active", "removed", "removing"},
   171  		Target:     []string{"removed"},
   172  		Refresh:    HostStateRefreshFunc(client, id),
   173  		Timeout:    10 * time.Minute,
   174  		Delay:      1 * time.Second,
   175  		MinTimeout: 3 * time.Second,
   176  	}
   177  
   178  	_, waitErr := stateConf.WaitForState()
   179  	if waitErr != nil {
   180  		return fmt.Errorf(
   181  			"Error waiting for host (%s) to be removed: %s", id, waitErr)
   182  	}
   183  
   184  	d.SetId("")
   185  	return nil
   186  }
   187  
   188  // HostStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch
   189  // a Rancher Host.
   190  func HostStateRefreshFunc(client *rancher.RancherClient, hostID string) resource.StateRefreshFunc {
   191  	return func() (interface{}, string, error) {
   192  		host, err := client.Host.ById(hostID)
   193  
   194  		if err != nil {
   195  			return nil, "", err
   196  		}
   197  
   198  		return host, host.State, nil
   199  	}
   200  }