github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/rancher/resource_rancher_environment.go (about) 1 package rancher 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 "time" 8 9 "github.com/hashicorp/terraform/helper/resource" 10 "github.com/hashicorp/terraform/helper/schema" 11 "github.com/hashicorp/terraform/helper/validation" 12 rancherClient "github.com/rancher/go-rancher/client" 13 ) 14 15 func resourceRancherEnvironment() *schema.Resource { 16 return &schema.Resource{ 17 Create: resourceRancherEnvironmentCreate, 18 Read: resourceRancherEnvironmentRead, 19 Update: resourceRancherEnvironmentUpdate, 20 Delete: resourceRancherEnvironmentDelete, 21 Importer: &schema.ResourceImporter{ 22 State: schema.ImportStatePassthrough, 23 }, 24 25 Schema: map[string]*schema.Schema{ 26 "id": &schema.Schema{ 27 Type: schema.TypeString, 28 Computed: true, 29 }, 30 "name": &schema.Schema{ 31 Type: schema.TypeString, 32 Required: true, 33 }, 34 "orchestration": &schema.Schema{ 35 Type: schema.TypeString, 36 Default: "cattle", 37 Optional: true, 38 ValidateFunc: validation.StringInSlice([]string{"cattle", "kubernetes", "mesos", "swarm"}, true), 39 }, 40 "description": &schema.Schema{ 41 Type: schema.TypeString, 42 Optional: true, 43 }, 44 }, 45 } 46 } 47 48 func resourceRancherEnvironmentCreate(d *schema.ResourceData, meta interface{}) error { 49 log.Printf("[INFO] Creating Environment: %s", d.Id()) 50 client, err := meta.(*Config).GlobalClient() 51 if err != nil { 52 return err 53 } 54 55 name := d.Get("name").(string) 56 description := d.Get("description").(string) 57 orchestration := d.Get("orchestration").(string) 58 59 data := map[string]interface{}{ 60 "name": &name, 61 "description": &description, 62 } 63 64 setOrchestrationFields(orchestration, data) 65 66 var newEnv rancherClient.Project 67 if err := client.Create("project", data, &newEnv); err != nil { 68 return err 69 } 70 71 stateConf := &resource.StateChangeConf{ 72 Pending: []string{"active", "removed", "removing"}, 73 Target: []string{"active"}, 74 Refresh: EnvironmentStateRefreshFunc(client, newEnv.Id), 75 Timeout: 10 * time.Minute, 76 Delay: 1 * time.Second, 77 MinTimeout: 3 * time.Second, 78 } 79 _, waitErr := stateConf.WaitForState() 80 if waitErr != nil { 81 return fmt.Errorf( 82 "Error waiting for environment (%s) to be created: %s", newEnv.Id, waitErr) 83 } 84 85 d.SetId(newEnv.Id) 86 log.Printf("[INFO] Environment ID: %s", d.Id()) 87 88 return resourceRancherEnvironmentRead(d, meta) 89 } 90 91 func resourceRancherEnvironmentRead(d *schema.ResourceData, meta interface{}) error { 92 log.Printf("[INFO] Refreshing Environment: %s", d.Id()) 93 client, err := meta.(*Config).GlobalClient() 94 if err != nil { 95 return err 96 } 97 98 env, err := client.Project.ById(d.Id()) 99 if err != nil { 100 return err 101 } 102 103 if env == nil { 104 log.Printf("[INFO] Environment %s not found", d.Id()) 105 d.SetId("") 106 return nil 107 } 108 109 if removed(env.State) { 110 log.Printf("[INFO] Environment %s was removed on %v", d.Id(), env.Removed) 111 d.SetId("") 112 return nil 113 } 114 115 log.Printf("[INFO] Environment Name: %s", env.Name) 116 117 d.Set("description", env.Description) 118 d.Set("name", env.Name) 119 d.Set("orchestration", getActiveOrchestration(env)) 120 121 return nil 122 } 123 124 func resourceRancherEnvironmentUpdate(d *schema.ResourceData, meta interface{}) error { 125 client, err := meta.(*Config).GlobalClient() 126 if err != nil { 127 return err 128 } 129 130 name := d.Get("name").(string) 131 description := d.Get("description").(string) 132 orchestration := d.Get("orchestration").(string) 133 134 data := map[string]interface{}{ 135 "name": &name, 136 "description": &description, 137 } 138 139 setOrchestrationFields(orchestration, data) 140 141 var newEnv rancherClient.Project 142 env, err := client.Project.ById(d.Id()) 143 if err != nil { 144 return err 145 } 146 147 if err := client.Update("project", &env.Resource, data, &newEnv); err != nil { 148 return err 149 } 150 151 return resourceRancherEnvironmentRead(d, meta) 152 } 153 154 func resourceRancherEnvironmentDelete(d *schema.ResourceData, meta interface{}) error { 155 log.Printf("[INFO] Deleting Environment: %s", d.Id()) 156 id := d.Id() 157 client, err := meta.(*Config).GlobalClient() 158 if err != nil { 159 return err 160 } 161 162 env, err := client.Project.ById(id) 163 if err != nil { 164 return err 165 } 166 167 if err := client.Project.Delete(env); err != nil { 168 return fmt.Errorf("Error deleting Environment: %s", err) 169 } 170 171 log.Printf("[DEBUG] Waiting for environment (%s) to be removed", id) 172 173 stateConf := &resource.StateChangeConf{ 174 Pending: []string{"active", "removed", "removing"}, 175 Target: []string{"removed"}, 176 Refresh: EnvironmentStateRefreshFunc(client, id), 177 Timeout: 10 * time.Minute, 178 Delay: 1 * time.Second, 179 MinTimeout: 3 * time.Second, 180 } 181 182 _, waitErr := stateConf.WaitForState() 183 if waitErr != nil { 184 return fmt.Errorf( 185 "Error waiting for environment (%s) to be removed: %s", id, waitErr) 186 } 187 188 d.SetId("") 189 return nil 190 } 191 192 func setOrchestrationFields(orchestration string, data map[string]interface{}) { 193 orch := strings.ToLower(orchestration) 194 195 data["swarm"] = false 196 data["kubernetes"] = false 197 data["mesos"] = false 198 199 if orch == "k8s" { 200 orch = "kubernetes" 201 } 202 203 data[orch] = true 204 } 205 206 // EnvironmentStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch 207 // a Rancher Environment. 208 func EnvironmentStateRefreshFunc(client *rancherClient.RancherClient, environmentID string) resource.StateRefreshFunc { 209 return func() (interface{}, string, error) { 210 env, err := client.Project.ById(environmentID) 211 212 if err != nil { 213 return nil, "", err 214 } 215 216 return env, env.State, nil 217 } 218 }