def executeRequest(vm_uuid, vm_name, config_path, cmd, full_vol_name, opts):
    """
    Executes a <cmd> request issused from a VM.
    The request is about volume <full_volume_name> in format volume@datastore.
    If @datastore is omitted, the one where the VM resides is used.
    For VM, the function gets vm_uuid, vm_name and config_path
    <opts> is a json options string blindly passed to a specific operation

    Returns None (if all OK) or error string
    """
    vm_datastore = get_datastore_name(config_path)
    error_info, tenant_uuid, tenant_name = auth.authorize(vm_uuid, vm_datastore, cmd, opts)
    if error_info:
        return err(error_info)

    if cmd == "list":
        return listVMDK(vm_datastore, tenant_name)

    try:
        vol_name, datastore = parse_vol_name(full_vol_name)
    except ValidationError as ex:
        return err(str(ex))
    if not datastore:
        datastore = vm_datastore
    elif datastore not in known_datastores():
        return err("Invalid datastore '%s'.\n" \
                   "Known datastores: %s.\n" \
                   "Default datastore: %s" \
                   % (datastore, ", ".join(known_datastores()), vm_datastore))

    # get /vmfs/volumes/<volid>/dockvols path on ESX:
    path = get_vol_path(datastore, tenant_name)
    logging.debug("executeRequest %s %s", tenant_name, path)
    if path is None:
        return err("Failed to initialize volume path {0}".format(path))

    vmdk_path = vmdk_utils.get_vmdk_path(path, vol_name)

    if cmd == "get":
        response = getVMDK(vmdk_path, vol_name, datastore)
    elif cmd == "create":
        response = createVMDK(vmdk_path, vm_name, vol_name, opts)
        # create succeed, insert infomation of this volume to volumes table
        if not response:
            if tenant_uuid:
                vol_size_in_MB = convert.convert_to_MB(auth.get_vol_size(opts))
                auth.add_volume_to_volumes_table(tenant_uuid, datastore, vol_name, vol_size_in_MB)
            else:
                logging.warning(" VM %s does not belong to any tenant", vm_name)
                                      
    elif cmd == "remove":
        response = removeVMDK(vmdk_path)
    elif cmd == "attach":
        response = attachVMDK(vmdk_path, vm_uuid)
    elif cmd == "detach":
        response = detachVMDK(vmdk_path, vm_uuid)
    else:
        return err("Unknown command:" + cmd)

    return response
