terraform/builtin/providers/rancher/resource_rancher_environmen...

195 lines
4.8 KiB
Go

package rancher
import (
"fmt"
"log"
"strings"
"time"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
rancherClient "github.com/rancher/go-rancher/client"
)
func resourceRancherEnvironment() *schema.Resource {
return &schema.Resource{
Create: resourceRancherEnvironmentCreate,
Read: resourceRancherEnvironmentRead,
Update: resourceRancherEnvironmentUpdate,
Delete: resourceRancherEnvironmentDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"orchestration": &schema.Schema{
Type: schema.TypeString,
Default: "cattle",
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"cattle", "kubernetes", "mesos", "swarm"}, true),
},
"description": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
},
}
}
func resourceRancherEnvironmentCreate(d *schema.ResourceData, meta interface{}) error {
log.Printf("[INFO] Creating Environment: %s", d.Id())
client := meta.(*Config)
name := d.Get("name").(string)
description := d.Get("description").(string)
orchestration := d.Get("orchestration").(string)
data := map[string]interface{}{
"name": &name,
"description": &description,
}
setOrchestrationFields(orchestration, data)
var newEnv rancherClient.Project
if err := client.Create("project", data, &newEnv); err != nil {
return err
}
stateConf := &resource.StateChangeConf{
Pending: []string{"active", "removed", "removing"},
Target: []string{"active"},
Refresh: EnvironmentStateRefreshFunc(client, newEnv.Id),
Timeout: 10 * time.Minute,
Delay: 1 * time.Second,
MinTimeout: 3 * time.Second,
}
_, waitErr := stateConf.WaitForState()
if waitErr != nil {
return fmt.Errorf(
"Error waiting for environment (%s) to be created: %s", newEnv.Id, waitErr)
}
d.SetId(newEnv.Id)
log.Printf("[INFO] Environment ID: %s", d.Id())
return resourceRancherEnvironmentRead(d, meta)
}
func resourceRancherEnvironmentRead(d *schema.ResourceData, meta interface{}) error {
log.Printf("[INFO] Refreshing Environment: %s", d.Id())
client := meta.(*Config)
env, err := client.Project.ById(d.Id())
if err != nil {
return err
}
log.Printf("[INFO] Environment Name: %s", env.Name)
d.Set("description", env.Description)
d.Set("name", env.Name)
d.Set("orchestration", GetActiveOrchestration(env))
return nil
}
func resourceRancherEnvironmentUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Config)
name := d.Get("name").(string)
description := d.Get("description").(string)
orchestration := d.Get("orchestration").(string)
data := map[string]interface{}{
"name": &name,
"description": &description,
}
setOrchestrationFields(orchestration, data)
var newEnv rancherClient.Project
env, err := client.Project.ById(d.Id())
if err != nil {
return err
}
if err := client.Update("project", &env.Resource, data, &newEnv); err != nil {
return err
}
return resourceRancherEnvironmentRead(d, meta)
}
func resourceRancherEnvironmentDelete(d *schema.ResourceData, meta interface{}) error {
log.Printf("[INFO] Deleting Environment: %s", d.Id())
id := d.Id()
client := meta.(*Config)
env, err := client.Project.ById(id)
if err != nil {
return err
}
if err := client.Project.Delete(env); err != nil {
return fmt.Errorf("Error deleting Environment: %s", err)
}
log.Printf("[DEBUG] Waiting for environment (%s) to be removed", id)
stateConf := &resource.StateChangeConf{
Pending: []string{"active", "removed", "removing"},
Target: []string{"removed"},
Refresh: EnvironmentStateRefreshFunc(client, id),
Timeout: 10 * time.Minute,
Delay: 1 * time.Second,
MinTimeout: 3 * time.Second,
}
_, waitErr := stateConf.WaitForState()
if waitErr != nil {
return fmt.Errorf(
"Error waiting for environment (%s) to be removed: %s", id, waitErr)
}
d.SetId("")
return nil
}
func setOrchestrationFields(orchestration string, data map[string]interface{}) {
orch := strings.ToLower(orchestration)
data["swarm"] = false
data["kubernetes"] = false
data["mesos"] = false
if orch == "k8s" {
orch = "kubernetes"
}
data[orch] = true
}
// EnvironmentStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch
// a Rancher Environment.
func EnvironmentStateRefreshFunc(client *Config, environmentID string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
env, err := client.Project.ById(environmentID)
if err != nil {
return nil, "", err
}
return env, env.State, nil
}
}