Skip to content
Snippets Groups Projects
Commit f785bbf9 authored by Josef Smrčka's avatar Josef Smrčka
Browse files

feat: log projects quotas comparison

Log quotas comparison of source and destination project.

Output a separate log line for each quota based on comparison result:
- `debug` if src_quota == dst_quota
- `warn` if src_quota < dst_quota
- `error` if src_quota > dst_quota

Compare only a predefined set of quotas.

See https://gitlab.ics.muni.cz/cloud/internal-wiki/-/issues/1656.
parent 14f1e1e2
Branches
Tags
1 merge request!21feat: log projects quotas comparison, fix: source server keypair - control flow
...@@ -748,3 +748,92 @@ def get_server_floating_ip_properties(server): ...@@ -748,3 +748,92 @@ def get_server_floating_ip_properties(server):
return {} return {}
def compare_and_log_projects_quotas(args, log_prefix, src_connection, src_project_id, dst_connection, dst_project_id):
""" Log quotas comparison for 2 projects. """
src_quotas = get_project_quotas(src_connection, src_project_id)
dst_quotas = get_project_quotas(dst_connection, dst_project_id)
quota_comparison_dict = {
0: {"logger": args.logger.info, "comment": "Source and destination project quota equal"},
1: {"logger": args.logger.error, "comment": "Source project quota higher"},
-1: {"logger": args.logger.warn, "comment": "Destination project quota higher"},
}
for i_quota_resource, i_src_quota in src_quotas.items():
dst_quota = dst_quotas[i_quota_resource]
comparison_result = compare_quota_values(i_src_quota, dst_quota)
logger_function = quota_comparison_dict[comparison_result]["logger"]
comment = quota_comparison_dict[comparison_result]["comment"]
logger_function(f"{log_prefix} {comment}: {i_quota_resource}, src: {i_src_quota}, dst: {dst_quota}")
# Define sets of names of quotas which we want to check explicitly,
# in order to avoid dealing with irrelevant QuotaSet / Quota properties.
quota_resources_compute = [
"cores",
"fixed_ips",
"injected_file_content_bytes",
"injected_file_path_bytes",
"injected_files",
"instances",
"key_pairs",
"metadata_items",
"ram",
"server_group_members",
"server_groups",
]
quota_resources_volume = [
"backup_gigabytes",
"backups",
"gigabytes",
"groups",
"per_volume_gigabytes",
"snapshots",
"volumes",
]
quota_resources_network = [
"floating_ips",
"networks",
"ports",
"rbac_policies",
"routers",
"security_group_rules",
"security_groups",
"subnet_pools",
"subnets",
]
def get_project_quotas(ostack_connection: openstack.connection.Connection, project_id):
""" Return all quotas (compute, volume, network) for given project. """
compute_quotas = ostack_connection.get_compute_quotas(project_id)
volume_quotas = ostack_connection.get_volume_quotas(project_id)
network_quotas = ostack_connection.get_network_quotas(project_id)
project_quotas = {}
project_quotas |= filter_quota_set(quota_resources_compute, compute_quotas)
project_quotas |= filter_quota_set(quota_resources_volume, volume_quotas)
project_quotas |= filter_quota_set(quota_resources_network, network_quotas)
return project_quotas
def filter_quota_set(quota_resources, quotas):
""" Return a dictionary of quotas filtered by keys in quota_resources """
return {i_quota_resource: quotas[i_quota_resource] for i_quota_resource in quota_resources}
def compare_quota_values(value_1, value_2):
"""
Return integer representation of comparison of parameters:
value_1 == value_2: return 0
value_1 > value_2: return 1
value_1 < value_2: return -1
Treats `None` and `-1` values as unlimited, i.e. always bigger than any other limited value.
"""
# treat None as unlimited quota, i.e. -1
val_1 = -1 if value_1 is None else value_1
val_2 = -1 if value_2 is None else value_2
if val_1 == val_2:
return 0
if val_1 > val_2 or val_1 == -1:
return 1
if val_1 < val_2 or val_2 == -1:
return -1
...@@ -72,17 +72,11 @@ def main(args): ...@@ -72,17 +72,11 @@ def main(args):
"B.14 Cloud group project migration is executed by authorized person (cloud/openstack team member).", "B.14 Cloud group project migration is executed by authorized person (cloud/openstack team member).",
lib.executed_as_admin_user_in_ci()) lib.executed_as_admin_user_in_ci())
# check user context switching & quotas
source_project_conn = lib.get_ostack_connection(source_migrator_openrc | {'OS_PROJECT_NAME': source_project.name}) source_project_conn = lib.get_ostack_connection(source_migrator_openrc | {'OS_PROJECT_NAME': source_project.name})
#source_project_quotas = source_project_conn.get_compute_quotas(source_project.id)
#lib.log_or_assert(args, f"C.1 Context switching to source OpenStack cloud project succeeded (id:{source_project.id})",
# source_project_quotas and source_project_quotas.id == source_project.id)
destination_project_conn = lib.get_ostack_connection(destination_migrator_openrc | {'OS_PROJECT_NAME': destination_project.name}) destination_project_conn = lib.get_ostack_connection(destination_migrator_openrc | {'OS_PROJECT_NAME': destination_project.name})
#destination_project_quotas = destination_project_conn.get_compute_quotas(destination_project.id)
#lib.log_or_assert(args, f"C.2 Context switching to destination OpenStack cloud project succeeded (id:{destination_project.id})", args.logger.info(f"C.01 Source and destination project quotas comparison:")
# destination_project_quotas and destination_project_quotas.id == destination_project.id) olib.compare_and_log_projects_quotas(args, "C.01", source_project_conn, source_project.id, destination_project_conn, destination_project.id)
# connect to migrator node # connect to migrator node
reply_stdout, reply_stderr, reply_ecode = lib.remote_cmd_exec(args.ceph_migrator_host, args.ceph_migrator_user, reply_stdout, reply_stderr, reply_ecode = lib.remote_cmd_exec(args.ceph_migrator_host, args.ceph_migrator_user,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment