def _tenant_access_set(name,
                       datastore,
                       allow_create=None,
                       volume_maxsize_in_MB=None,
                       volume_totalsize_in_MB=None):
    """ API to modify datastore access for a tenant """
    logging.debug(
        "_tenant_access_set: name=%s datastore=%s, allow_create=%s "
        "volume_maxsize(MB)=%s volume_totalsize(MB)=%s", name, datastore,
        allow_create, volume_maxsize_in_MB, volume_totalsize_in_MB)

    error_info, tenant = get_tenant_from_db(name)
    if error_info:
        return error_info

    if not tenant:
        error_info = generate_error_info(ErrorCode.TENANT_NOT_EXIST, name)
        return error_info

    error_info = check_datastore(datastore)
    if error_info:
        return error_info

    error_info = check_usage_quota(datastore, volume_totalsize_in_MB)
    if error_info:
        return error_info

    datastore_url = vmdk_utils.get_datastore_url(datastore)

    error_info, existing_privileges = _tenant_access_ls(name)
    if error_info:
        return error_info

    if not privilege_exist(existing_privileges, datastore_url):
        error_info = generate_error_info(ErrorCode.PRIVILEGE_NOT_FOUND, name,
                                         datastore)
        return error_info

    logging.debug("_tenant_access_set: datastore_url=%s", datastore_url)
    privileges = [
        d for d in tenant.privileges if d.datastore_url == datastore_url
    ]

    if not privileges:
        err_code = ErrorCode.PRIVILEGE_NOT_FOUND
        err_msg = error_code_to_message[err_code].format(name, datastore)
        error_info = ErrorInfo(err_code, err_msg)
        return error_info

    if allow_create is not None:
        allow_create_val, valid = validate_string_to_bool(allow_create)

        if not valid:
            err_code = ErrorCode.PRIVILEGE_INVALID_ALLOW_CREATE_VALUE
            err_msg = error_code_to_message[err_code].format(allow_create)
            logging.error(err_msg)
            return ErrorInfo(err_code, err_msg)

        allow_create = allow_create_val

    privileges_dict = generate_privileges_dict(privileges[0])
    logging.debug("_tenant_access_set: originial privileges_dict=%s",
                  privileges_dict)
    privileges_dict = modify_privileges(
        privileges=privileges_dict,
        allow_create=allow_create,
        volume_maxsize_in_MB=volume_maxsize_in_MB,
        volume_totalsize_in_MB=volume_totalsize_in_MB)
    logging.debug("_tenant_access_set: modified privileges_dict=%s",
                  privileges_dict)

    error_info = check_privilege_parameters(privilege=privileges_dict)
    if error_info:
        return error_info

    error_info, auth_mgr = get_auth_mgr_object()

    if error_info:
        return error_info

    error_msg = tenant.set_datastore_access_privileges(auth_mgr.conn,
                                                       [privileges_dict])
    if error_msg:
        error_info = generate_error_info(ErrorCode.INTERNAL_ERROR, error_msg)
    return error_info
def _tenant_access_add(name,
                       datastore,
                       allow_create=None,
                       volume_maxsize_in_MB=None,
                       volume_totalsize_in_MB=None):
    """ API to add datastore access for a tenant """

    logging.debug(
        "_tenant_access_add: name=%s datastore=%s, allow_create=%s "
        "volume_maxsize(MB)=%s volume_totalsize(MB)=%s", name, datastore,
        allow_create, volume_maxsize_in_MB, volume_totalsize_in_MB)

    error_info, tenant = get_tenant_from_db(name)
    if error_info:
        return error_info

    if not tenant:
        error_info = generate_error_info(ErrorCode.TENANT_NOT_EXIST, name)
        return error_info

    error_info = check_datastore(datastore)
    if error_info:
        return error_info

    error_info = check_usage_quota(datastore, volume_totalsize_in_MB)
    if error_info:
        return error_info

    datastore_url = vmdk_utils.get_datastore_url(datastore)

    error_info, existing_privileges = _tenant_access_ls(name)
    if error_info:
        return error_info

    if privilege_exist(existing_privileges, datastore_url):
        error_info = generate_error_info(ErrorCode.PRIVILEGE_ALREADY_EXIST,
                                         name, datastore)
        return error_info

    # Possible value:
    # None -  no change required
    # True/False (boolean or string) - change to corresponding True/False
    if allow_create is not None:
        # validate to boolean value if it is a string
        allow_create_val, valid = validate_string_to_bool(allow_create)

        if not valid:
            err_code = ErrorCode.PRIVILEGE_INVALID_ALLOW_CREATE_VALUE
            err_msg = error_code_to_message[err_code].format(allow_create)
            logging.error(err_msg)
            return ErrorInfo(err_code, err_msg)

        allow_create = allow_create_val

    privileges = generate_privileges(
        datastore_url=datastore_url,
        allow_create=allow_create,
        volume_maxsize_in_MB=volume_maxsize_in_MB,
        volume_totalsize_in_MB=volume_totalsize_in_MB)
    logging.debug("_tenant_access_add: privileges=%s", privileges)

    error_info = check_privilege_parameters(privilege=privileges)
    if error_info:
        return error_info

    error_info, auth_mgr = get_auth_mgr_object()
    if error_info:
        return error_info

    error_msg = tenant.set_datastore_access_privileges(auth_mgr.conn,
                                                       [privileges])
    if error_msg:
        error_info = generate_error_info(ErrorCode.INTERNAL_ERROR, error_msg)
        return error_info

    return error_info
