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
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)