github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/arukas/resource_arukas_container.go (about) 1 package arukas 2 3 import ( 4 "fmt" 5 "strings" 6 7 API "github.com/arukasio/cli" 8 "github.com/hashicorp/terraform/helper/resource" 9 "github.com/hashicorp/terraform/helper/schema" 10 ) 11 12 func resourceArukasContainer() *schema.Resource { 13 return &schema.Resource{ 14 Create: resourceArukasContainerCreate, 15 Read: resourceArukasContainerRead, 16 Update: resourceArukasContainerUpdate, 17 Delete: resourceArukasContainerDelete, 18 Importer: &schema.ResourceImporter{ 19 State: schema.ImportStatePassthrough, 20 }, 21 Schema: map[string]*schema.Schema{ 22 "name": &schema.Schema{ 23 Type: schema.TypeString, 24 Required: true, 25 ForceNew: true, 26 }, 27 "image": &schema.Schema{ 28 Type: schema.TypeString, 29 Required: true, 30 }, 31 "instances": &schema.Schema{ 32 Type: schema.TypeInt, 33 Optional: true, 34 Default: 1, 35 ValidateFunc: validateIntegerInRange(1, 10), 36 }, 37 "memory": &schema.Schema{ 38 Type: schema.TypeInt, 39 Optional: true, 40 Default: 256, 41 ValidateFunc: validateIntInWord([]string{"256", "512"}), 42 }, 43 "endpoint": &schema.Schema{ 44 Type: schema.TypeString, 45 Optional: true, 46 Computed: true, 47 }, 48 "ports": &schema.Schema{ 49 Type: schema.TypeList, 50 Required: true, 51 MaxItems: 20, 52 Elem: &schema.Resource{ 53 Schema: map[string]*schema.Schema{ 54 "protocol": &schema.Schema{ 55 Type: schema.TypeString, 56 Optional: true, 57 Default: "tcp", 58 ValidateFunc: validateStringInWord([]string{"tcp", "udp"}), 59 }, 60 "number": &schema.Schema{ 61 Type: schema.TypeInt, 62 Optional: true, 63 Default: "80", 64 ValidateFunc: validateIntegerInRange(1, 65535), 65 }, 66 }, 67 }, 68 }, 69 "environments": &schema.Schema{ 70 Type: schema.TypeList, 71 Optional: true, 72 MaxItems: 20, 73 Elem: &schema.Resource{ 74 Schema: map[string]*schema.Schema{ 75 "key": &schema.Schema{ 76 Type: schema.TypeString, 77 Required: true, 78 }, 79 "value": &schema.Schema{ 80 Type: schema.TypeString, 81 Required: true, 82 }, 83 }, 84 }, 85 }, 86 "cmd": &schema.Schema{ 87 Type: schema.TypeString, 88 Optional: true, 89 }, 90 "port_mappings": &schema.Schema{ 91 Type: schema.TypeList, 92 Computed: true, 93 Elem: &schema.Resource{ 94 Schema: map[string]*schema.Schema{ 95 "host": &schema.Schema{ 96 Type: schema.TypeString, 97 Computed: true, 98 }, 99 "ipaddress": &schema.Schema{ 100 Type: schema.TypeString, 101 Computed: true, 102 }, 103 "container_port": &schema.Schema{ 104 Type: schema.TypeInt, 105 Computed: true, 106 }, 107 "service_port": &schema.Schema{ 108 Type: schema.TypeInt, 109 Computed: true, 110 }, 111 }, 112 }, 113 }, 114 "endpoint_full_hostname": &schema.Schema{ 115 Type: schema.TypeString, 116 Computed: true, 117 }, 118 "endpoint_full_url": &schema.Schema{ 119 Type: schema.TypeString, 120 Computed: true, 121 }, 122 "app_id": &schema.Schema{ 123 Type: schema.TypeString, 124 Computed: true, 125 }, 126 }, 127 } 128 } 129 130 func resourceArukasContainerCreate(d *schema.ResourceData, meta interface{}) error { 131 client := meta.(*ArukasClient) 132 133 var appSet API.AppSet 134 135 // create an app 136 newApp := API.App{Name: d.Get("name").(string)} 137 138 var parsedEnvs API.Envs 139 var parsedPorts API.Ports 140 141 if rawEnvs, ok := d.GetOk("environments"); ok { 142 parsedEnvs = expandEnvs(rawEnvs) 143 } 144 if rawPorts, ok := d.GetOk("ports"); ok { 145 parsedPorts = expandPorts(rawPorts) 146 } 147 148 newContainer := API.Container{ 149 Envs: parsedEnvs, 150 Ports: parsedPorts, 151 ImageName: d.Get("image").(string), 152 Mem: d.Get("memory").(int), 153 Instances: d.Get("instances").(int), 154 Cmd: d.Get("cmd").(string), 155 156 Name: d.Get("endpoint").(string), 157 } 158 newAppSet := API.AppSet{ 159 App: newApp, 160 Container: newContainer, 161 } 162 163 // create 164 if err := client.Post(&appSet, "/app-sets", newAppSet); err != nil { 165 return err 166 } 167 168 // start container 169 if err := client.Post(nil, fmt.Sprintf("/containers/%s/power", appSet.Container.ID), nil); err != nil { 170 return err 171 } 172 173 d.SetId(appSet.Container.ID) 174 175 stateConf := &resource.StateChangeConf{ 176 Target: []string{"running"}, 177 Pending: []string{"stopped", "booting"}, 178 Timeout: client.Timeout, 179 Refresh: func() (interface{}, string, error) { 180 var container API.Container 181 err := client.Get(&container, fmt.Sprintf("/containers/%s", appSet.Container.ID)) 182 if err != nil { 183 return nil, "", err 184 } 185 186 return container, container.StatusText, nil 187 }, 188 } 189 _, err := stateConf.WaitForState() 190 if err != nil { 191 return err 192 } 193 194 return resourceArukasContainerRead(d, meta) 195 } 196 197 func resourceArukasContainerRead(d *schema.ResourceData, meta interface{}) error { 198 client := meta.(*ArukasClient) 199 200 var container API.Container 201 var app API.App 202 203 if err := client.Get(&container, fmt.Sprintf("/containers/%s", d.Id())); err != nil { 204 return err 205 } 206 if err := client.Get(&app, fmt.Sprintf("/apps/%s", container.AppID)); err != nil { 207 return err 208 } 209 210 d.Set("app_id", container.AppID) 211 d.Set("name", app.Name) 212 d.Set("image", container.ImageName) 213 d.Set("instances", container.Instances) 214 d.Set("memory", container.Mem) 215 endpoint := container.Endpoint 216 if strings.HasSuffix(endpoint, ".arukascloud.io") { 217 endpoint = strings.Replace(endpoint, ".arukascloud.io", "", -1) 218 } 219 220 d.Set("endpoint", endpoint) 221 d.Set("endpoint_full_hostname", container.Endpoint) 222 d.Set("endpoint_full_url", fmt.Sprintf("https://%s", container.Endpoint)) 223 224 d.Set("cmd", container.Cmd) 225 226 //ports 227 d.Set("ports", flattenPorts(container.Ports)) 228 229 //port mappings 230 d.Set("port_mappings", flattenPortMappings(container.PortMappings)) 231 232 //envs 233 d.Set("environments", flattenEnvs(container.Envs)) 234 235 return nil 236 } 237 238 func resourceArukasContainerUpdate(d *schema.ResourceData, meta interface{}) error { 239 240 client := meta.(*ArukasClient) 241 var container API.Container 242 243 if err := client.Get(&container, fmt.Sprintf("/containers/%s", d.Id())); err != nil { 244 return err 245 } 246 247 var parsedEnvs API.Envs 248 var parsedPorts API.Ports 249 250 if rawEnvs, ok := d.GetOk("environments"); ok { 251 parsedEnvs = expandEnvs(rawEnvs) 252 } 253 if rawPorts, ok := d.GetOk("ports"); ok { 254 parsedPorts = expandPorts(rawPorts) 255 } 256 257 newContainer := API.Container{ 258 Envs: parsedEnvs, 259 Ports: parsedPorts, 260 ImageName: d.Get("image").(string), 261 Mem: d.Get("memory").(int), 262 Instances: d.Get("instances").(int), 263 Cmd: d.Get("cmd").(string), 264 Name: d.Get("endpoint").(string), 265 } 266 267 // update 268 if err := client.Patch(nil, fmt.Sprintf("/containers/%s", d.Id()), newContainer); err != nil { 269 return err 270 } 271 272 return resourceArukasContainerRead(d, meta) 273 274 } 275 276 func resourceArukasContainerDelete(d *schema.ResourceData, meta interface{}) error { 277 client := meta.(*ArukasClient) 278 var container API.Container 279 280 if err := client.Get(&container, fmt.Sprintf("/containers/%s", d.Id())); err != nil { 281 return err 282 } 283 284 if err := client.Delete(fmt.Sprintf("/apps/%s", container.AppID)); err != nil { 285 return err 286 } 287 288 return nil 289 }