From b0cdfe7625bc2f185b3ec05b37d13b544978f947 Mon Sep 17 00:00:00 2001 From: Jeff Bradberry Date: Thu, 15 Apr 2021 14:15:30 -0400 Subject: [PATCH] Clean up the management commands --- .../commands/generate_isolated_key.py | 38 --------------- .../management/commands/list_instances.py | 7 +-- .../management/commands/provision_instance.py | 14 ++---- .../management/commands/register_queue.py | 31 ++---------- .../management/commands/run_wsbroadcast.py | 1 + .../commands/test_isolated_connection.py | 47 ------------------- awx/main/managers.py | 2 +- awx/main/wsbroadcast.py | 1 + 8 files changed, 12 insertions(+), 129 deletions(-) delete mode 100644 awx/main/management/commands/generate_isolated_key.py delete mode 100644 awx/main/management/commands/test_isolated_connection.py diff --git a/awx/main/management/commands/generate_isolated_key.py b/awx/main/management/commands/generate_isolated_key.py deleted file mode 100644 index 51112ea3d7..0000000000 --- a/awx/main/management/commands/generate_isolated_key.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2015 Ansible, Inc. -# All Rights Reserved -import datetime -from django.utils.encoding import smart_str - -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives import serialization -from cryptography.hazmat.primitives.asymmetric import rsa -from django.conf import settings -from django.core.management.base import BaseCommand - -from awx.conf.models import Setting - - -class Command(BaseCommand): - """Generate and store a randomized RSA key for SSH traffic to isolated instances""" - - help = 'Generates and stores a randomized RSA key for SSH traffic to isolated instances' - - def handle(self, *args, **kwargs): - if getattr(settings, 'AWX_ISOLATED_PRIVATE_KEY', False): - print(settings.AWX_ISOLATED_PUBLIC_KEY) - return - - key = rsa.generate_private_key(public_exponent=65537, key_size=4096, backend=default_backend()) - Setting.objects.create( - key='AWX_ISOLATED_PRIVATE_KEY', - value=key.private_bytes( - encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption() - ), - ).save() - pemfile = Setting.objects.create( - key='AWX_ISOLATED_PUBLIC_KEY', - value=smart_str(key.public_key().public_bytes(encoding=serialization.Encoding.OpenSSH, format=serialization.PublicFormat.OpenSSH)) - + " generated-by-awx@%s" % datetime.datetime.utcnow().isoformat(), - ) - pemfile.save() - print(pemfile.value) diff --git a/awx/main/management/commands/list_instances.py b/awx/main/management/commands/list_instances.py index 95807cb5a9..473f0e379e 100644 --- a/awx/main/management/commands/list_instances.py +++ b/awx/main/management/commands/list_instances.py @@ -10,7 +10,6 @@ class Ungrouped(object): name = 'ungrouped' policy_instance_percentage = None policy_instance_minimum = None - controller = None @property def instances(self): @@ -18,7 +17,7 @@ class Ungrouped(object): @property def capacity(self): - return sum([x.capacity for x in self.instances]) + return sum(x.capacity for x in self.instances) class Command(BaseCommand): @@ -38,8 +37,6 @@ class Command(BaseCommand): fmt += ' policy={0.policy_instance_percentage}%' if instance_group.policy_instance_minimum: fmt += ' policy>={0.policy_instance_minimum}' - if instance_group.controller: - fmt += ' controller={0.controller.name}' print((fmt + ']').format(instance_group)) for x in instance_group.instances.all(): color = '\033[92m' @@ -48,8 +45,6 @@ class Command(BaseCommand): if x.enabled is False: color = '\033[90m[DISABLED] ' fmt = '\t' + color + '{0.hostname} capacity={0.capacity} version={1}' - if x.last_isolated_check: - fmt += ' last_isolated_check="{0.last_isolated_check:%Y-%m-%d %H:%M:%S}"' if x.capacity: fmt += ' heartbeat="{0.modified:%Y-%m-%d %H:%M:%S}"' print((fmt + '\033[0m').format(x, x.version or '?')) diff --git a/awx/main/management/commands/provision_instance.py b/awx/main/management/commands/provision_instance.py index 02435ee167..06ca4470ac 100644 --- a/awx/main/management/commands/provision_instance.py +++ b/awx/main/management/commands/provision_instance.py @@ -1,13 +1,11 @@ # Copyright (c) 2015 Ansible, Inc. # All Rights Reserved -from uuid import uuid4 +from django.conf import settings +from django.core.management.base import BaseCommand, CommandError +from django.db import transaction from awx.main.models import Instance -from django.conf import settings - -from django.db import transaction -from django.core.management.base import BaseCommand, CommandError class Command(BaseCommand): @@ -20,7 +18,6 @@ class Command(BaseCommand): def add_arguments(self, parser): parser.add_argument('--hostname', dest='hostname', type=str, help='Hostname used during provisioning') - parser.add_argument('--is-isolated', dest='is_isolated', action='store_true', help='Specify whether the instance is isolated') def _register_hostname(self, hostname): if not hostname: @@ -36,10 +33,7 @@ class Command(BaseCommand): def handle(self, **options): if not options.get('hostname'): raise CommandError("Specify `--hostname` to use this command.") - if options['is_isolated']: - self.uuid = str(uuid4()) - else: - self.uuid = settings.SYSTEM_UUID + self.uuid = settings.SYSTEM_UUID self.changed = False self._register_hostname(options.get('hostname')) if self.changed: diff --git a/awx/main/management/commands/register_queue.py b/awx/main/management/commands/register_queue.py index 5369e4fe06..9c05020545 100644 --- a/awx/main/management/commands/register_queue.py +++ b/awx/main/management/commands/register_queue.py @@ -17,10 +17,9 @@ class InstanceNotFound(Exception): class RegisterQueue: - def __init__(self, queuename, controller, instance_percent, inst_min, hostname_list, is_container_group=None): + def __init__(self, queuename, instance_percent, inst_min, hostname_list, is_container_group=None): self.instance_not_found_err = None self.queuename = queuename - self.controller = controller self.instance_percent = instance_percent self.instance_min = inst_min self.hostname_list = hostname_list @@ -46,20 +45,6 @@ class RegisterQueue: return (ig, created, changed) - def update_instance_group_controller(self, ig): - changed = False - control_ig = None - - if self.controller: - control_ig = InstanceGroup.objects.filter(name=self.controller).first() - - if control_ig and ig.controller_id != control_ig.pk: - ig.controller = control_ig - ig.save() - changed = True - - return (control_ig, changed) - def add_instances_to_group(self, ig): changed = False @@ -88,26 +73,20 @@ class RegisterQueue: with advisory_lock('cluster_policy_lock'): with transaction.atomic(): changed2 = False - changed3 = False (ig, created, changed1) = self.get_create_update_instance_group() if created: print("Creating instance group {}".format(ig.name)) elif not created: print("Instance Group already registered {}".format(ig.name)) - if self.controller: - (ig_ctrl, changed2) = self.update_instance_group_controller(ig) - if changed2: - print("Set controller group {} on {}.".format(self.controller, self.queuename)) - try: - (instances, changed3) = self.add_instances_to_group(ig) + (instances, changed2) = self.add_instances_to_group(ig) for i in instances: print("Added instance {} to {}".format(i.hostname, ig.name)) except InstanceNotFound as e: self.instance_not_found_err = e - if any([changed1, changed2, changed3]): + if changed1 or changed2: print('(changed: True)') @@ -117,7 +96,6 @@ class Command(BaseCommand): parser.add_argument( '--hostnames', dest='hostnames', type=str, help='Comma-Delimited Hosts to add to the Queue (will not remove already assigned instances)' ) - parser.add_argument('--controller', dest='controller', type=str, default='', help='The controlling group (makes this an isolated group)') parser.add_argument( '--instance_percent', dest='instance_percent', type=int, default=0, help='The percentage of active instances that will be assigned to this group' ), @@ -133,14 +111,13 @@ class Command(BaseCommand): queuename = options.get('queuename') if not queuename: raise CommandError("Specify `--queuename` to use this command.") - ctrl = options.get('controller') inst_per = options.get('instance_percent') instance_min = options.get('instance_minimum') hostname_list = [] if options.get('hostnames'): hostname_list = options.get('hostnames').split(",") - rq = RegisterQueue(queuename, ctrl, inst_per, instance_min, hostname_list) + rq = RegisterQueue(queuename, inst_per, instance_min, hostname_list) rq.register() if rq.instance_not_found_err: print(rq.instance_not_found_err.message) diff --git a/awx/main/management/commands/run_wsbroadcast.py b/awx/main/management/commands/run_wsbroadcast.py index 60f262c86c..56a91f2a93 100644 --- a/awx/main/management/commands/run_wsbroadcast.py +++ b/awx/main/management/commands/run_wsbroadcast.py @@ -140,6 +140,7 @@ class Command(BaseCommand): data[family.name] = family.samples[0].value me = Instance.objects.me() + # TODO: drop the isolated groups exclusion when the model is updated hostnames = [i.hostname for i in Instance.objects.exclude(Q(hostname=me.hostname) | Q(rampart_groups__controller__isnull=False))] host_stats = Command.get_connection_status(me, hostnames, data) diff --git a/awx/main/management/commands/test_isolated_connection.py b/awx/main/management/commands/test_isolated_connection.py deleted file mode 100644 index c89b71a892..0000000000 --- a/awx/main/management/commands/test_isolated_connection.py +++ /dev/null @@ -1,47 +0,0 @@ -import os -import shutil -import sys -import tempfile - -from django.conf import settings -from django.core.management.base import BaseCommand, CommandError - -import ansible_runner - -from awx.main.isolated.manager import set_pythonpath - - -class Command(BaseCommand): - """Tests SSH connectivity between a controller and target isolated node""" - - help = 'Tests SSH connectivity between a controller and target isolated node' - - def add_arguments(self, parser): - parser.add_argument('--hostname', dest='hostname', type=str, help='Hostname of an isolated node') - - def handle(self, *args, **options): - hostname = options.get('hostname') - if not hostname: - raise CommandError("--hostname is a required argument") - - try: - path = tempfile.mkdtemp(prefix='awx_isolated_ssh', dir=settings.AWX_ISOLATION_BASE_PATH) - ssh_key = None - if all([getattr(settings, 'AWX_ISOLATED_KEY_GENERATION', False) is True, getattr(settings, 'AWX_ISOLATED_PRIVATE_KEY', None)]): - ssh_key = settings.AWX_ISOLATED_PRIVATE_KEY - env = dict(os.environ.items()) - env['ANSIBLE_HOST_KEY_CHECKING'] = str(settings.AWX_ISOLATED_HOST_KEY_CHECKING) - set_pythonpath(os.path.join(settings.ANSIBLE_VENV_PATH, 'lib'), env) - res = ansible_runner.interface.run( - private_data_dir=path, - host_pattern='all', - inventory='{} ansible_ssh_user={}'.format(hostname, settings.AWX_ISOLATED_USERNAME), - module='shell', - module_args='ansible-runner --version', - envvars=env, - verbosity=3, - ssh_key=ssh_key, - ) - sys.exit(res.rc) - finally: - shutil.rmtree(path) diff --git a/awx/main/managers.py b/awx/main/managers.py index 473ff6523b..b3ff96783a 100644 --- a/awx/main/managers.py +++ b/awx/main/managers.py @@ -142,7 +142,7 @@ class InstanceManager(models.Manager): pod_ip = os.environ.get('MY_POD_IP') registered = self.register(ip_address=pod_ip) is_container_group = settings.IS_K8S - RegisterQueue('tower', None, 100, 0, [], is_container_group).register() + RegisterQueue('tower', 100, 0, [], is_container_group).register() return registered else: return (False, self.me()) diff --git a/awx/main/wsbroadcast.py b/awx/main/wsbroadcast.py index 184ae06122..7e0ca3a7e2 100644 --- a/awx/main/wsbroadcast.py +++ b/awx/main/wsbroadcast.py @@ -33,6 +33,7 @@ def unwrap_broadcast_msg(payload: dict): def get_broadcast_hosts(): Instance = apps.get_model('main', 'Instance') instances = ( + # TODO: no longer filter for non-isolated after the models change Instance.objects.filter(rampart_groups__controller__isnull=True) .exclude(hostname=Instance.objects.me().hostname) .order_by('hostname')