Reformat everything.

This commit is contained in:
Felix Fontein
2025-11-01 12:08:41 +01:00
parent 3f2213791a
commit 340ff8586d
1008 changed files with 61301 additions and 58309 deletions

View File

@@ -177,42 +177,34 @@ else:
def run_module():
"""run ansible module"""
module_args = dict(
host=dict(type='str', default='localhost'),
port=dict(type='int', default=3000),
connect_timeout=dict(type='int', default=1000),
consecutive_good_checks=dict(type='int', default=3),
sleep_between_checks=dict(type='int', default=60),
tries_limit=dict(type='int', default=300),
local_only=dict(type='bool', required=True),
min_cluster_size=dict(type='int', default=1),
target_cluster_size=dict(type='int'),
fail_on_cluster_change=dict(type='bool', default=True),
migrate_tx_key=dict(type='str', no_log=False,
default="migrate_tx_partitions_remaining"),
migrate_rx_key=dict(type='str', no_log=False,
default="migrate_rx_partitions_remaining")
host=dict(type="str", default="localhost"),
port=dict(type="int", default=3000),
connect_timeout=dict(type="int", default=1000),
consecutive_good_checks=dict(type="int", default=3),
sleep_between_checks=dict(type="int", default=60),
tries_limit=dict(type="int", default=300),
local_only=dict(type="bool", required=True),
min_cluster_size=dict(type="int", default=1),
target_cluster_size=dict(type="int"),
fail_on_cluster_change=dict(type="bool", default=True),
migrate_tx_key=dict(type="str", no_log=False, default="migrate_tx_partitions_remaining"),
migrate_rx_key=dict(type="str", no_log=False, default="migrate_rx_partitions_remaining"),
)
result = dict(
changed=False,
)
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True
)
module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
if not LIB_FOUND:
module.fail_json(msg=missing_required_lib('aerospike'),
exception=LIB_FOUND_ERR)
module.fail_json(msg=missing_required_lib("aerospike"), exception=LIB_FOUND_ERR)
try:
if module.check_mode:
has_migrations, skip_reason = False, None
else:
migrations = Migrations(module)
has_migrations, skip_reason = migrations.has_migs(
module.params['local_only']
)
has_migrations, skip_reason = migrations.has_migs(module.params["local_only"])
if has_migrations:
module.fail_json(msg="Failed.", skip_reason=skip_reason)
@@ -223,7 +215,7 @@ def run_module():
class Migrations:
""" Check or wait for migrations between nodes """
"""Check or wait for migrations between nodes"""
def __init__(self, module):
self.module = module
@@ -236,25 +228,20 @@ class Migrations:
self._update_cluster_namespace_list()
self._build_list = set()
self._update_build_list()
self._start_cluster_key = \
self._cluster_statistics[self._nodes[0]]['cluster_key']
self._start_cluster_key = self._cluster_statistics[self._nodes[0]]["cluster_key"]
def _create_client(self):
""" TODO: add support for auth, tls, and other special features
I won't use those features, so I'll wait until somebody complains
or does it for me (Cross fingers)
create the client object"""
"""TODO: add support for auth, tls, and other special features
I won't use those features, so I'll wait until somebody complains
or does it for me (Cross fingers)
create the client object"""
config = {
'hosts': [
(self.module.params['host'], self.module.params['port'])
],
'policies': {
'timeout': self.module.params['connect_timeout']
}
"hosts": [(self.module.params["host"], self.module.params["port"])],
"policies": {"timeout": self.module.params["connect_timeout"]},
}
return aerospike.client(config)
def _info_cmd_helper(self, cmd, node=None, delimiter=';'):
def _info_cmd_helper(self, cmd, node=None, delimiter=";"):
"""delimiter is for separate stats that come back, NOT for kv
separation which is ="""
if node is None: # If no node passed, use the first one (local)
@@ -262,9 +249,7 @@ class Migrations:
data = self._client.info_node(cmd, node)
data = data.split("\t")
if len(data) != 1 and len(data) != 2:
self.module.fail_json(
msg=f"Unexpected number of values returned in info command: {len(data)}"
)
self.module.fail_json(msg=f"Unexpected number of values returned in info command: {len(data)}")
# data will be in format 'command\touput'
data = data[-1]
data = data.rstrip("\n\r")
@@ -272,10 +257,8 @@ class Migrations:
# some commands don't return in kv format
# so we dont want a dict from those.
if '=' in data:
retval = dict(
metric.split("=", 1) for metric in data_arr
)
if "=" in data:
retval = dict(metric.split("=", 1) for metric in data_arr)
else:
# if only 1 element found, and not kv, return just the value.
if len(data_arr) == 1:
@@ -289,7 +272,7 @@ class Migrations:
of build versions."""
self._build_list = set()
for node in self._nodes:
build = self._info_cmd_helper('build', node)
build = self._info_cmd_helper("build", node)
self._build_list.add(build)
# just checks to see if the version is 4.3 or greater
@@ -297,26 +280,25 @@ class Migrations:
# if version <4.3 we can't use cluster-stable info cmd
# regex hack to check for versions beginning with 0-3 or
# beginning with 4.0,4.1,4.2
if re.search(R'^([0-3]\.|4\.[0-2])', min(self._build_list)):
if re.search(R"^([0-3]\.|4\.[0-2])", min(self._build_list)):
return False
return True
def _update_cluster_namespace_list(self):
""" make a unique list of namespaces
"""make a unique list of namespaces
TODO: does this work on a rolling namespace add/deletion?
thankfully if it doesn't, we dont need this on builds >=4.3"""
self._namespaces = set()
for node in self._nodes:
namespaces = self._info_cmd_helper('namespaces', node)
namespaces = self._info_cmd_helper("namespaces", node)
for namespace in namespaces:
self._namespaces.add(namespace)
def _update_cluster_statistics(self):
"""create a dict of nodes with their related stats """
"""create a dict of nodes with their related stats"""
self._cluster_statistics = {}
for node in self._nodes:
self._cluster_statistics[node] = \
self._info_cmd_helper('statistics', node)
self._cluster_statistics[node] = self._info_cmd_helper("statistics", node)
def _update_nodes_list(self):
"""get a fresh list of all the nodes"""
@@ -330,10 +312,8 @@ class Migrations:
If no node passed, uses the local node or the first one in the list"""
namespace_stats = self._info_cmd_helper(f"namespace/{namespace}", node)
try:
namespace_tx = \
int(namespace_stats[self.module.params['migrate_tx_key']])
namespace_rx = \
int(namespace_stats[self.module.params['migrate_rx_key']])
namespace_tx = int(namespace_stats[self.module.params["migrate_tx_key"]])
namespace_rx = int(namespace_stats[self.module.params["migrate_rx_key"]])
except KeyError:
self.module.fail_json(
msg=(
@@ -342,9 +322,7 @@ class Migrations:
)
)
except TypeError:
self.module.fail_json(
msg="namespace stat returned was not numerical"
)
self.module.fail_json(msg="namespace stat returned was not numerical")
return namespace_tx != 0 or namespace_rx != 0
def _node_has_migs(self, node=None):
@@ -363,22 +341,20 @@ class Migrations:
with the key being the cluster key."""
cluster_keys = {}
for node in self._nodes:
cluster_key = self._cluster_statistics[node][
'cluster_key']
cluster_key = self._cluster_statistics[node]["cluster_key"]
if cluster_key not in cluster_keys:
cluster_keys[cluster_key] = 1
else:
cluster_keys[cluster_key] += 1
if len(cluster_keys.keys()) == 1 and \
self._start_cluster_key in cluster_keys:
if len(cluster_keys.keys()) == 1 and self._start_cluster_key in cluster_keys:
return True
return False
def _cluster_migrates_allowed(self):
"""ensure all nodes have 'migrate_allowed' in their stats output"""
for node in self._nodes:
node_stats = self._info_cmd_helper('statistics', node)
allowed = node_stats['migrate_allowed']
node_stats = self._info_cmd_helper("statistics", node)
allowed = node_stats["migrate_allowed"]
if allowed == "false":
return False
return True
@@ -406,11 +382,11 @@ class Migrations:
minimum cluster size specified in their statistics output"""
sizes = set()
for node in self._cluster_statistics:
sizes.add(int(self._cluster_statistics[node]['cluster_size']))
sizes.add(int(self._cluster_statistics[node]["cluster_size"]))
if (len(sizes)) > 1: # if we are getting more than 1 size, lets say no
return False
if (min(sizes)) >= self.module.params['min_cluster_size']:
if (min(sizes)) >= self.module.params["min_cluster_size"]:
return True
return False
@@ -425,16 +401,16 @@ class Migrations:
the target node's migrations counts must be zero for the provided
'namespace' or all namespaces if 'namespace' is not provided."""
cluster_key = set()
cluster_key.add(self._info_cmd_helper('statistics')['cluster_key'])
cluster_key.add(self._info_cmd_helper("statistics")["cluster_key"])
cmd = "cluster-stable:"
target_cluster_size = self.module.params['target_cluster_size']
target_cluster_size = self.module.params["target_cluster_size"]
if target_cluster_size is not None:
cmd = f"{cmd}size={target_cluster_size};"
for node in self._nodes:
try:
cluster_key.add(self._info_cmd_helper(cmd, node))
except aerospike.exception.ServerError as e: # unstable-cluster is returned in form of Exception
if 'unstable-cluster' in e.msg:
if "unstable-cluster" in e.msg:
return False
raise e
if len(cluster_key) == 1:
@@ -458,11 +434,9 @@ class Migrations:
consecutive_good = 0
try_num = 0
skip_reason = list()
while \
try_num < int(self.module.params['tries_limit']) and \
consecutive_good < \
int(self.module.params['consecutive_good_checks']):
while try_num < int(self.module.params["tries_limit"]) and consecutive_good < int(
self.module.params["consecutive_good_checks"]
):
self._update_nodes_list()
self._update_cluster_statistics()
@@ -470,33 +444,26 @@ class Migrations:
# we probably want to skip & sleep instead of failing entirely
stable, reason = self._cluster_good_state()
if stable is not True:
skip_reason.append(
f"Skipping on try#{try_num} for reason:{reason}"
)
skip_reason.append(f"Skipping on try#{try_num} for reason:{reason}")
else:
if self._can_use_cluster_stable():
if self._cluster_stable():
consecutive_good += 1
else:
consecutive_good = 0
skip_reason.append(
f"Skipping on try#{try_num} for reason: cluster_stable"
)
skip_reason.append(f"Skipping on try#{try_num} for reason: cluster_stable")
elif self._has_migs(local):
# print("_has_migs")
skip_reason.append(
f"Skipping on try#{try_num} for reason: migrations"
)
skip_reason.append(f"Skipping on try#{try_num} for reason: migrations")
consecutive_good = 0
else:
consecutive_good += 1
if consecutive_good == self.module.params[
'consecutive_good_checks']:
if consecutive_good == self.module.params["consecutive_good_checks"]:
break
try_num += 1
sleep(self.module.params['sleep_between_checks'])
sleep(self.module.params["sleep_between_checks"])
# print(skip_reason)
if consecutive_good == self.module.params['consecutive_good_checks']:
if consecutive_good == self.module.params["consecutive_good_checks"]:
return False, None
return True, skip_reason
@@ -506,5 +473,5 @@ def main():
run_module()
if __name__ == '__main__':
if __name__ == "__main__":
main()