github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/builtin/providers/vcd/resource_vcd_vapp.go (about) 1 package vcd 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/hashicorp/terraform/helper/schema" 8 types "github.com/hmrc/vmware-govcd/types/v56" 9 ) 10 11 func resourceVcdVApp() *schema.Resource { 12 return &schema.Resource{ 13 Create: resourceVcdVAppCreate, 14 Update: resourceVcdVAppUpdate, 15 Read: resourceVcdVAppRead, 16 Delete: resourceVcdVAppDelete, 17 18 Schema: map[string]*schema.Schema{ 19 "name": &schema.Schema{ 20 Type: schema.TypeString, 21 Required: true, 22 ForceNew: true, 23 }, 24 25 "template_name": &schema.Schema{ 26 Type: schema.TypeString, 27 Required: true, 28 ForceNew: true, 29 }, 30 31 "catalog_name": &schema.Schema{ 32 Type: schema.TypeString, 33 Required: true, 34 }, 35 36 "network_href": &schema.Schema{ 37 Type: schema.TypeString, 38 Optional: true, 39 }, 40 41 "network_name": &schema.Schema{ 42 Type: schema.TypeString, 43 Required: true, 44 ForceNew: true, 45 }, 46 "memory": &schema.Schema{ 47 Type: schema.TypeInt, 48 Optional: true, 49 }, 50 "cpus": &schema.Schema{ 51 Type: schema.TypeInt, 52 Optional: true, 53 }, 54 "ip": &schema.Schema{ 55 Type: schema.TypeString, 56 Optional: true, 57 Computed: true, 58 }, 59 "initscript": &schema.Schema{ 60 Type: schema.TypeString, 61 Optional: true, 62 ForceNew: true, 63 }, 64 "metadata": &schema.Schema{ 65 Type: schema.TypeMap, 66 Optional: true, 67 }, 68 "href": &schema.Schema{ 69 Type: schema.TypeString, 70 Optional: true, 71 Computed: true, 72 }, 73 "power_on": &schema.Schema{ 74 Type: schema.TypeBool, 75 Optional: true, 76 Default: true, 77 }, 78 }, 79 } 80 } 81 82 func resourceVcdVAppCreate(d *schema.ResourceData, meta interface{}) error { 83 vcdClient := meta.(*VCDClient) 84 85 catalog, err := vcdClient.Org.FindCatalog(d.Get("catalog_name").(string)) 86 if err != nil { 87 return fmt.Errorf("Error finding catalog: %#v", err) 88 } 89 90 catalogitem, err := catalog.FindCatalogItem(d.Get("template_name").(string)) 91 if err != nil { 92 return fmt.Errorf("Error finding catelog item: %#v", err) 93 } 94 95 vapptemplate, err := catalogitem.GetVAppTemplate() 96 if err != nil { 97 return fmt.Errorf("Error finding VAppTemplate: %#v", err) 98 } 99 100 log.Printf("[DEBUG] VAppTemplate: %#v", vapptemplate) 101 var networkHref string 102 net, err := vcdClient.OrgVdc.FindVDCNetwork(d.Get("network_name").(string)) 103 if err != nil { 104 return fmt.Errorf("Error finding OrgVCD Network: %#v", err) 105 } 106 if attr, ok := d.GetOk("network_href"); ok { 107 networkHref = attr.(string) 108 } else { 109 networkHref = net.OrgVDCNetwork.HREF 110 } 111 // vapptemplate := govcd.NewVAppTemplate(&vcdClient.Client) 112 // 113 createvapp := &types.InstantiateVAppTemplateParams{ 114 Ovf: "http://schemas.dmtf.org/ovf/envelope/1", 115 Xmlns: "http://www.vmware.com/vcloud/v1.5", 116 Name: d.Get("name").(string), 117 InstantiationParams: &types.InstantiationParams{ 118 NetworkConfigSection: &types.NetworkConfigSection{ 119 Info: "Configuration parameters for logical networks", 120 NetworkConfig: &types.VAppNetworkConfiguration{ 121 NetworkName: d.Get("network_name").(string), 122 Configuration: &types.NetworkConfiguration{ 123 ParentNetwork: &types.Reference{ 124 HREF: networkHref, 125 }, 126 FenceMode: "bridged", 127 }, 128 }, 129 }, 130 }, 131 Source: &types.Reference{ 132 HREF: vapptemplate.VAppTemplate.HREF, 133 }, 134 } 135 136 err = retryCall(vcdClient.MaxRetryTimeout, func() error { 137 e := vcdClient.OrgVdc.InstantiateVAppTemplate(createvapp) 138 139 if e != nil { 140 return fmt.Errorf("Error: %#v", e) 141 } 142 143 e = vcdClient.OrgVdc.Refresh() 144 if e != nil { 145 return fmt.Errorf("Error: %#v", e) 146 } 147 return nil 148 }) 149 if err != nil { 150 return err 151 } 152 153 vapp, err := vcdClient.OrgVdc.FindVAppByName(d.Get("name").(string)) 154 155 err = retryCall(vcdClient.MaxRetryTimeout, func() error { 156 task, err := vapp.ChangeVMName(d.Get("name").(string)) 157 if err != nil { 158 return fmt.Errorf("Error with vm name change: %#v", err) 159 } 160 161 return task.WaitTaskCompletion() 162 }) 163 if err != nil { 164 return fmt.Errorf("Error changing vmname: %#v", err) 165 } 166 167 err = retryCall(vcdClient.MaxRetryTimeout, func() error { 168 task, err := vapp.ChangeNetworkConfig(d.Get("network_name").(string), d.Get("ip").(string)) 169 if err != nil { 170 return fmt.Errorf("Error with Networking change: %#v", err) 171 } 172 return task.WaitTaskCompletion() 173 }) 174 if err != nil { 175 return fmt.Errorf("Error changing network: %#v", err) 176 } 177 178 if initscript, ok := d.GetOk("initscript"); ok { 179 err = retryCall(vcdClient.MaxRetryTimeout, func() error { 180 task, err := vapp.RunCustomizationScript(d.Get("name").(string), initscript.(string)) 181 if err != nil { 182 return fmt.Errorf("Error with setting init script: %#v", err) 183 } 184 return task.WaitTaskCompletion() 185 }) 186 if err != nil { 187 return fmt.Errorf("Error completing tasks: %#v", err) 188 } 189 } 190 191 d.SetId(d.Get("name").(string)) 192 193 return resourceVcdVAppUpdate(d, meta) 194 } 195 196 func resourceVcdVAppUpdate(d *schema.ResourceData, meta interface{}) error { 197 vcdClient := meta.(*VCDClient) 198 vapp, err := vcdClient.OrgVdc.FindVAppByName(d.Id()) 199 200 if err != nil { 201 return fmt.Errorf("Error finding VApp: %#v", err) 202 } 203 204 status, err := vapp.GetStatus() 205 if err != nil { 206 return fmt.Errorf("Error getting VApp status: %#v", err) 207 } 208 209 if d.HasChange("metadata") { 210 oraw, nraw := d.GetChange("metadata") 211 metadata := oraw.(map[string]interface{}) 212 for k := range metadata { 213 task, err := vapp.DeleteMetadata(k) 214 if err != nil { 215 return fmt.Errorf("Error deleting metadata: %#v", err) 216 } 217 err = task.WaitTaskCompletion() 218 if err != nil { 219 return fmt.Errorf("Error completing tasks: %#v", err) 220 } 221 } 222 metadata = nraw.(map[string]interface{}) 223 for k, v := range metadata { 224 task, err := vapp.AddMetadata(k, v.(string)) 225 if err != nil { 226 return fmt.Errorf("Error adding metadata: %#v", err) 227 } 228 err = task.WaitTaskCompletion() 229 if err != nil { 230 return fmt.Errorf("Error completing tasks: %#v", err) 231 } 232 } 233 234 } 235 236 if d.HasChange("memory") || d.HasChange("cpus") || d.HasChange("power_on") { 237 if status != "POWERED_OFF" { 238 task, err := vapp.PowerOff() 239 if err != nil { 240 return fmt.Errorf("Error Powering Off: %#v", err) 241 } 242 err = task.WaitTaskCompletion() 243 if err != nil { 244 return fmt.Errorf("Error completing tasks: %#v", err) 245 } 246 } 247 248 if d.HasChange("memory") { 249 err = retryCall(vcdClient.MaxRetryTimeout, func() error { 250 task, err := vapp.ChangeMemorySize(d.Get("memory").(int)) 251 if err != nil { 252 return fmt.Errorf("Error changing memory size: %#v", err) 253 } 254 255 return task.WaitTaskCompletion() 256 }) 257 if err != nil { 258 return err 259 } 260 } 261 262 if d.HasChange("cpus") { 263 err = retryCall(vcdClient.MaxRetryTimeout, func() error { 264 task, err := vapp.ChangeCPUcount(d.Get("cpus").(int)) 265 if err != nil { 266 return fmt.Errorf("Error changing cpu count: %#v", err) 267 } 268 269 return task.WaitTaskCompletion() 270 }) 271 if err != nil { 272 return fmt.Errorf("Error completing task: %#v", err) 273 } 274 } 275 276 if d.Get("power_on").(bool) { 277 task, err := vapp.PowerOn() 278 if err != nil { 279 return fmt.Errorf("Error Powering Up: %#v", err) 280 } 281 err = task.WaitTaskCompletion() 282 if err != nil { 283 return fmt.Errorf("Error completing tasks: %#v", err) 284 } 285 } 286 287 } 288 289 return resourceVcdVAppRead(d, meta) 290 } 291 292 func resourceVcdVAppRead(d *schema.ResourceData, meta interface{}) error { 293 vcdClient := meta.(*VCDClient) 294 295 err := vcdClient.OrgVdc.Refresh() 296 if err != nil { 297 return fmt.Errorf("Error refreshing vdc: %#v", err) 298 } 299 300 vapp, err := vcdClient.OrgVdc.FindVAppByName(d.Id()) 301 if err != nil { 302 log.Printf("[DEBUG] Unable to find vapp. Removing from tfstate") 303 d.SetId("") 304 return nil 305 } 306 d.Set("ip", vapp.VApp.Children.VM[0].NetworkConnectionSection.NetworkConnection.IPAddress) 307 308 return nil 309 } 310 311 func resourceVcdVAppDelete(d *schema.ResourceData, meta interface{}) error { 312 vcdClient := meta.(*VCDClient) 313 vapp, err := vcdClient.OrgVdc.FindVAppByName(d.Id()) 314 315 if err != nil { 316 return fmt.Errorf("error finding vapp: %s", err) 317 } 318 319 if err != nil { 320 return fmt.Errorf("Error getting VApp status: %#v", err) 321 } 322 323 _ = retryCall(vcdClient.MaxRetryTimeout, func() error { 324 task, err := vapp.Undeploy() 325 if err != nil { 326 return fmt.Errorf("Error undeploying: %#v", err) 327 } 328 329 return task.WaitTaskCompletion() 330 }) 331 332 err = retryCall(vcdClient.MaxRetryTimeout, func() error { 333 task, err := vapp.Delete() 334 if err != nil { 335 return fmt.Errorf("Error deleting: %#v", err) 336 } 337 338 return task.WaitTaskCompletion() 339 }) 340 341 return err 342 }