Onegate client not working as advertised

From within a VM I try to initiate a “resched” operation through the onegate client provided by contextualisation service. According to 1 I should be able to perform a “onegate vm resched”. If I do so I get the response “You have to provide a VM ID”. Adding a VM ID results in the following response “ERROR:
Empty or invalid SERVICE_ID”. Even if the owner of the VM is “oneadmin” the same RRROR is thrown. Am I doing it wrong?

Hi Stefan,

The VM ID for actions is mandatory, I will update the documentation.

Does the VM belong to a OneFlow service? Currently, actions are only supported for VMs that are part of a service.

The VM does not belong to a OneFlow service. So that explains why it’s not working. The onegate client is explained in the “OneGate” documentation: http://docs.opennebula.org/4.14/advanced_administration/application_insight/onegate_usage.html#onegate-client-usage. So fromt this documentation you expect it to work regardless of OneFlow service(s).

The onegate functionality might be a security risk though as a user can update the “USER TEMPLATE” information which has the following attributes:

SCHED_DS_REQUIREMENTS="some_datastore"
SCHED_REQUIREMENTS=“ID=some_host_id”

A user could update for example “SCHED_REQUIREMENTS” with a different host_id and trigger a “resched” operation. From a cloud admin perspective this might be undesireable (as it for example could be a host reserved for “high performance” customers). Do you need to have VM:ADMIN permissions (http://docs.opennebula.org/4.14/integration/system_interfaces/api.html#onevm)?

This limitation makes no sense, I have created a ticket to enable these actions for a VM that does not belong to a service

The permissions for the OneGate server can be customized in the onegate-server.conf file. In this file you can disable the action_by_id api calls.
http://docs.opennebula.org/4.14/advanced_administration/application_insight/onegate_configure.html#configuration

Even, if this option is enabled, the action will be performed using the UNAME of the VM and the permissions associated with this user will be applied.

But, yes probably there should be a configuration option to define the attrs that cannot be modified through OneGate.

I’d like to clarify something here: the scheduler is not so easily fooled. You can request whatever you want in the template, but the scheduler will check those requirements only against the set of hosts that the VM owner can actually deploy to (HOST:MANAGE).

Moreover, if it really is a concern in your infrastructure, SCHED_REQUIREMENTS can be added as a RESTRICTED_ATTRIBUTE in oned.conf to disable it from any interface, not just OneGate:

http://docs.opennebula.org/4.14/administration/references/oned_conf.html#restricted-attributes-configuration

Hi Developers,
I’m using ONE-5.4.1 and I can’t poweroff the VMs that are not part of a OneFlow service through onegate. The restart command is functioning althoug.
When I run the poweroff command from inside the VM that I want to turn off I get the error:
sudo onegate vm poweroff 57
ERROR:
Empty or invalid SERVICE_ID
The issue ticket http://dev.opennebula.org/issues/4255 report that this issue was fixed after ONE 5.0. Could you please verify if the poweroff feature is working without SERVICE_ID requirement.

I want to poweroff through onegate to remain the correct VM status every time, because if I use the linux poweroff command inside the VM the VM status on ONE will take some time to be updated by the scheduler.

Thank you.
Regards!

I have found the error source. It is in the onegate-server.rb, line 158, on the get_requested_vm definition.
When testing if the source_vm['ID'] is different of requested_vm_id it is comparing string with integer. So they never pass over this condition. Inside them the function check_vm_in_service raise the refereed error.
I found this examining the source code and outputting the variables’ values in the erro log.
My solution was to convert the source_vm['ID'] to integer before comparison as shown here:

# Retrieve the VM id from the header of the request and return
# an OpenNebula VirtualMachine object
def get_source_vm(request_env, client)
    vm_id = request_env['HTTP_X_ONEGATE_VMID'].to_i
    get_vm(vm_id, client)
end

def get_requested_vm(requested_vm_id, request_env, client)
    source_vm = get_source_vm(request_env, client)
==> if source_vm['ID'].to_i != requested_vm_id
    #   logger.error {"Source  #{source_vm['ID']} != requested  #{requested_vm_id.to_i} VMID."}_
        service_id = source_vm['USER_TEMPLATE/SERVICE_ID']
        check_vm_in_service(requested_vm_id, service_id, client)

        requested_vm = get_vm(requested_vm_id, client)
    else
        requested_vm = source_vm
    end
end

I hope someone update this on future releases.
Thank you.
#development #support

1 Like