diff --git a/awx/api/serializers.py b/awx/api/serializers.py index f8e7468d65..fd52c1d52f 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -5598,27 +5598,32 @@ class InstanceSerializer(BaseSerializer): def create_or_update(self, validated_data, obj=None, create=True): # create a managed receptor address if listener port is defined - kwargs = dict() - if 'listener_port' in validated_data: - kwargs['port'] = validated_data.pop('listener_port') - if 'peers_from_control_nodes' in validated_data: - kwargs['peers_from_control_nodes'] = validated_data.pop('peers_from_control_nodes') + port = validated_data.pop('listener_port', -1) + peers_from_control_nodes = validated_data.pop('peers_from_control_nodes', -1) + + # delete the receptor address if the port is explicitly set to None + if obj and port == None: + obj.receptor_addresses.filter(address=obj.hostname).delete() if create: instance = super(InstanceSerializer, self).create(validated_data) else: instance = super(InstanceSerializer, self).update(obj, validated_data) + instance.refresh_from_db() # instance canonical address lookup is deferred, so needs to be reloaded - # delete the receptor address if the port is expolisitly set to None - if 'port' in kwargs and not kwargs['port']: - instance.receptor_addresses.filter(address=instance.hostname).delete() # only create or update if port is defined in validated_data or already exists in the # canonical address # this prevents creating a receptor address if peers_from_control_nodes is in # validated_data but a port is not set - elif kwargs and ('port' in kwargs or instance.canonical_address_port): - kwargs['canonical'] = True - instance.receptor_addresses.update_or_create(address=instance.hostname, defaults=kwargs) + if (port != None and port != -1) or instance.canonical_address_port: + kwargs = {} + if port != -1: + kwargs['port'] = port + if peers_from_control_nodes != -1: + kwargs['peers_from_control_nodes'] = peers_from_control_nodes + if kwargs: + kwargs['canonical'] = True + instance.receptor_addresses.update_or_create(address=instance.hostname, defaults=kwargs) return instance diff --git a/awx/main/models/ha.py b/awx/main/models/ha.py index 5aec708c07..fe8fbfa0ab 100644 --- a/awx/main/models/ha.py +++ b/awx/main/models/ha.py @@ -522,13 +522,14 @@ def receptor_address_saved(sender, instance, **kwargs): control_instances = set(Instance.objects.filter(node_type__in=[Instance.Types.CONTROL, Instance.Types.HYBRID])) if address.peers_from_control_nodes: - # FIXME: you ought to be able to have more connections than just the control instances - if set(address.peers_from.all()) != control_instances: + # if control_instances is not a subset of current peers of address, then + # that means we need to add some InstanceLinks + if not control_instances <= set(address.peers_from.all()): with disable_activity_stream(): - address.peers_from.add(*control_instances) + for control_instance in control_instances: + InstanceLink.objects.update_or_create(source=control_instance, target=address) schedule_write_receptor_config() else: - # FIXME: you shouldn't unconditionally remove every peer when disabling peers_from_control_nodes if address.peers_from.exists(): with disable_activity_stream(): address.peers_from.remove(*control_instances)