VMware {code} Community
OldguardMD
Contributor
Contributor
Jump to solution

cloud-init Never Works through API

We need to use cloud-init to assign IP addresses to VMs we create through the API as part of a cloning process. We have tried many variations other then this example, but they all return the same error. 

 

curl -X PUT 'https://<vCenterServerRemoved>/api/vcenter/vm/vm-17057/guest/customization' -H 'vmware-api-session-id: SessionIDRemoved' -H 'Content-type: application/json' -d '{ "spec": { "configuration_spec": { "linux_config": { "domain": "domain.removed", "hostname": { "fixed_name": "hostnameremoved", "type": "FIXED" } } }, "global_DNS_settings": {}, "interfaces": {} } }'

Here is the result:

{
"messages": [
{
"args": [],
"default_message": "Invalid type",
"id": "vapi.data.invalid.type"
}
]
}

 

We have tried a number of different examples and languages to see if we can figure out a path forward. The end state will include metadata and userdata, but the example above is intended to simplify the input. 

Target is vcenter 7.0.3.01800

 

Tags (3)
0 Kudos
1 Solution

Accepted Solutions
OldguardMD
Contributor
Contributor
Jump to solution

We found the cause of this issue. It appears the JSON was never the problem, though in some instances I likely broke the code trying to fix the issue. This was easiest to troubleshoot in postman, because the returned data seems to be more visible / effective when you have the JSON wrong. The issue we could never get past was this error:

 

{
    "error_type": "INVALID_ARGUMENT",
    "messages": []
} 

 

We determined that when "Guest OS Version" is set to "Debian GNU/Linux 11 (64-Bit)" you get the above error. Change the OS Version to "Other Linux (64-Bit)", the problem goes away. We are actcually running Debian 12 set as Debian 11 in the Guest OS Version, but it works fine as long as you don't select Debian 11.

We also noticed that in Terraform and govc, there is an alternative mothod that might be more compatible and maybe less complicated. With Terraform, it appears that SOAP is used to modify extraConfig properties of the VM, including:

  • guestinfo.userdata
  • guestinfo.userdata.encoding
  • guestinfo.metadata
  • guestinfo.metadata.encoding

This SOAP call has been around for much longer than the new REST method, and it doesn't require unnecessary elements that are required with the rest call. I have no experience with SOAP, so it will take a bit for me to provide that method as a foot note to this solution.

View solution in original post

0 Kudos
2 Replies
OldguardMD
Contributor
Contributor
Jump to solution

So this has gotten even worse. I can now send JSON to the server that destablizes the vCenter box (7.0.3.01800).

Let's say I have this url:

https://<our-vcenter-box>/api/vcenter/vm/vm-18876/guest/customization

And I push this JSON as a PUT:

 

{
        "spec": {
            "configuration_spec": {
                "linux_config": {
                    "domain": "removed.domain.local",
                    "hostname": {
                        "fixed_name": "removed-hostname",
                        "type": "FIXED"
                    }
                }
            },
            "global_DNS_settings": {},
            "interfaces": [
                {
                    "adapter": {
                        "ipv4": {
                            "type": "STATIC"
                        }
                    }
                }
            ]
        }
    }
}

 

I then get to reboot my vcenter box, because the entire GUI dies. Both the GUI and the API return "SERVICE_UNAVAILABLE" until you reboot the vCenter box.

Not sure this is a good feature.

Tags (1)
0 Kudos
OldguardMD
Contributor
Contributor
Jump to solution

We found the cause of this issue. It appears the JSON was never the problem, though in some instances I likely broke the code trying to fix the issue. This was easiest to troubleshoot in postman, because the returned data seems to be more visible / effective when you have the JSON wrong. The issue we could never get past was this error:

 

{
    "error_type": "INVALID_ARGUMENT",
    "messages": []
} 

 

We determined that when "Guest OS Version" is set to "Debian GNU/Linux 11 (64-Bit)" you get the above error. Change the OS Version to "Other Linux (64-Bit)", the problem goes away. We are actcually running Debian 12 set as Debian 11 in the Guest OS Version, but it works fine as long as you don't select Debian 11.

We also noticed that in Terraform and govc, there is an alternative mothod that might be more compatible and maybe less complicated. With Terraform, it appears that SOAP is used to modify extraConfig properties of the VM, including:

  • guestinfo.userdata
  • guestinfo.userdata.encoding
  • guestinfo.metadata
  • guestinfo.metadata.encoding

This SOAP call has been around for much longer than the new REST method, and it doesn't require unnecessary elements that are required with the rest call. I have no experience with SOAP, so it will take a bit for me to provide that method as a foot note to this solution.

0 Kudos