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
Beispiel #2
0
def modify_privileges(privileges, args):
    """ Modify privileges based on CLI argument """
    if args.add_rights:
        set_privileges(args.add_rights, privileges, 1)

    if args.rm_rights:
        set_privileges(args.rm_rights, privileges, 0)

    if args.volume_maxsize:
        size_in_MB = convert.convert_to_MB(args.volume_maxsize)
        privileges[auth_data_const.COL_MAX_VOLUME_SIZE] = size_in_MB

    if args.volume_totalsize:
        size_in_MB = convert.convert_to_MB(args.volume_totalsize)
        privileges[auth_data_const.COL_USAGE_QUOTA] = size_in_MB

    return privileges
def generate_privileges(args):
    """ Generate privileges based on CLI argument """
    privileges = default_privileges()[0]
    privileges[auth_data_const.COL_DATASTORE] = args.datastore
    
    if args.rights:
        set_privileges(args.rights, privileges, 1)
    
    if args.volume_maxsize:
        size_in_MB = convert.convert_to_MB(args.volume_maxsize)
        privileges[auth_data_const.COL_MAX_VOLUME_SIZE] = size_in_MB
    
    if args.volume_totalsize:
        size_in_MB = convert.convert_to_MB(args.volume_totalsize)
        privileges[auth_data_const.COL_USAGE_QUOTA] = size_in_MB
    
    return privileges
Beispiel #4
0
def generate_privileges(args):
    """ Generate privileges based on CLI argument """
    privileges = default_privileges()[0]
    privileges[auth_data_const.COL_DATASTORE] = args.datastore

    if args.rights:
        set_privileges(args.rights, privileges, 1)

    if args.volume_maxsize:
        size_in_MB = convert.convert_to_MB(args.volume_maxsize)
        privileges[auth_data_const.COL_MAX_VOLUME_SIZE] = size_in_MB

    if args.volume_totalsize:
        size_in_MB = convert.convert_to_MB(args.volume_totalsize)
        privileges[auth_data_const.COL_USAGE_QUOTA] = size_in_MB

    return privileges
def modify_privileges(privileges, args):
    """ Modify privileges based on CLI argument """
    if args.add_rights:
        set_privileges(args.add_rights, privileges, 1)
        
    if args.rm_rights:
        set_privileges(args.rm_rights, privileges, 0)

    if args.volume_maxsize:
        size_in_MB = convert.convert_to_MB(args.volume_maxsize)
        privileges[auth_data_const.COL_MAX_VOLUME_SIZE] = size_in_MB
    
    if args.volume_totalsize:
        size_in_MB = convert.convert_to_MB(args.volume_totalsize)
        privileges[auth_data_const.COL_USAGE_QUOTA] = size_in_MB
    
    return privileges
def tenant_access_set(args):
    """ Handle tenant access set command """
    volume_maxsize_in_MB = None
    volume_totalsize_in_MB = None
    if args.volume_maxsize:
        volume_maxsize_in_MB = convert.convert_to_MB(args.volume_maxsize)
    if args.volume_totalsize:
        volume_totalsize_in_MB = convert.convert_to_MB(args.volume_totalsize)

    error_info = auth_api._tenant_access_set(name=args.name,
                                             datastore=args.datastore,
                                             allow_create=args.allow_create,
                                             volume_maxsize_in_MB=volume_maxsize_in_MB,
                                             volume_totalsize_in_MB=volume_totalsize_in_MB)

    if error_info:
        return operation_fail(error_info.msg)
    else:
        print("vm-group access set succeeded")
Beispiel #7
0
def check_usage_quota(opts, tenant_uuid, datastore, privileges):
    """ Check if the volume can be created without violating the quota. """
    if privileges:
        vol_size_in_MB = convert.convert_to_MB(get_vol_size(opts))
        error_info, total_storage_used = get_total_storage_used(tenant_uuid, datastore)
        if error_info:
            # cannot get the total_storage_used, to be safe, return False
            return False
        usage_quota = privileges[auth_data_const.COL_USAGE_QUOTA]
        # if usage_quota which read from DB is 0, which means
        # no usage_quota, function should return True
        if usage_quota == 0:
            return True
        return vol_size_in_MB + total_storage_used <= usage_quota
    else:
        # no privileges
        return True