def _tenant_access_add(name, datastore, allow_create=None, default_datastore=False,
                       volume_maxsize_in_MB=None, volume_totalsize_in_MB=None):
    """ API to add datastore access for a tenant """

    logging.debug("_tenant_access_add: name=%s datastore=%s, allow_create=%s "
                  "volume_maxsize_in_MB=%s volume_totalsize_in_MB=%s", name, datastore, allow_create,
                  volume_maxsize_in_MB, volume_totalsize_in_MB)

    error_info, tenant = get_tenant_from_db(name)
    if error_info:
        return error_info

    if not tenant:
        error_info = error_code.generate_error_info(ErrorCode.TENANT_NOT_EXIST, name)
        return error_info

    error_info = check_datastore(datastore)
    if error_info:
        return error_info

    datastore_url = vmdk_utils.get_datastore_url(datastore)

    error_info, existing_privileges = _tenant_access_ls(name)
    if error_info:
        return error_info

    if privilege_exist(existing_privileges, datastore_url):
        error_info = error_code.generate_error_info(ErrorCode.PRIVILEGE_ALREADY_EXIST, name, datastore)
        return error_info

    # Possible value:
    # None -  no change required
    # True/False (boolean or string) - change to corresponding True/False
    if allow_create is not None:
        # validate to boolean value if it is a string
        allow_create_val, valid = validate_string_to_bool(allow_create)

        if not valid:
            err_code = ErrorCode.PRIVILEGE_INVALID_ALLOW_CREATE_VALUE
            err_msg = error_code.error_code_to_message[err_code].format(allow_create)
            logging.error(err_msg)
            return ErrorInfo(err_code, err_msg)

        allow_create = allow_create_val

    privileges = generate_privileges(datastore_url=datastore_url,
                                     allow_create=allow_create,
                                     volume_maxsize_in_MB=volume_maxsize_in_MB,
                                     volume_totalsize_in_MB=volume_totalsize_in_MB)
    logging.debug("_tenant_access_add: privileges=%s", privileges)

    error_info = check_privilege_parameters(privilege=privileges)
    if error_info:
        return error_info

    error_info, auth_mgr = get_auth_mgr_object()

    if error_info:
        return error_info

    error_msg = tenant.set_datastore_access_privileges(auth_mgr.conn, [privileges])
    if error_msg:
        error_info = error_code.generate_error_info(ErrorCode.INTERNAL_ERROR, error_msg)
        return error_info

    error_msg, result = auth.get_row_from_privileges_table(auth_mgr.conn, tenant.id)
    # if len(result) == 1, which means "datastore"" is the first datastore for this tenant,
    # and should set this datastore to the "default_datastore" for this tenant
    if error_msg:
        error_info = error_code.generate_error_info(ErrorCode.INTERNAL_ERROR, error_msg)
        return error_info
    logging.debug("_tenant_access_add: get_row_from_privileges_table for tenant id=%s return %s",
                  tenant.id, result)

    if len(result) == 1 or default_datastore:
        if datastore_url == auth_data_const.DEFAULT_DS_URL:
            # Create DEFAULT privilege for DEFAULT tenant, should not set the default_datastore in DB
            error_msg = tenant.set_default_datastore(auth_mgr.conn, "")
        else:
            error_msg = tenant.set_default_datastore(auth_mgr.conn, datastore_url)
        if error_msg:
            error_info = error_code.generate_error_info(ErrorCode.INTERNAL_ERROR, error_msg)

    return error_info