func getFlavorID(client *gophercloud.ServiceClient, d *schema.ResourceData) (string, error) { flavorId := d.Get("flavor_id").(string) if flavorId != "" { return flavorId, nil } flavorName := d.Get("flavor_name").(string) return flavors.IDFromName(client, flavorName) }
func (s *StepLoadFlavor) Run(state multistep.StateBag) multistep.StepAction { config := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) // We need the v2 compute client client, err := config.computeV2Client() if err != nil { err = fmt.Errorf("Error initializing compute client: %s", err) state.Put("error", err) return multistep.ActionHalt } ui.Say(fmt.Sprintf("Loading flavor: %s", s.Flavor)) log.Printf("[INFO] Loading flavor by ID: %s", s.Flavor) flavor, err := flavors.Get(client, s.Flavor).Extract() if err != nil { log.Printf("[ERROR] Failed to find flavor by ID: %s", err) geterr := err log.Printf("[INFO] Loading flavor by name: %s", s.Flavor) id, err := flavors.IDFromName(client, s.Flavor) if err != nil { log.Printf("[ERROR] Failed to find flavor by name: %s", err) err = fmt.Errorf( "Unable to find specified flavor by ID or name!\n\n"+ "Error from ID lookup: %s\n\n"+ "Error from name lookup: %s", geterr, err) state.Put("error", err) return multistep.ActionHalt } flavor = &flavors.Flavor{ID: id} } ui.Message(fmt.Sprintf("Verified flavor. ID: %s", flavor.ID)) state.Put("flavor_id", flavor.ID) return multistep.ActionContinue }
// ToServerCreateMap assembles a request body based on the contents of a CreateOpts. func (opts CreateOpts) ToServerCreateMap() (map[string]interface{}, error) { sc := opts.ServiceClient opts.ServiceClient = nil b, err := gophercloud.BuildRequestBody(opts, "") if err != nil { return nil, err } if opts.UserData != nil { var userData string if _, err := base64.StdEncoding.DecodeString(string(opts.UserData)); err != nil { userData = base64.StdEncoding.EncodeToString(opts.UserData) } else { userData = string(opts.UserData) } b["user_data"] = &userData } if len(opts.SecurityGroups) > 0 { securityGroups := make([]map[string]interface{}, len(opts.SecurityGroups)) for i, groupName := range opts.SecurityGroups { securityGroups[i] = map[string]interface{}{"name": groupName} } b["security_groups"] = securityGroups } if len(opts.Networks) > 0 { networks := make([]map[string]interface{}, len(opts.Networks)) for i, net := range opts.Networks { networks[i] = make(map[string]interface{}) if net.UUID != "" { networks[i]["uuid"] = net.UUID } if net.Port != "" { networks[i]["port"] = net.Port } if net.FixedIP != "" { networks[i]["fixed_ip"] = net.FixedIP } } b["networks"] = networks } // If ImageRef isn't provided, check if ImageName was provided to ascertain // the image ID. if opts.ImageRef == "" { if opts.ImageName != "" { if sc == nil { err := ErrNoClientProvidedForIDByName{} err.Argument = "ServiceClient" return nil, err } imageID, err := images.IDFromName(sc, opts.ImageName) if err != nil { return nil, err } b["imageRef"] = imageID } } // If FlavorRef isn't provided, use FlavorName to ascertain the flavor ID. if opts.FlavorRef == "" { if opts.FlavorName == "" { err := ErrNeitherFlavorIDNorFlavorNameProvided{} err.Argument = "FlavorRef/FlavorName" return nil, err } if sc == nil { err := ErrNoClientProvidedForIDByName{} err.Argument = "ServiceClient" return nil, err } flavorID, err := flavors.IDFromName(sc, opts.FlavorName) if err != nil { return nil, err } b["flavorRef"] = flavorID } return map[string]interface{}{"server": b}, nil }
func resourceComputeInstanceV2Update(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) computeClient, err := config.computeV2Client(GetRegion(d)) if err != nil { return fmt.Errorf("Error creating OpenStack compute client: %s", err) } var updateOpts servers.UpdateOpts if d.HasChange("name") { updateOpts.Name = d.Get("name").(string) } if updateOpts != (servers.UpdateOpts{}) { _, err := servers.Update(computeClient, d.Id(), updateOpts).Extract() if err != nil { return fmt.Errorf("Error updating OpenStack server: %s", err) } } if d.HasChange("metadata") { oldMetadata, newMetadata := d.GetChange("metadata") var metadataToDelete []string // Determine if any metadata keys were removed from the configuration. // Then request those keys to be deleted. for oldKey, _ := range oldMetadata.(map[string]interface{}) { var found bool for newKey, _ := range newMetadata.(map[string]interface{}) { if oldKey == newKey { found = true } } if !found { metadataToDelete = append(metadataToDelete, oldKey) } } for _, key := range metadataToDelete { err := servers.DeleteMetadatum(computeClient, d.Id(), key).ExtractErr() if err != nil { return fmt.Errorf("Error deleting metadata (%s) from server (%s): %s", key, d.Id(), err) } } // Update existing metadata and add any new metadata. metadataOpts := make(servers.MetadataOpts) for k, v := range newMetadata.(map[string]interface{}) { metadataOpts[k] = v.(string) } _, err := servers.UpdateMetadata(computeClient, d.Id(), metadataOpts).Extract() if err != nil { return fmt.Errorf("Error updating OpenStack server (%s) metadata: %s", d.Id(), err) } } if d.HasChange("security_groups") { oldSGRaw, newSGRaw := d.GetChange("security_groups") oldSGSet := oldSGRaw.(*schema.Set) newSGSet := newSGRaw.(*schema.Set) secgroupsToAdd := newSGSet.Difference(oldSGSet) secgroupsToRemove := oldSGSet.Difference(newSGSet) log.Printf("[DEBUG] Security groups to add: %v", secgroupsToAdd) log.Printf("[DEBUG] Security groups to remove: %v", secgroupsToRemove) for _, g := range secgroupsToRemove.List() { err := secgroups.RemoveServer(computeClient, d.Id(), g.(string)).ExtractErr() if err != nil && err.Error() != "EOF" { if _, ok := err.(gophercloud.ErrDefault404); ok { continue } return fmt.Errorf("Error removing security group (%s) from OpenStack server (%s): %s", g, d.Id(), err) } else { log.Printf("[DEBUG] Removed security group (%s) from instance (%s)", g, d.Id()) } } for _, g := range secgroupsToAdd.List() { err := secgroups.AddServer(computeClient, d.Id(), g.(string)).ExtractErr() if err != nil && err.Error() != "EOF" { return fmt.Errorf("Error adding security group (%s) to OpenStack server (%s): %s", g, d.Id(), err) } log.Printf("[DEBUG] Added security group (%s) to instance (%s)", g, d.Id()) } } if d.HasChange("admin_pass") { if newPwd, ok := d.Get("admin_pass").(string); ok { err := servers.ChangeAdminPassword(computeClient, d.Id(), newPwd).ExtractErr() if err != nil { return fmt.Errorf("Error changing admin password of OpenStack server (%s): %s", d.Id(), err) } } } if d.HasChange("floating_ip") { oldFIP, newFIP := d.GetChange("floating_ip") log.Printf("[DEBUG] Old Floating IP: %v", oldFIP) log.Printf("[DEBUG] New Floating IP: %v", newFIP) if oldFIP.(string) != "" { log.Printf("[DEBUG] Attempting to disassociate %s from %s", oldFIP, d.Id()) if err := disassociateFloatingIPFromInstance(computeClient, oldFIP.(string), d.Id(), ""); err != nil { return fmt.Errorf("Error disassociating Floating IP during update: %s", err) } } if newFIP.(string) != "" { log.Printf("[DEBUG] Attempting to associate %s to %s", newFIP, d.Id()) if err := associateFloatingIPToInstance(computeClient, newFIP.(string), d.Id(), ""); err != nil { return fmt.Errorf("Error associating Floating IP during update: %s", err) } } } if d.HasChange("network") { oldNetworks, newNetworks := d.GetChange("network") oldNetworkList := oldNetworks.([]interface{}) newNetworkList := newNetworks.([]interface{}) for i, oldNet := range oldNetworkList { var oldFIP, newFIP string var oldFixedIP, newFixedIP string if oldNetRaw, ok := oldNet.(map[string]interface{}); ok { oldFIP = oldNetRaw["floating_ip"].(string) oldFixedIP = oldNetRaw["fixed_ip_v4"].(string) } if len(newNetworkList) > i { if newNetRaw, ok := newNetworkList[i].(map[string]interface{}); ok { newFIP = newNetRaw["floating_ip"].(string) newFixedIP = newNetRaw["fixed_ip_v4"].(string) } } // Only changes to the floating IP are supported if oldFIP != "" && oldFIP != newFIP { log.Printf("[DEBUG] Attempting to disassociate %s from %s", oldFIP, d.Id()) if err := disassociateFloatingIPFromInstance(computeClient, oldFIP, d.Id(), oldFixedIP); err != nil { return fmt.Errorf("Error disassociating Floating IP during update: %s", err) } } if newFIP != "" && oldFIP != newFIP { log.Printf("[DEBUG] Attempting to associate %s to %s", newFIP, d.Id()) if err := associateFloatingIPToInstance(computeClient, newFIP, d.Id(), newFixedIP); err != nil { return fmt.Errorf("Error associating Floating IP during update: %s", err) } } } } if d.HasChange("volume") { // old attachments and new attachments oldAttachments, newAttachments := d.GetChange("volume") // for each old attachment, detach the volume oldAttachmentSet := oldAttachments.(*schema.Set).List() log.Printf("[DEBUG] Attempting to detach the following volumes: %#v", oldAttachmentSet) if blockClient, err := config.blockStorageV1Client(GetRegion(d)); err != nil { return err } else { if err := detachVolumesFromInstance(computeClient, blockClient, d.Id(), oldAttachmentSet); err != nil { return err } } // for each new attachment, attach the volume newAttachmentSet := newAttachments.(*schema.Set).List() if blockClient, err := config.blockStorageV1Client(GetRegion(d)); err != nil { return err } else { if err := attachVolumesToInstance(computeClient, blockClient, d.Id(), newAttachmentSet); err != nil { return err } } d.SetPartial("volume") } if d.HasChange("flavor_id") || d.HasChange("flavor_name") { var newFlavorId string var err error if d.HasChange("flavor_id") { newFlavorId = d.Get("flavor_id").(string) } else { newFlavorName := d.Get("flavor_name").(string) newFlavorId, err = flavors.IDFromName(computeClient, newFlavorName) if err != nil { return err } } resizeOpts := &servers.ResizeOpts{ FlavorRef: newFlavorId, } log.Printf("[DEBUG] Resize configuration: %#v", resizeOpts) err = servers.Resize(computeClient, d.Id(), resizeOpts).ExtractErr() if err != nil { return fmt.Errorf("Error resizing OpenStack server: %s", err) } // Wait for the instance to finish resizing. log.Printf("[DEBUG] Waiting for instance (%s) to finish resizing", d.Id()) stateConf := &resource.StateChangeConf{ Pending: []string{"RESIZE"}, Target: []string{"VERIFY_RESIZE"}, Refresh: ServerV2StateRefreshFunc(computeClient, d.Id()), Timeout: 30 * time.Minute, Delay: 10 * time.Second, MinTimeout: 3 * time.Second, } _, err = stateConf.WaitForState() if err != nil { return fmt.Errorf("Error waiting for instance (%s) to resize: %s", d.Id(), err) } // Confirm resize. log.Printf("[DEBUG] Confirming resize") err = servers.ConfirmResize(computeClient, d.Id()).ExtractErr() if err != nil { return fmt.Errorf("Error confirming resize of OpenStack server: %s", err) } stateConf = &resource.StateChangeConf{ Pending: []string{"VERIFY_RESIZE"}, Target: []string{"ACTIVE"}, Refresh: ServerV2StateRefreshFunc(computeClient, d.Id()), Timeout: 30 * time.Minute, Delay: 10 * time.Second, MinTimeout: 3 * time.Second, } _, err = stateConf.WaitForState() if err != nil { return fmt.Errorf("Error waiting for instance (%s) to confirm resize: %s", d.Id(), err) } } return resourceComputeInstanceV2Read(d, meta) }