Beispiel #8
0
def check_usage_quota(opts, tenant_uuid, datastore, privileges):
    """ Check if the volume can be created without violating the quota. """
    if privileges:
        vol_size_in_MB = convert.convert_to_MB(get_vol_size(opts))
        error_info, total_storage_used = get_total_storage_used(tenant_uuid, datastore)
        if error_info:
            # cannot get the total_storage_used, to be safe, return False
            return False
        usage_quota = privileges[auth_data_const.COL_USAGE_QUOTA]
        # if usage_quota which read from DB is 0, which means
        # no usage_quota, function should return True
        if usage_quota == 0:
            return True
        return vol_size_in_MB + total_storage_used <= usage_quota
    else:
        # no privileges
        return True
Beispiel #9
0
def check_max_volume_size(opts, privileges):
    """ Check whether the size of the volume to be created exceeds
        the max volume size specified in the privileges.

    """
    if privileges:
        vol_size_in_MB = convert.convert_to_MB(get_vol_size(opts))
        max_vol_size_in_MB = privileges[auth_data_const.COL_MAX_VOLUME_SIZE]
        logging.debug("vol_size_in_MB=%d max_vol_size_in_MB=%d",
                      vol_size_in_MB, max_vol_size_in_MB)
        # if max_vol_size_in_MB which read from DB is 0, which means
        # no max_vol_size limit, function should return True
        if max_vol_size_in_MB == 0:
            return True
        return vol_size_in_MB <= max_vol_size_in_MB
    else:
        # no privileges
        return True
def check_max_volume_size(opts, privileges):
    """ Check whether the size of the volume to be created exceeds
        the max volume size specified in the privileges.

    """
    if privileges:
        vol_size_in_MB = convert.convert_to_MB(get_vol_size(opts))
        max_vol_size_in_MB = privileges[auth_data_const.COL_MAX_VOLUME_SIZE]
        logging.debug("vol_size_in_MB=%d max_vol_size_in_MB=%d",
                      vol_size_in_MB, max_vol_size_in_MB)
        # if max_vol_size_in_MB which read from DB is 0, which means
        # no max_vol_size limit, function should return True
        if max_vol_size_in_MB == 0:
            return True
        return vol_size_in_MB <= max_vol_size_in_MB
    else:
        # no privileges
        return True
Beispiel #11
0
def check_privileges_for_command(cmd, opts, tenant_uuid, datastore_url,
                                 privileges, vm_datastore_url):
    """
        Check whether the (tenant_uuid, datastore) has the privileges to run
        the given command.

    """
    result = None
    if not privileges:
        result = error_code_to_message[ErrorCode.PRIVILEGE_NO_PRIVILEGE]
        return result

    cmd_need_mount_privilege = [CMD_ATTACH, CMD_DETACH]
    if cmd in cmd_need_mount_privilege:
        if not has_privilege(privileges):
            result = error_code_to_message[
                ErrorCode.PRIVILEGE_NO_MOUNT_PRIVILEGE]
            return result

    if cmd == CMD_CREATE:
        if not has_privilege(privileges, auth_data_const.COL_ALLOW_CREATE):
            result = error_code_to_message[
                ErrorCode.PRIVILEGE_NO_CREATE_PRIVILEGE]
            return result
        vol_size_in_MB = convert.convert_to_MB(get_vol_size(opts))
        if vol_size_in_MB == 0:
            result = error_code_to_message[ErrorCode.OPT_VOLUME_SIZE_INVALID]
            return result
        if not check_max_volume_size(vol_size_in_MB, privileges):
            result = error_code_to_message[ErrorCode.PRIVILEGE_MAX_VOL_EXCEED]
            return result
        if not check_usage_quota(vol_size_in_MB, tenant_uuid, datastore_url,
                                 privileges, vm_datastore_url):
            result = error_code_to_message[
                ErrorCode.PRIVILEGE_USAGE_QUOTA_EXCEED]
            return result

    if cmd == CMD_REMOVE:
        if not has_privilege(privileges, auth_data_const.COL_ALLOW_CREATE):
            result = error_code_to_message[
                ErrorCode.PRIVILEGE_NO_DELETE_PRIVILEGE]
            return result
