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 }