diff --git a/awx/api/serializers.py b/awx/api/serializers.py
index 9bf64b313ff9..d8db405f5195 100644
--- a/awx/api/serializers.py
+++ b/awx/api/serializers.py
@@ -5501,8 +5501,12 @@ def get_field_from_model_or_attrs(fd):
_("Setting peers manually for control nodes is not allowed. Enable peers_from_control_nodes on the hop and execution nodes instead.")
)
- if peers_from_control_nodes and listener_port is None:
+ if not listener_port and peers_from_control_nodes:
raise serializers.ValidationError(_("Field listener_port must be a valid integer when peers_from_control_nodes is enabled."))
+
+ if not listener_port and self.instance and self.instance.peers_from.exists():
+ raise serializers.ValidationError(_("Field listener_port must be a valid integer when other nodes peer to it."))
+
for peer in attrs.get('peers', []):
if peer.listener_port is None:
raise serializers.ValidationError(_("Field listener_port must be set on peer ") + peer.hostname + ".")
@@ -5544,7 +5548,10 @@ def validate_hostname(self, value):
return value
def validate_listener_port(self, value):
- if self.instance and self.instance.listener_port != value:
+ """
+ Cannot change listener port, unless going from none to integer, and vice versa
+ """
+ if value and self.instance and self.instance.listener_port and self.instance.listener_port != value:
raise serializers.ValidationError(_("Cannot change listener port."))
return value
diff --git a/awx/main/models/ha.py b/awx/main/models/ha.py
index c0c031d8fd72..349d36cd43f1 100644
--- a/awx/main/models/ha.py
+++ b/awx/main/models/ha.py
@@ -513,14 +513,14 @@ def on_instance_saved(sender, instance, created=False, raw=False, **kwargs):
# node and kick off write_receptor_config
connection.on_commit(lambda: remove_deprovisioned_node.apply_async([instance.hostname]))
else:
+ control_instances = set(Instance.objects.filter(node_type__in=[Instance.Types.CONTROL, Instance.Types.HYBRID]))
if instance.peers_from_control_nodes:
- control_instances = Instance.objects.filter(node_type__in=[Instance.Types.CONTROL, Instance.Types.HYBRID])
- if set(instance.peers_from.all()) != control_instances:
- instance.peers_from.set(control_instances)
+ if (control_instances & set(instance.peers_from.all())) != set(control_instances):
+ instance.peers_from.add(*control_instances)
schedule_write_receptor_config() # keep method separate to make pytest mocking easier
else:
- if instance.peers_from.exists():
- instance.peers_from.clear()
+ if set(control_instances) & set(instance.peers_from.all()):
+ instance.peers_from.remove(*control_instances)
schedule_write_receptor_config()
if created or instance.has_policy_changes():
diff --git a/awx/ui/src/screens/Instances/InstanceDetail/InstanceDetail.js b/awx/ui/src/screens/Instances/InstanceDetail/InstanceDetail.js
index fd643c5edd8a..70fa161e6878 100644
--- a/awx/ui/src/screens/Instances/InstanceDetail/InstanceDetail.js
+++ b/awx/ui/src/screens/Instances/InstanceDetail/InstanceDetail.js
@@ -210,7 +210,7 @@ function InstanceDetail({ setBreadcrumb, isK8s }) {
{(isExecutionNode || isHopNode) && (
)}
diff --git a/awx/ui/src/screens/Instances/Shared/InstanceForm.js b/awx/ui/src/screens/Instances/Shared/InstanceForm.js
index 152c16b4fa34..41776f0decb3 100644
--- a/awx/ui/src/screens/Instances/Shared/InstanceForm.js
+++ b/awx/ui/src/screens/Instances/Shared/InstanceForm.js
@@ -63,8 +63,7 @@ function InstanceFormFields({ isEdit }) {
label={t`Listener Port`}
name="listener_port"
type="number"
- tooltip={t`Select the port that Receptor will listen on for incoming connections. Default is 27199.`}
- isRequired
+ tooltip={t`Select the port that Receptor will listen on for incoming connections, e.g. 27199.`}
/>
>
@@ -146,17 +145,16 @@ function InstanceForm({
description: instance.description || '',
node_type: instance.node_type || 'execution',
node_state: instance.node_state || 'installed',
- listener_port: instance.listener_port || 27199,
+ listener_port: instance.listener_port,
enabled: instance.enabled || true,
managed_by_policy: instance.managed_by_policy || true,
- peers_from_control_nodes: instance.peers_from_control_nodes
- ? true
- : !isEdit,
+ peers_from_control_nodes: instance.peers_from_control_nodes || false,
peers: instance_peers,
}}
onSubmit={(values) => {
handleSubmit({
...values,
+ listener_port: values.listener_port === '' ? null : values.listener_port,
peers: values.peers.map((peer) => peer.hostname || peer),
});
}}