Beispiel #12
0
def check_privileges_for_command(cmd, opts, tenant_uuid, datastore_url, privileges, vm_datastore_url):
    """
        Check whether the (tenant_uuid, datastore) has the privileges to run
        the given command.

    """
    result = None
    if not privileges:
        result = error_code_to_message[ErrorCode.PRIVILEGE_NO_PRIVILEGE]
        return result

    cmd_need_mount_privilege = [CMD_ATTACH, CMD_DETACH]
    if cmd in cmd_need_mount_privilege:
        if not has_privilege(privileges):
            result = error_code_to_message[ErrorCode.PRIVILEGE_NO_MOUNT_PRIVILEGE]
            return result

    if cmd == CMD_CREATE:
        if not has_privilege(privileges, auth_data_const.COL_ALLOW_CREATE):
            result = error_code_to_message[ErrorCode.PRIVILEGE_NO_CREATE_PRIVILEGE]
            return result
        vol_size_in_MB = convert.convert_to_MB(get_vol_size(opts))
        if vol_size_in_MB == 0:
            result = error_code_to_message[ErrorCode.OPT_VOLUME_SIZE_INVALID]
            return result
        if not check_max_volume_size(vol_size_in_MB, privileges):
            result = error_code_to_message[ErrorCode.PRIVILEGE_MAX_VOL_EXCEED]
            return result
        if not check_usage_quota(vol_size_in_MB, tenant_uuid, datastore_url, privileges, vm_datastore_url):
            result = error_code_to_message[ErrorCode.PRIVILEGE_USAGE_QUOTA_EXCEED]
            return result

    if cmd == CMD_REMOVE:
        if not has_privilege(privileges, auth_data_const.COL_ALLOW_CREATE):
            result = error_code_to_message[ErrorCode.PRIVILEGE_NO_DELETE_PRIVILEGE]
            return result
