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