diff --git a/awx/main/management/commands/deprovision_instance.py b/awx/main/management/commands/deprovision_instance.py new file mode 100644 index 0000000000..117c615db5 --- /dev/null +++ b/awx/main/management/commands/deprovision_instance.py @@ -0,0 +1,52 @@ +# Copyright (c) 2016 Ansible, Inc. +# All Rights Reserved + +from optparse import make_option +import subprocess +import warnings + +from django.db import transaction +from django.core.management.base import BaseCommand, CommandError + +from awx.main.models import Instance +from awx.main.utils.pglock import advisory_lock + + +class Command(BaseCommand): + """ + Deprovision a Tower cluster node + """ + + option_list = BaseCommand.option_list + ( + make_option('--hostname', dest='hostname', type='string', + help='Hostname used during provisioning'), + make_option('--name', dest='name', type='string', + help='(PENDING DEPRECIATION) Hostname used during provisioning'), + ) + + @transaction.atomic + def handle(self, *args, **options): + # TODO: remove in 3.3 + if options.get('name'): + warnings.warn("`--name` is depreciated in favor of `--hostname`, and will be removed in release 3.3.") + if options.get('hostname'): + raise CommandError("Cannot accept both --name and --hostname.") + options['hostname'] = options['name'] + hostname = options.get('hostname') + if not hostname: + raise CommandError("--hostname is a required argument") + with advisory_lock('instance_registration_%s' % hostname): + instance = Instance.objects.filter(hostname=hostname) + if instance.exists(): + instance.delete() + print("Instance Removed") + result = subprocess.Popen("rabbitmqctl forget_cluster_node rabbitmq@{}".format(hostname), shell=True).wait() + if result != 0: + print("Node deprovisioning may have failed when attempting to " + "remove the RabbitMQ instance {} from the cluster".format(hostname)) + else: + print('Successfully deprovisioned {}'.format(hostname)) + print('(changed: True)') + else: + print('No instance found matching name {}'.format(hostname)) + diff --git a/awx/main/management/commands/deprovision_node.py b/awx/main/management/commands/deprovision_node.py index 00e9fd92da..e5d89d2a5e 100644 --- a/awx/main/management/commands/deprovision_node.py +++ b/awx/main/management/commands/deprovision_node.py @@ -1,42 +1,17 @@ -# Copyright (c) 2016 Ansible, Inc. +# Copyright (c) 2017 Ansible by Red Hat # All Rights Reserved -from optparse import make_option -import subprocess +# Borrow from another AWX command +from awx.main.management.commands.deprovision_instance import Command as OtherCommand -from django.db import transaction -from django.core.management.base import BaseCommand, CommandError - -from awx.main.models import Instance -from awx.main.utils.pglock import advisory_lock +# Python +import warnings -class Command(BaseCommand): - """ - Deprovision a Tower cluster node - """ +class Command(OtherCommand): - option_list = BaseCommand.option_list + ( - make_option('--name', dest='name', type='string', - help='Hostname used during provisioning'), - ) - - @transaction.atomic def handle(self, *args, **options): - hostname = options.get('name') - if not hostname: - raise CommandError("--name is a required argument") - with advisory_lock('instance_registration_%s' % hostname): - instance = Instance.objects.filter(hostname=hostname) - if instance.exists(): - instance.delete() - print("Instance Removed") - result = subprocess.Popen("rabbitmqctl forget_cluster_node rabbitmq@{}".format(hostname), shell=True).wait() - if result != 0: - print("Node deprovisioning may have failed when attempting to remove the RabbitMQ instance from the cluster") - else: - print('Successfully deprovisioned {}'.format(hostname)) - print('(changed: True)') - else: - print('No instance found matching name {}'.format(hostname)) - + # TODO: delete this entire file in 3.3 + warnings.warn('This command is replaced with `deprovision_instance` and will ' + 'be removed in release 3.3.') + return super(Command, self).handle(*args, **options) diff --git a/awx/main/management/commands/provision_instance.py b/awx/main/management/commands/provision_instance.py new file mode 100644 index 0000000000..98831dfb52 --- /dev/null +++ b/awx/main/management/commands/provision_instance.py @@ -0,0 +1,45 @@ +# Copyright (c) 2015 Ansible, Inc. +# All Rights Reserved + +from awx.main.models import Instance +from awx.main.utils.pglock import advisory_lock +from django.conf import settings + +from optparse import make_option +from django.db import transaction +from django.core.management.base import BaseCommand, CommandError + + +class Command(BaseCommand): + """ + Internal tower command. + Regsiter this instance with the database for HA tracking. + """ + + option_list = BaseCommand.option_list + ( + make_option('--hostname', dest='hostname', type='string', + help='Hostname used during provisioning'), + ) + + def _register_hostname(self, hostname): + if not hostname: + return + with advisory_lock('instance_registration_%s' % hostname): + instance = Instance.objects.filter(hostname=hostname) + if instance.exists(): + print("Instance already registered {}".format(instance[0].hostname)) + return + instance = Instance(uuid=self.uuid, hostname=hostname) + instance.save() + print('Successfully registered instance {}'.format(hostname)) + self.changed = True + + @transaction.atomic + def handle(self, **options): + if not options.get('hostname'): + raise CommandError("Specify `--hostname` to use this command.") + self.uuid = settings.SYSTEM_UUID + self.changed = False + self._register_hostname(options.get('hostname')) + if self.changed: + print('(changed: True)') diff --git a/awx/main/management/commands/register_instance.py b/awx/main/management/commands/register_instance.py index 98831dfb52..66aa2344f4 100644 --- a/awx/main/management/commands/register_instance.py +++ b/awx/main/management/commands/register_instance.py @@ -1,45 +1,17 @@ -# Copyright (c) 2015 Ansible, Inc. +# Copyright (c) 2017 Ansible by Red Hat # All Rights Reserved -from awx.main.models import Instance -from awx.main.utils.pglock import advisory_lock -from django.conf import settings +# Borrow from another AWX command +from awx.main.management.commands.provision_instance import Command as OtherCommand -from optparse import make_option -from django.db import transaction -from django.core.management.base import BaseCommand, CommandError +# Python +import warnings -class Command(BaseCommand): - """ - Internal tower command. - Regsiter this instance with the database for HA tracking. - """ +class Command(OtherCommand): - option_list = BaseCommand.option_list + ( - make_option('--hostname', dest='hostname', type='string', - help='Hostname used during provisioning'), - ) - - def _register_hostname(self, hostname): - if not hostname: - return - with advisory_lock('instance_registration_%s' % hostname): - instance = Instance.objects.filter(hostname=hostname) - if instance.exists(): - print("Instance already registered {}".format(instance[0].hostname)) - return - instance = Instance(uuid=self.uuid, hostname=hostname) - instance.save() - print('Successfully registered instance {}'.format(hostname)) - self.changed = True - - @transaction.atomic - def handle(self, **options): - if not options.get('hostname'): - raise CommandError("Specify `--hostname` to use this command.") - self.uuid = settings.SYSTEM_UUID - self.changed = False - self._register_hostname(options.get('hostname')) - if self.changed: - print('(changed: True)') + def handle(self, *args, **options): + # TODO: delete this entire file in 3.3 + warnings.warn('This command is replaced with `provision_instance` and will ' + 'be removed in release 3.3.') + return super(Command, self).handle(*args, **options) diff --git a/awx/main/management/commands/instance_group_remove.py b/awx/main/management/commands/remove_from_queue.py similarity index 100% rename from awx/main/management/commands/instance_group_remove.py rename to awx/main/management/commands/remove_from_queue.py diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 403a67b443..9888c3bede 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -49,3 +49,7 @@ [[#5783](https://github.com/ansible/ansible-tower/pull/5783)] * Remove Rackspace as a supported inventory source type and credential type. [[#6117](https://github.com/ansible/ansible-tower/pull/6117)] +* Changed names of tower-mange commands `register_instance` -> `provision_instance`, + `deprovision_node` -> `deprovision_instance`, and `instance_group_remove` -> `remove_from_queue`, + which backward compatibility support for 3.1 use pattern + [[#6915](https://github.com/ansible/ansible-tower/issues/6915)] diff --git a/docs/clustering.md b/docs/clustering.md index 26924c45b7..df52cbadd8 100644 --- a/docs/clustering.md +++ b/docs/clustering.md @@ -189,15 +189,15 @@ Recommendations for system configuration with isolated groups: variable - the behavior in this case can not be predicted. - Do not put an isolated instance in more than 1 isolated group. -Isolated Node Authentication ----------------------------- +Isolated Instance Authentication +-------------------------------- By default - at installation time - a randomized RSA key is generated and distributed as an authorized key to all "isolated" instances. The private half of the key is encrypted and stored within Tower, and is used to authenticate from "controller" instances to "isolated" instances when jobs are run. -For users who wish to manage SSH authentication from controlling nodes to -isolated nodes via some system _outside_ of Tower (such as externally-managed +For users who wish to manage SSH authentication from controlling instances to +isolated instances via some system _outside_ of Tower (such as externally-managed passwordless SSH keys), this behavior can be disabled by unsetting two Tower API settings values: @@ -215,7 +215,7 @@ Tower does not automatically de-provision instances since we can't distinguish b Instead the procedure for deprovisioning an instance is to shut it down (or stop the `ansible-tower-service`) and run the Tower deprovision command: ``` -$ tower-manage deprovision-node +$ awx-manage deprovision_instance --hostname= ``` * Removing/Deprovisioning Instance Groups @@ -223,7 +223,7 @@ Tower does not automatically de-provision or remove instance groups, even though show up in api endpoints and stats monitoring. These groups can be removed with the following command: ``` -$ tower-manage unregister_queue --queuename= +$ awx-manage unregister_queue --queuename= ``` ### Status and Monitoring