Beispiel #13
0
    def test_tenant_access(self):
        """ Test AdminCLI command for tenant access management """

        # create tenant1 without adding any vms and privileges
        # the "default_datastore" will be set to "_VM_DS"
        # a full access privilege will be created for tenant1
        error_info, tenant = auth_api._tenant_create(
            name=self.tenant1_name,
            default_datastore=auth_data_const.VM_DS,
            description="Test tenant1",
            vm_list=[self.vm1_name],
            privileges=[])
        self.assertEqual(None, error_info)

        # now, should only have privilege to ""_VM_DS
        error_info, privileges = auth_api._tenant_access_ls(self.tenant1_name)
        _, rows = vmdkops_admin.generate_tenant_access_ls_rows(
            privileges, self.tenant1_name)
        self.assertEqual(1, len(rows))
        expected_output = [auth_data_const.VM_DS, "True", "Unset", "Unset"]
        actual_output = [rows[0][0], rows[0][1], rows[0][2], rows[0][3]]
        self.assertEqual(expected_output, actual_output)

        # remove the privilege to "_VM_DS", which should fail
        # since "_VM_DS still the "default_datastore" for tenant1
        error_info = auth_api._tenant_access_rm(
            name=self.tenant1_name, datastore=auth_data_const.VM_DS)
        self.assertNotEqual(None, error_info)

        # add a access privilege for tenant to self.datastore_name
        # allow_create = False
        # max_volume size = 600MB
        # total_volume size = 1GB
        volume_maxsize_in_MB = convert.convert_to_MB("600MB")
        volume_totalsize_in_MB = convert.convert_to_MB("1GB")
        error_info = auth_api._tenant_access_add(
            name=self.tenant1_name,
            datastore=self.datastore_name,
            allow_create=False,
            volume_maxsize_in_MB=volume_maxsize_in_MB,
            volume_totalsize_in_MB=volume_totalsize_in_MB)
        self.assertEqual(None, error_info)

        # update the "default_datastore" to self.datastore_name
        error_info = auth_api._tenant_update(
            name=self.tenant1_name, default_datastore=self.datastore_name)
        self.assertEqual(None, error_info)

        # try to remove the privilege to "_VM_DS" again, which should not fail
        # since the "default_datastore" for tenant1 is set to self.datastore_name
        error_info = auth_api._tenant_access_rm(
            name=self.tenant1_name, datastore=auth_data_const.VM_DS)
        self.assertEqual(None, error_info)

        error_info, privileges = auth_api._tenant_access_ls(self.tenant1_name)
        self.assertEqual(None, error_info)

        header = vmdkops_admin.tenant_access_ls_headers()
        # There are 4 columns for each row, the name of the columns are
        # "Datastore", "Allow_create", "Max_volume_size", "Total_size"
        # Sample output of a row:
        # ['datastore1', 'False', '600.00MB', '1.00GB']
        _, rows = vmdkops_admin.generate_tenant_access_ls_rows(
            privileges, self.tenant1_name)
        self.assertEqual(len(header), TENANT_ACCESS_LS_EXPECTED_COLUMN_COUNT)

        # tenant aceess privilege should only have a row now
        self.assertEqual(len(rows), 1)

        expected_output = [self.datastore_name, "False", "600.00MB", "1.00GB"]
        actual_output = [rows[0][0], rows[0][1], rows[0][2], rows[0][3]]
        self.assertEqual(expected_output, actual_output)

        # update the access privileges
        # change allow_create to True
        # change max_volume size to 1000MB
        # change total_volume size to 2GB
        volume_maxsize_in_MB = convert.convert_to_MB("1000MB")
        volume_totalsize_in_MB = convert.convert_to_MB("3GB")

        self.parser = vmdkops_admin.create_parser()

        privilege_test_info = [
            ["False", "False"],
            ["FALSE", "False"],
            ["false", "False"],
            ["True", "True"],
            ["TRUE", "True"],
            ["true", "True"],
        ]

        for val in privilege_test_info:
            command = ("vmgroup access set --name={0} ".format(
                self.tenant1_name))
            command += ("--datastore={0} ".format(self.datastore_name))
            command += ("--allow-create={0} ".format(val[0]))
            command += ("--volume-maxsize=500MB --volume-totalsize=1GB")

            args = self.parser.parse_args(command.split())
            error_info = vmdkops_admin.tenant_access_set(args)
            self.assertEqual(None, error_info)

            error_info, privileges = auth_api._tenant_access_ls(
                self.tenant1_name)
            self.assertEqual(None, error_info)

            _, rows = vmdkops_admin.generate_tenant_access_ls_rows(
                privileges, self.tenant1_name)
            self.assertEqual(len(rows), 1)

            expected_output = [
                self.datastore_name, val[1], "500.00MB", "1.00GB"
            ]
            actual_output = [rows[0][0], rows[0][1], rows[0][2], rows[0][3]]
            self.assertEqual(expected_output, actual_output)

        print(
            "[Negative test case]: Expected invalid values for allow-create option"
        )
        for val in ["INVALID", ""]:
            command = ("vmgroup access set --name={0} ".format(
                self.tenant1_name))
            command += ("--datastore={0} ".format(self.datastore_name))
            command += ("--allow-create={0} ".format(val))
            command += ("--volume-maxsize=500MB --volume-totalsize=1GB")

            args = self.parser.parse_args(command.split())
            error_info = vmdkops_admin.tenant_access_set(args)
            expected_message = "Invalid value {0} for allow-create option".format(
                val)
            self.assertEqual(expected_message, error_info)

        if self.datastore1_name:
            # second datastore is available, can test tenant update with  --default_datastore
            error_info, tenant_list = auth_api._tenant_ls()
            self.assertEqual(None, error_info)

            # Two tenants in the list, "_DEFAULT" and "test_tenant1"
            # rows[0] is for "_DEFAULT" tenant, and rows[1] is for "test_tenant1"

            # There are 5 columns for each row, the name of the columns are
            # "Uuid", "Name", "Description", "Default_datastore", "VM_list"
            # Sample output of one row:
            # [u'9e1be0ce-3d58-40f6-a335-d6e267e34baa', u'test_tenant1', u'Test tenant1', '', 'test_vm1']
            _, rows = vmdkops_admin.generate_tenant_ls_rows(tenant_list)

            # get "default_datastore" from the output
            actual_output = rows[1][3]
            expected_output = self.datastore_name
            self.assertEqual(expected_output, actual_output)

            # add access privilege to self.datastore1_name
            volume_maxsize_in_MB = convert.convert_to_MB("600MB")
            volume_totalsize_in_MB = convert.convert_to_MB("1GB")
            error_info = auth_api._tenant_access_add(
                name=self.tenant1_name,
                datastore=self.datastore1_name,
                allow_create=False,
                volume_maxsize_in_MB=volume_maxsize_in_MB,
                volume_totalsize_in_MB=volume_totalsize_in_MB)
            self.assertEqual(None, error_info)

            # update the "default_datastore"
            error_info = auth_api._tenant_update(
                name=self.tenant1_name, default_datastore=self.datastore1_name)
            self.assertEqual(None, error_info)

            error_info, tenant_list = auth_api._tenant_ls()
            self.assertEqual(None, error_info)

            _, rows = vmdkops_admin.generate_tenant_ls_rows(tenant_list)
            # get "default_datastore" from the output
            actual_output = rows[1][3]
            expected_output = self.datastore1_name
            self.assertEqual(expected_output, actual_output)

            # switch the "default_datastore" to self.datastore_name
            error_info = auth_api._tenant_update(
                name=self.tenant1_name, default_datastore=self.datastore_name)
            self.assertEqual(error_info, None)
            # remove the privilege to self.datastore1_name
            error_info = auth_api._tenant_access_rm(
                name=self.tenant1_name, datastore=self.datastore1_name)
            self.assertEqual(error_info, None)

        # remove access privileges, which should fail
        # since the "default_datastore" is set to self.datastore_name
        # cannot remove the privilege
        error_info = auth_api._tenant_access_rm(name=self.tenant1_name,
                                                datastore=self.datastore_name)

        self.assertNotEqual(None, error_info)

        error_info, privileges = auth_api._tenant_access_ls(self.tenant1_name)
        self.assertEqual(None, error_info)

        # now, only have a privilege to self.datastore_name
        _, rows = vmdkops_admin.generate_tenant_access_ls_rows(
            privileges, self.tenant1_name)
        self.assertEqual(1, len(rows))
        expected_output = [self.datastore_name, "True", "500.00MB", "1.00GB"]
        actual_output = [rows[0][0], rows[0][1], rows[0][2], rows[0][3]]
        self.assertEqual(expected_output, actual_output)
    def test_tenant_access(self):
        """ Test AdminCLI command for tenant access management """

        # create tenant1 without adding any vms and privileges
        # the "default_datastore" will be set to "_VM_DS"
        # a full access privilege will be created for tenant1
        error_info, tenant = auth_api._tenant_create(
                                                    name=self.tenant1_name,
                                                    default_datastore=auth_data_const.VM_DS,
                                                    description="Test tenant1",
                                                    vm_list=[self.vm1_name],
                                                    privileges=[])
        self.assertEqual(None, error_info)

        # now, should only have privilege to ""_VM_DS
        error_info, privileges = auth_api._tenant_access_ls(self.tenant1_name)
        _, rows = vmdkops_admin.generate_tenant_access_ls_rows(privileges, self.tenant1_name)
        self.assertEqual(1, len(rows))
        expected_output = [auth_data_const.VM_DS,
                            "True",
                            "Unset",
                            "Unset"]
        actual_output = [rows[0][0],
                         rows[0][1],
                         rows[0][2],
                         rows[0][3]]
        self.assertEqual(expected_output, actual_output)

        # remove the privilege to "_VM_DS", which should fail
        # since "_VM_DS still the "default_datastore" for tenant1
        error_info = auth_api._tenant_access_rm(name=self.tenant1_name,
                                                datastore=auth_data_const.VM_DS
                                                )
        self.assertNotEqual(None, error_info)

        # add a access privilege for tenant to self.datastore_name
        # allow_create = False
        # max_volume size = 600MB
        # total_volume size = 1GB
        volume_maxsize_in_MB = convert.convert_to_MB("600MB")
        volume_totalsize_in_MB = convert.convert_to_MB("1GB")
        error_info = auth_api._tenant_access_add(name=self.tenant1_name,
                                                 datastore=self.datastore_name,
                                                 allow_create=False,
                                                 volume_maxsize_in_MB=volume_maxsize_in_MB,
                                                 volume_totalsize_in_MB=volume_totalsize_in_MB
                                             )
        self.assertEqual(None, error_info)

        # update the "default_datastore" to self.datastore_name
        error_info = auth_api._tenant_update(name=self.tenant1_name,
                                             default_datastore=self.datastore_name)
        self.assertEqual(None, error_info)

        # try to remove the privilege to "_VM_DS" again, which should not fail
        # since the "default_datastore" for tenant1 is set to self.datastore_name
        error_info = auth_api._tenant_access_rm(name=self.tenant1_name,
                                                datastore=auth_data_const.VM_DS
                                                )
        self.assertEqual(None, error_info)

        error_info, privileges = auth_api._tenant_access_ls(self.tenant1_name)
        self.assertEqual(None, error_info)

        header = vmdkops_admin.tenant_access_ls_headers()
        # There are 4 columns for each row, the name of the columns are
        # "Datastore", "Allow_create", "Max_volume_size", "Total_size"
        # Sample output of a row:
        # ['datastore1', 'False', '600.00MB', '1.00GB']
        _, rows = vmdkops_admin.generate_tenant_access_ls_rows(privileges, self.tenant1_name)
        self.assertEqual(len(header), TENANT_ACCESS_LS_EXPECTED_COLUMN_COUNT)

        # tenant aceess privilege should only have a row now
        self.assertEqual(len(rows), 1)

        expected_output = [self.datastore_name,
                           "False",
                           "600.00MB",
                           "1.00GB"]
        actual_output = [rows[0][0],
                         rows[0][1],
                         rows[0][2],
                         rows[0][3]]
        self.assertEqual(expected_output, actual_output)

        # update the access privileges
        # change allow_create to True
        # change max_volume size to 1000MB
        # change total_volume size to 2GB
        volume_maxsize_in_MB = convert.convert_to_MB("1000MB")
        volume_totalsize_in_MB = convert.convert_to_MB("3GB")

        self.parser = vmdkops_admin.create_parser()

        privilege_test_info = [
            ["False", "False"],
            ["FALSE", "False"],
            ["false", "False"],
            ["True", "True"],
            ["TRUE", "True"],
            ["true", "True"],
        ]

        for val in privilege_test_info:
            command = ("vmgroup access set --name={0} ".format(self.tenant1_name))
            command += ("--datastore={0} ".format(self.datastore_name))
            command += ("--allow-create={0} ".format(val[0]))
            command += ("--volume-maxsize=500MB --volume-totalsize=1GB")

            args = self.parser.parse_args(command.split())
            error_info = vmdkops_admin.tenant_access_set(args)
            self.assertEqual(None, error_info)

            error_info, privileges = auth_api._tenant_access_ls(self.tenant1_name)
            self.assertEqual(None, error_info)

            _, rows = vmdkops_admin.generate_tenant_access_ls_rows(privileges, self.tenant1_name)
            self.assertEqual(len(rows), 1)

            expected_output = [self.datastore_name,
                            val[1],
                            "500.00MB",
                            "1.00GB"]
            actual_output = [rows[0][0],
                            rows[0][1],
                            rows[0][2],
                            rows[0][3]]
            self.assertEqual(expected_output, actual_output)

        print("[Negative test case]: Expected invalid values for allow-create option")
        for val in ["INVALID", ""]:
            command = ("vmgroup access set --name={0} ".format(self.tenant1_name))
            command += ("--datastore={0} ".format(self.datastore_name))
            command += ("--allow-create={0} ".format(val))
            command += ("--volume-maxsize=500MB --volume-totalsize=1GB")

            args = self.parser.parse_args(command.split())
            error_info = vmdkops_admin.tenant_access_set(args)
            expected_message = "ERROR:Invalid value {0} for allow-create option".format(val)
            self.assertEqual(expected_message, error_info)

        if self.datastore1_name:
            # second datastore is available, can test tenant update with  --default_datastore
            error_info, tenant_list = auth_api._tenant_ls()
            self.assertEqual(None, error_info)

            # Two tenants in the list, "_DEFAULT" and "test_tenant1"
            # rows[0] is for "_DEFAULT" tenant, and rows[1] is for "test_tenant1"

            # There are 5 columns for each row, the name of the columns are
            # "Uuid", "Name", "Description", "Default_datastore", "VM_list"
            # Sample output of one row:
            # [u'9e1be0ce-3d58-40f6-a335-d6e267e34baa', u'test_tenant1', u'Test tenant1', '', 'test_vm1']
            _, rows = vmdkops_admin.generate_tenant_ls_rows(tenant_list)

            # get "default_datastore" from the output
            actual_output = rows[1][3]
            expected_output = self.datastore_name
            self.assertEqual(expected_output, actual_output)

            # add access privilege to self.datastore1_name
            volume_maxsize_in_MB = convert.convert_to_MB("600MB")
            volume_totalsize_in_MB = convert.convert_to_MB("1GB")
            error_info = auth_api._tenant_access_add(name=self.tenant1_name,
                                                     datastore=self.datastore1_name,
                                                     allow_create=False,
                                                     volume_maxsize_in_MB=volume_maxsize_in_MB,
                                                     volume_totalsize_in_MB=volume_totalsize_in_MB)
            self.assertEqual(None, error_info)

            # update the "default_datastore"
            error_info = auth_api._tenant_update(name=self.tenant1_name,
                                                 default_datastore=self.datastore1_name)
            self.assertEqual(None, error_info)

            error_info, tenant_list = auth_api._tenant_ls()
            self.assertEqual(None, error_info)

            _, rows = vmdkops_admin.generate_tenant_ls_rows(tenant_list)
            # get "default_datastore" from the output
            actual_output = rows[1][3]
            expected_output = self.datastore1_name
            self.assertEqual(expected_output, actual_output)

            # switch the "default_datastore" to self.datastore_name
            error_info = auth_api._tenant_update(name=self.tenant1_name,
                                                 default_datastore=self.datastore_name)
            self.assertEqual(error_info, None)
            # remove the privilege to self.datastore1_name
            error_info = auth_api._tenant_access_rm(name=self.tenant1_name,
                                                    datastore=self.datastore1_name)
            self.assertEqual(error_info, None)

        # remove access privileges, which should fail
        # since the "default_datastore" is set to self.datastore_name
        # cannot remove the privilege
        error_info = auth_api._tenant_access_rm(name=self.tenant1_name,
        datastore=self.datastore_name)

        self.assertNotEqual(None, error_info)

        error_info, privileges = auth_api._tenant_access_ls(self.tenant1_name)
        self.assertEqual(None, error_info)

        # now, only have a privilege to self.datastore_name
        _, rows = vmdkops_admin.generate_tenant_access_ls_rows(privileges, self.tenant1_name)
        self.assertEqual(1, len(rows))
        expected_output = [self.datastore_name,
                            "True",
                            "500.00MB",
                            "1.00GB"]
        actual_output = [rows[0][0],
                         rows[0][1],
                         rows[0][2],
                         rows[0][3]]
        self.assertEqual(expected_output, actual_output)
    def test_tenant_access(self):
        """ Test AdminCLI command for tenant access management """

        # create tenant1 without adding any vms and privileges
        error_info, tenant = auth_api._tenant_create(
                                                    name=self.tenant1_name,
                                                    description="Test tenant1",
                                                    vm_list=[self.vm1_name],
                                                    privileges=[])
        self.assertEqual(None, error_info)

        # add first access privilege for tenant
        # allow_create = False
        # max_volume size = 600MB
        # total_volume size = 1GB
        volume_maxsize_in_MB = convert.convert_to_MB("600MB")
        volume_totalsize_in_MB = convert.convert_to_MB("1GB")
        error_info = auth_api._tenant_access_add(name=self.tenant1_name,
                                                 datastore=self.datastore_name,
                                                 default_datastore=False,
                                                 allow_create=False,
                                                 volume_maxsize_in_MB=volume_maxsize_in_MB,
                                                 volume_totalsize_in_MB=volume_totalsize_in_MB
                                             )
        self.assertEqual(None, error_info)

        error_info, privileges = auth_api._tenant_access_ls(self.tenant1_name)
        self.assertEqual(None, error_info)

        header = vmdkops_admin.tenant_access_ls_headers()
        # There are 4 columns for each row, the name of the columns are
        # "Datastore", "Allow_create", "Max_volume_size", "Total_size"
        # Sample output of a row:
        # ['datastore1', 'False', '600.00MB', '1.00GB']
        rows = vmdkops_admin.generate_tenant_access_ls_rows(privileges)
        self.assertEqual(len(header), TENANT_ACCESS_LS_EXPECTED_COLUMN_COUNT)

        # tenant aceess privilege should only have a row now
        self.assertEqual(len(rows), 1)

        expected_output = [self.datastore_name,
                           "False",
                           "600.00MB",
                           "1.00GB"]
        actual_output = [rows[0][0],
                         rows[0][1],
                         rows[0][2],
                         rows[0][3]]
        self.assertEqual(expected_output, actual_output)

        # update the access privileges
        # change allow_create to True
        # change max_volume size to 1000MB
        # change total_volume size to 2GB
        volume_maxsize_in_MB = convert.convert_to_MB("1000MB")
        volume_totalsize_in_MB = convert.convert_to_MB("3GB")
        error_info = auth_api._tenant_access_set(name=self.tenant1_name,
                                                 datastore=self.datastore_name,
                                                 allow_create="True",
                                                 volume_maxsize_in_MB=volume_maxsize_in_MB,
                                                 volume_totalsize_in_MB=volume_totalsize_in_MB
                                             )
        self.assertEqual(None, error_info)

        error_info, privileges = auth_api._tenant_access_ls(self.tenant1_name)
        self.assertEqual(None, error_info)

        rows = vmdkops_admin.generate_tenant_access_ls_rows(privileges)
        self.assertEqual(len(rows), 1)


        expected_output = [self.datastore_name,
                           "True",
                           "1000.00MB",
                           "3.00GB"]
        actual_output = [rows[0][0],
                         rows[0][1],
                         rows[0][2],
                         rows[0][3]]
        self.assertEqual(expected_output, actual_output)

        if self.datastore1_name:
            # second datastore is available, can test tenant access add with --default_datastore
            error_info, tenant_list = auth_api._tenant_ls()
            self.assertEqual(None, error_info)

            # Two tenants in the list, "_DEFAULT" and "test_tenant1"
            # rows[0] is for "_DEFAULT" tenant, and rows[1] is for "test_tenant1"

            # There are 5 columns for each row, the name of the columns are
            # "Uuid", "Name", "Description", "Default_datastore", "VM_list"
            # Sample output of one row:
            # [u'9e1be0ce-3d58-40f6-a335-d6e267e34baa', u'test_tenant1', u'Test tenant1', '', 'test_vm1']
            rows = vmdkops_admin.generate_tenant_ls_rows(tenant_list)

            # get "default_datastore" from the output
            actual_output = rows[1][3]
            expected_output = self.datastore_name
            self.assertEqual(expected_output, actual_output)

            # add second access privilege for tenant
            # allow_create = False
            # max_volume size = 600MB
            # total_volume size = 1GB
            volume_maxsize_in_MB = convert.convert_to_MB("600MB")
            volume_totalsize_in_MB = convert.convert_to_MB("1GB")
            error_info = auth_api._tenant_access_add(name=self.tenant1_name,
                                                    datastore=self.datastore1_name,
                                                    default_datastore=True,
                                                    allow_create=False,
                                                    volume_maxsize_in_MB=volume_maxsize_in_MB,
                                                    volume_totalsize_in_MB=volume_totalsize_in_MB
                                                )
            self.assertEqual(None, error_info)

            error_info, tenant_list = auth_api._tenant_ls()
            self.assertEqual(None, error_info)


            rows = vmdkops_admin.generate_tenant_ls_rows(tenant_list)
            # get "default_datastore" from the output
            actual_output = rows[1][3]
            expected_output = self.datastore1_name
            self.assertEqual(expected_output, actual_output)

            error_info = auth_api._tenant_access_rm(name=self.tenant1_name,
                                                    datastore=self.datastore1_name)
            self.assertEqual(error_info, None)

        # remove access privileges
        error_info = auth_api._tenant_access_rm(name=self.tenant1_name,
        datastore=self.datastore_name)

        self.assertEqual(None, error_info)

        error_info, privileges = auth_api._tenant_access_ls(self.tenant1_name)
        self.assertEqual(None, error_info)

        rows = vmdkops_admin.generate_tenant_access_ls_rows(privileges)

        # no tenant access privilege available for this tenant
        self.assertEqual(rows, [])