-
Notifications
You must be signed in to change notification settings - Fork 453
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
r/virtual_machine: add vApp properties #303
Conversation
- Currently removing vApp properties doesn't work, which seems to potentially be a vSphere API or client issue. Signed-off-by: Rowan Jacobs <[email protected]>
@charandas I've verified that setting Here's what the VM configuration I'm using looks like:
|
I'm testing against vSphere 5.5. |
I had missed the file changes in vsphere/virtual_machine_config_structure.go when building last night. Sorry for the false alarm. It works now. The reason I reverted to manually copying changes from your fork, is because of the following:
|
Hey @rowanjacobs, just wanted to say I have been watching this and it looks promising - I will give this a much closer look later this week! One thing that I did notice when I looked earlier - does this support removal of the vApp properties? It looks like another attribute needs to be set to make this happen ( In any case - will look later this week as mentioned. |
Just want to thank you guys for working on this stuff... I use terraform with vsphere to deploy some images that doesn't support guest customization and this is the only way to go for me, so I'm very excited seing you guys working on it! |
Hey @rowanjacobs, I'm about to give this a spin to see how it goes. I'll also see if I can solve the config zeroing problem as well. Re: What I mentioned about removing vApp config, I don't think we need to concern ourselves with this right now 100%. A VM's OVF configuration is a complex thing that I think that we might not even want to touch with TF, treating vApp and OVF template configuration as kind of a template that that is out of our scope to manage, but rather something that would be up to something like Packer to configure as part of the image building process. Anyway, will update soon! |
Hey @rowanjacobs, alright, finished checking, looks like there is an issue here. Here is the
This is not writing a correct configuration. I think the best way to illustrate it is via how it seems to be overwriting some of the config parameters. Here is an example of the first three from the MOB. The first parameter - However, the next couple get odd looking. This is the next parameter, the full cloud-config data, which should have not been touched. However if you look at the second picture here closely, you'll see that the key has been overwritten with the Finally, the last example overwrites the cloud-config URL property with the key and value for Finally, there is a non-empty diff on the next plan:
Looking deeper, I'm guessing there has to be something up with the way the Also thinking about this a bit more, and given the potential for corruption here: I think we should be a bit more absolute when working with the vApp settings - we should only allow keys that are already in the vApp configuration (ie: are already valid parameters in the template). Also, we should make sure that we are saving non-zero values for any keys that are a part of the vApp configuration but are not defined in Terraform config (this way they can be properly zeroed out on the next run). I'll add some notes in the code in the next couple of hours. |
// | ||
// This sub-resource allows the customization of vApp properties | ||
// on cloned VMs. | ||
func VAppSubresourceSchema() map[string]*schema.Schema { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could probably just put this directly into schemaVirtualMachineConfigSpec
as it's so small, along with the vapp
key. I'm almost tempted to also just say we flatten it and name it vapp_properties
, but we might need to add more keys at a later time.
@@ -836,6 +836,45 @@ func TestAccResourceVSphereVirtualMachine(t *testing.T) { | |||
}, | |||
}, | |||
}, | |||
{ | |||
"clone with vapp properties", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some thoughts on testing this while enforcing present keys only - we might need to test this against a CoreOS template or something else well known, and work on setting well-known cloud-config keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've started testing against the CoreOS OVA instead of against a custom-built template.
Info: &types.VAppPropertyInfo{ | ||
Key: int32(i) + 1, | ||
Id: k, | ||
Value: "", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noticed this here - the original comment said that there was problems zeroing out a property - is this code non-functional, or were you referring to something else (maybe deleting a key completely)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issues with zeroing out properties are due to the fact that at least in version 5.5, the vSphere API doesn't actually do anything when it receives an empty string for a vApp property value. We've gotten around this by changing the empty string to " ", and the corresponding portion of the new code should work properly now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! This is great info actually as I can now update some of my code on the work I was doing on govc. Good find! 👍
} | ||
vac := make(map[string]interface{}) | ||
vApp := d.Get("vapp").([]interface{}) | ||
if len(vApp) > 0 && vApp[0] != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in the comments before the change request, I think we need to add config values that have non-zero values set on them as well, that way, on the next apply, they get zeroed out and any defaults apply. That way, removing a key always removes the corresponding value from config, even if someone adds OOB changes.
_, isOld := oldMap[k] | ||
_, isNew := newMap[k] | ||
|
||
if isNew { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Annotating as I'm guessing it would be around here - just noting that we will want to somehow check to ensure the key is actually present in the vApp config before working with it. This may be here, or in another part of the function, or in another function altogether (maybe it actually is part of diff customization so that we can keep the method signature clean here and as consistent as possible with the rest of the expander/flattener logic).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although it changes the signature, I decided to check if the key is present in this function because it does clean up the logic of the function significantly, now that we no longer have to merge two different lists of vApp properties and can rely on the canonical list of properties from the template.
// We track changes to keys to determine if any have been removed from | ||
// configuration - if they have, we add them with an empty value to ensure | ||
// they are removed from vAppConfig on the update. | ||
func expandVAppConfig(d *schema.ResourceData) types.BaseVmConfigSpec { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BaseVmConfigSpec
is an interface, but we aren't returning anything else other than VmConfigSpec
so this is abstracting things in a way that they don't need to be abstracted. Can this be changed to return a *types.VmConfigSpec
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Thanks for getting back to us with your feedback! Unfortunately I'm about to go on vacation and the rest of the team will be short-staffed next week, so it's unlikely we'll be able to make required changes until the beginning of January. We'll definitely get to it when we can! |
instead of getting them from the old version of the terraform template
Hey @rowanjacobs - just FYI I will probably be reviewing this next week. Thanks! |
- so that terraform always knows about all keys in vApp properties Signed-off-by: Rowan Jacobs <[email protected]>
Signed-off-by: Desmond Pompa Alarcon Rawls <[email protected]>
Hey all, looks like this is coming along great. A few things are still outstanding, save maybe documentation (still haven't looked at this part yet):
Do you know when you all will be able to work on these items? If it's going to be too much later, I can actually get these over the line for you all. We are actually doing some work here internally that could benefit from this and I'd be happy to finish it up. But let me know either way 🙂 |
I can definitely take care of the first change. I'll see if I can get to the second one this week, and if not then I'll pass it back to you since I'm going to be unavailable for a while starting next week. |
Fair enough! Will keep an eye out 👍 This is looking very good by the way! I was excited to see a CoreOS VM come up purely from guestinfo! |
Thanks! Regarding the second change: should the plan fail and provide an error message indicating that you can't add new vApp property keys? Or should the new keys be silently removed from the plan? (Or, for my own reference, do you have an existing example somewhere in this or another provider that implements this in a preferred way?) |
Hey @rowanjacobs sorry for missing this. It should be set up so that TF explicitly fails with an error. We don't want silent behaviour as that gives the wrong impression to the user, and the bad keys risk ending up propagating to state, which would be bad as well. |
Signed-off-by: Genevieve LEsperance <[email protected]>
We were thinking of returning an error from |
Signed-off-by: Rowan Jacobs <[email protected]>
Signed-off-by: Genevieve LEsperance <[email protected]>
Here's an example of what the error looks like:
|
Hey @rowanjacobs, the error handling looks good for now. I want to maybe move this over to CustomizeDiff in the long run both so that the validation can be done at plan-time, and also so that we keep the expander/flattener interface clean, but that can be done later. I'm reviewing this today - if it looks good, is it ready to merge? Thanks! |
Yes, it should be ready to merge. Thanks! |
Outstanding checklist:
|
The interface for expandVirtualMachineConfigSpec has changed to accommodate errors during config expansion (namely to check for invalid vApp properties). However, as the expansion happens post-clone but before the initial configuration, errors risk putting the Terraform state in an irrecoverable situation should the configuration fail here. Moved the rollback functionality that we have for the post-clone reconfigure into a helper function so that we can leverage it here. Also, changed the wording of the error message so that it's a bit friendlier to the average user.
This blocks vApp properties from being set on virtual machines created from scratch. As this support is targeted towards VMs that haven been cloned from a template that has been imported from OVF/OVA, we expect the vApp configuration to exist (and further to that we don't support setting unknown keys). This basically means that it's impossible to set vApp properties on new virtual machines with this resource, or it should be. This commit corrects a few crash scenarios that are happening when trying to use this block on new virtual machines as it stands. It also blocks situations where someone tries to add configuration after the fact or on a virtual machine where no vApp configuration exists, which would be possible on both the from-scratch and clone paths.
* Unexported the schema helper for vApp configurations. * Fixed a hit on the standard "else" linter.
Also corrected some things that were actually valid for extra_config already, but had not been updated since discovering that vApp properties/OVF environment was blocking the ability to use guestinfo.
We have a different Linux template (Ubuntu) for base testing, I don't want to mess with that specifically. As such, I've added a variable exclusively for CoreOS templates and set the vApp tests to use those.
The tests were not working with our lab as the seemed to be expecting DHCP for network configuration. Added in the appropriate configuration options that are set up for the rest of the clone tests, with the customization options just moved to their appropriate cloud-config key/value settings. This may need to be changed if CoreOS ever drops support for the old cloud-init guestinfo keys in favour of Ignition.
Final update of the vApp property tests, adding tests for all determined failure scenarios to make sure we are trapping errors correctly. This should be the last commit before merge.
FYI - this LGTM, I've made several updates and resolved the merge conflicts and I think we are in a good place now. I'm just waiting for the whole VM test suite to finish and then I'm merging! Great job and hats off to everyone at @pivotal and @pivotal-cf that made this happen! |
In order to support configurable vApp properties on VMs cloned from an OVF (#243), we have added a
vapp
subresource with aproperties
key-value map. In order to run acceptance tests, the template needs to have vApp properties with the keysexample_key
andanother_key
, whose initial and default values should be blank.Note that we haven't been able to successfully implement zeroing out a property. This seems to likely be an issue with the vSphere API or client. But we think this should not block adding this feature in the mean time.
cc @mcwumbly @desmondrawls @genevievelesperance @evanfarrar