Example #2
0
    def test_vmdkop_authorize(self):
        vm_ds = 'datastore1'
        vms = [(self.vm_uuid, self.vm_name)]
        privileges = []
        default_datastore='default_ds'
        default_privileges = {'datastore': default_datastore,
                        'global_visibility': 0,
                        'create_volume': 0,
                        'delete_volume': 0,
                        'mount_volume': 0,
                        'max_volume_size': 0,
                        'usage_quota': 0}
                
        error_info, tenant1 = self.auth_mgr.create_tenant('vmdk_auth_test', 'Tenant used to vmdk_auth_test', default_datastore,
                                              default_privileges, vms, privileges)
        self.assertEqual(error_info, None)
        self.assertTrue(uuid.UUID(tenant1.id))

        # test CMD_CREATE without "create_volume" set
        privileges = [{'datastore': vm_ds,
                        'global_visibility': 0,
                        'create_volume': 0,
                        'delete_volume': 0,
                        'mount_volume': 1,
                        'max_volume_size': 500,
                        'usage_quota': 1000}]
        
        error_info = tenant1.set_datastore_access_privileges(self.auth_mgr.conn, privileges)
        self.assertEqual(error_info, None)
        opts={u'size': u'100MB', u'fstype': u'ext4'}
        error_info, tenant_uuid, tenant_name = auth.authorize(self.vm_uuid, vm_ds, auth.CMD_CREATE, opts)
        self.assertEqual(error_info, "No create privilege" )

        # set "create_volume" privilege to true 
        privileges = [{'datastore': vm_ds,
                        'global_visibility': 0,
                        'create_volume': 1,
                        'delete_volume': 0,
                        'mount_volume': 1,
                        'max_volume_size': 500,
                        'usage_quota': 1000}]

        error_info = tenant1.set_datastore_access_privileges(self.auth_mgr.conn, privileges)
        self.assertEqual(error_info, None)
        error_info, tenant_uuid, tenant_name = auth.authorize(self.vm_uuid, vm_ds, auth.CMD_CREATE, opts)
        self.assertEqual(error_info, None)

        if not error_info:
            error_info = auth.add_volume_to_volumes_table(tenant1.id, vm_ds, "VmdkAuthorizeTestVol1", 100)
            self.assertEqual(error_info, None)

        opts={u'size': u'600MB', u'fstype': u'ext4'}
        error_info, tenant_uuid, tenant_name = auth.authorize(self.vm_uuid, vm_ds, auth.CMD_CREATE, opts)
        # create a volume with 600MB which exceed the"max_volume_size", command should fail
        self.assertEqual(error_info, "volume size exceeds the max volume size limit") 

        opts={u'size': u'500MB', u'fstype': u'ext4'}
        error_info, tenant_uuid, tenant_name = auth.authorize(self.vm_uuid, vm_ds, auth.CMD_CREATE, opts)
        self.assertEqual(error_info, None)

        if not error_info:
            error_info = auth.add_volume_to_volumes_table(tenant1.id, vm_ds, "VmdkAuthorizeTestVol2", 500)
            self.assertEqual(error_info, None)
        
        opts={u'size': u'500MB', u'fstype': u'ext4'}
        error_info, tenant_uuid, tenant_name = auth.authorize(self.vm_uuid, vm_ds, auth.CMD_CREATE, opts)
        self.assertEqual(error_info, "The total volume size exceeds the usage quota")

        # delete volume
        error_info, tenant_uuid, tenant_name = auth.authorize(self.vm_uuid, vm_ds, auth.CMD_REMOVE, opts)
        self.assertEqual(error_info, "No delete privilege")

        privileges = [{'datastore': vm_ds,
                        'global_visibility': 0,
                        'create_volume': 1,
                        'delete_volume': 1,
                        'mount_volume': 1,
                        'max_volume_size': 500,
                        'usage_quota': 1000}]

        error_info = tenant1.set_datastore_access_privileges(self.auth_mgr.conn, privileges)
        self.assertEqual(error_info, None)

        error_info, tenant_uuid, tenant_name = auth.authorize(self.vm_uuid, vm_ds, auth.CMD_REMOVE, opts)
        self.assertEqual(error_info, None)

        # remove the tenant
        error_info = self.auth_mgr.remove_tenant(tenant1.id, False)
        self.assertEqual(error_info, None)
        error_info = self.auth_mgr.remove_volumes_from_volume_table(tenant1.id)
        self.assertEqual(error_info, None)        
    def test_vmdkop_authorize(self):
        vm_ds = 'datastore1'
        vms = [(self.vm_uuid, self.vm_name)]
        privileges = []
        default_datastore='default_ds'
        default_privileges = {'datastore': default_datastore,
                        'global_visibility': 0,
                        'create_volume': 0,
                        'delete_volume': 0,
                        'mount_volume': 0,
                        'max_volume_size': 0,
                        'usage_quota': 0}
                
        error_info, tenant1 = self.auth_mgr.create_tenant('vmdk_auth_test', 'Tenant used to vmdk_auth_test', default_datastore,
                                              default_privileges, vms, privileges)
        self.assertEqual(error_info, None)
        self.assertTrue(uuid.UUID(tenant1.id))

        # test CMD_CREATE without "create_volume" set
        privileges = [{'datastore': vm_ds,
                        'global_visibility': 0,
                        'create_volume': 0,
                        'delete_volume': 0,
                        'mount_volume': 1,
                        'max_volume_size': 500,
                        'usage_quota': 1000}]
        
        error_info = tenant1.set_datastore_access_privileges(self.auth_mgr.conn, privileges)
        self.assertEqual(error_info, None)
        opts={u'size': u'100MB', u'fstype': u'ext4'}
        error_info, tenant_uuid, tenant_name = auth.authorize(self.vm_uuid, vm_ds, auth.CMD_CREATE, opts)
        self.assertEqual(error_info, "No create privilege" )

        # set "create_volume" privilege to true 
        privileges = [{'datastore': vm_ds,
                        'global_visibility': 0,
                        'create_volume': 1,
                        'delete_volume': 0,
                        'mount_volume': 1,
                        'max_volume_size': 500,
                        'usage_quota': 1000}]

        error_info = tenant1.set_datastore_access_privileges(self.auth_mgr.conn, privileges)
        self.assertEqual(error_info, None)
        error_info, tenant_uuid, tenant_name = auth.authorize(self.vm_uuid, vm_ds, auth.CMD_CREATE, opts)
        self.assertEqual(error_info, None)

        if not error_info:
            error_info = auth.add_volume_to_volumes_table(tenant1.id, vm_ds, "VmdkAuthorizeTestVol1", 100)
            self.assertEqual(error_info, None)

        opts={u'size': u'600MB', u'fstype': u'ext4'}
        error_info, tenant_uuid, tenant_name = auth.authorize(self.vm_uuid, vm_ds, auth.CMD_CREATE, opts)
        # create a volume with 600MB which exceed the"max_volume_size", command should fail
        self.assertEqual(error_info, "volume size exceeds the max volume size limit") 

        opts={u'size': u'500MB', u'fstype': u'ext4'}
        error_info, tenant_uuid, tenant_name = auth.authorize(self.vm_uuid, vm_ds, auth.CMD_CREATE, opts)
        self.assertEqual(error_info, None)

        if not error_info:
            error_info = auth.add_volume_to_volumes_table(tenant1.id, vm_ds, "VmdkAuthorizeTestVol2", 500)
            self.assertEqual(error_info, None)
        
        opts={u'size': u'500MB', u'fstype': u'ext4'}
        error_info, tenant_uuid, tenant_name = auth.authorize(self.vm_uuid, vm_ds, auth.CMD_CREATE, opts)
        self.assertEqual(error_info, "The total volume size exceeds the usage quota")

        # delete volume
        error_info, tenant_uuid, tenant_name = auth.authorize(self.vm_uuid, vm_ds, auth.CMD_REMOVE, opts)
        self.assertEqual(error_info, "No delete privilege")

        privileges = [{'datastore': vm_ds,
                        'global_visibility': 0,
                        'create_volume': 1,
                        'delete_volume': 1,
                        'mount_volume': 1,
                        'max_volume_size': 500,
                        'usage_quota': 1000}]

        error_info = tenant1.set_datastore_access_privileges(self.auth_mgr.conn, privileges)
        self.assertEqual(error_info, None)

        error_info, tenant_uuid, tenant_name = auth.authorize(self.vm_uuid, vm_ds, auth.CMD_REMOVE, opts)
        self.assertEqual(error_info, None)

        # remove the tenant
        error_info = self.auth_mgr.remove_tenant(tenant1.id, False)
        self.assertEqual(error_info, None)
        error_info = self.auth_mgr.remove_volumes_from_volume_table(tenant1.id)
        self.assertEqual(error_info, None)