diff --git a/awx/main/management/commands/add_receptor_address.py b/awx/main/management/commands/add_receptor_address.py index ad23230556..5ad1a044dc 100644 --- a/awx/main/management/commands/add_receptor_address.py +++ b/awx/main/management/commands/add_receptor_address.py @@ -21,9 +21,7 @@ class Command(BaseCommand): parser.add_argument('--port', dest='port', type=int, help="Receptor listener port") parser.add_argument('--protocol', dest='protocol', type=str, default='tcp', choices=['tcp', 'ws'], help="Protocol of the backend connection") parser.add_argument('--websocket_path', dest='websocket_path', type=str, default="", help="Path for websockets") - parser.add_argument( - '--is_internal', dest='is_internal', type=bool, default=False, help="If true, address only resolvable within the Kubernetes cluster" - ) + parser.add_argument('--is_internal', action='store_true', help="If true, address only resolvable within the Kubernetes cluster") def _add_address(self, **kwargs): try: diff --git a/awx/main/management/commands/provision_instance.py b/awx/main/management/commands/provision_instance.py index e7f8063d61..be9a1a8102 100644 --- a/awx/main/management/commands/provision_instance.py +++ b/awx/main/management/commands/provision_instance.py @@ -28,8 +28,9 @@ class Command(BaseCommand): parser.add_argument('--listener_port', dest='listener_port', type=int, help="Receptor listener port") parser.add_argument('--node_type', type=str, default='hybrid', choices=['control', 'execution', 'hop', 'hybrid'], help="Instance Node type") parser.add_argument('--uuid', type=str, help="Instance UUID") + parser.add_argument('--peers_from_control_nodes', action='store_true', help="If set, will automatically peer from control nodes") - def _register_hostname(self, hostname, node_type, uuid, listener_port): + def _register_hostname(self, hostname, node_type, uuid, listener_port, peers_from_control_nodes): if not hostname: if not settings.AWX_AUTO_DEPROVISION_INSTANCES: raise CommandError('Registering with values from settings only intended for use in K8s installs') @@ -51,7 +52,9 @@ class Command(BaseCommand): max_concurrent_jobs=settings.DEFAULT_EXECUTION_QUEUE_MAX_CONCURRENT_JOBS, ).register() else: - (changed, instance) = Instance.objects.register(hostname=hostname, node_type=node_type, node_uuid=uuid, listener_port=listener_port) + (changed, instance) = Instance.objects.register( + hostname=hostname, node_type=node_type, node_uuid=uuid, listener_port=listener_port, peers_from_control_nodes=peers_from_control_nodes + ) if changed: print("Successfully registered instance {}".format(hostname)) else: @@ -61,6 +64,8 @@ class Command(BaseCommand): @transaction.atomic def handle(self, **options): self.changed = False - self._register_hostname(options.get('hostname'), options.get('node_type'), options.get('uuid'), options.get('listener_port')) + self._register_hostname( + options.get('hostname'), options.get('node_type'), options.get('uuid'), options.get('listener_port'), options.get('peers_from_control_nodes') + ) if self.changed: print("(changed: True)") diff --git a/awx/main/managers.py b/awx/main/managers.py index 747f9d4467..ce5bef7e60 100644 --- a/awx/main/managers.py +++ b/awx/main/managers.py @@ -115,7 +115,7 @@ class InstanceManager(models.Manager): return node[0] raise RuntimeError("No instance found with the current cluster host id") - def register(self, node_uuid=None, hostname=None, ip_address="", listener_port=None, node_type='hybrid', defaults=None): + def register(self, node_uuid=None, hostname=None, ip_address="", listener_port=None, node_type='hybrid', peers_from_control_nodes=False, defaults=None): if not hostname: hostname = settings.CLUSTER_HOST_ID @@ -180,5 +180,13 @@ class InstanceManager(models.Manager): uuid_option = {'uuid': node_uuid if node_uuid is not None else uuid.uuid4()} if node_type == 'execution' and 'version' not in create_defaults: create_defaults['version'] = RECEPTOR_PENDING - instance = self.create(hostname=hostname, ip_address=ip_address, listener_port=listener_port, node_type=node_type, **create_defaults, **uuid_option) + instance = self.create( + hostname=hostname, + ip_address=ip_address, + listener_port=listener_port, + node_type=node_type, + peers_from_control_nodes=peers_from_control_nodes, + **create_defaults, + **uuid_option + ) return (True, instance) diff --git a/awx/main/models/receptor_address.py b/awx/main/models/receptor_address.py index 4936f16124..dd0ff4b411 100644 --- a/awx/main/models/receptor_address.py +++ b/awx/main/models/receptor_address.py @@ -1,8 +1,12 @@ from django.db import models from django.utils.translation import gettext_lazy as _ +from django.db.models.signals import post_save, post_delete +from django.dispatch import receiver from awx.api.versioning import reverse from django.db.models import Sum, Q +from awx.main.models.ha import schedule_write_receptor_config + class ReceptorAddress(models.Model): class Meta: @@ -58,3 +62,13 @@ class ReceptorAddress(models.Model): def get_absolute_url(self, request=None): return reverse('api:receptor_address_detail', kwargs={'pk': self.pk}, request=request) + + +@receiver(post_save, sender=ReceptorAddress) +def receptor_address_saved(sender, instance, **kwargs): + schedule_write_receptor_config(True) + + +@receiver(post_delete, sender=ReceptorAddress) +def receptor_address_deleted(sender, instance, **kwargs): + schedule_write_receptor_config(True) diff --git a/awx/main/tasks/receptor.py b/awx/main/tasks/receptor.py index ce4049e6ab..b1bf657f32 100644 --- a/awx/main/tasks/receptor.py +++ b/awx/main/tasks/receptor.py @@ -703,9 +703,10 @@ def generate_config_data(): receptor_config = list(RECEPTOR_CONFIG_STARTER) for instance in instances: - if instance.listener_port: - peer = {'tcp-peer': {'address': f'{instance.hostname}:{instance.listener_port}', 'tls': 'tlsclient'}} - receptor_config.append(peer) + # receptor_addresses = instance.receptor_addresses.all() + # if not receptor_addresses.exists() and instance.listener_port: + # peer = {'tcp-peer': {'address': f'{instance.hostname}:{instance.listener_port}', 'tls': 'tlsclient'}} + # receptor_config.append(peer) for address in instance.receptor_addresses.all(): if address.get_peer_type() and address.is_internal: peer = {