optional listener port UI (#14300)

This commit is contained in:
Seth Foster
2023-07-31 14:52:42 -04:00
parent 3bd25c682e
commit e41ad82687
4 changed files with 21 additions and 16 deletions

View File

@@ -5501,8 +5501,12 @@ class InstanceSerializer(BaseSerializer):
_("Setting peers manually for control nodes is not allowed. Enable peers_from_control_nodes on the hop and execution nodes instead.") _("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.")) 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', []): for peer in attrs.get('peers', []):
if peer.listener_port is None: if peer.listener_port is None:
raise serializers.ValidationError(_("Field listener_port must be set on peer ") + peer.hostname + ".") raise serializers.ValidationError(_("Field listener_port must be set on peer ") + peer.hostname + ".")
@@ -5544,7 +5548,10 @@ class InstanceSerializer(BaseSerializer):
return value return value
def validate_listener_port(self, 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.")) raise serializers.ValidationError(_("Cannot change listener port."))
return value return value

View File

@@ -513,14 +513,14 @@ def on_instance_saved(sender, instance, created=False, raw=False, **kwargs):
# node and kick off write_receptor_config # node and kick off write_receptor_config
connection.on_commit(lambda: remove_deprovisioned_node.apply_async([instance.hostname])) connection.on_commit(lambda: remove_deprovisioned_node.apply_async([instance.hostname]))
else: else:
control_instances = set(Instance.objects.filter(node_type__in=[Instance.Types.CONTROL, Instance.Types.HYBRID]))
if instance.peers_from_control_nodes: if instance.peers_from_control_nodes:
control_instances = Instance.objects.filter(node_type__in=[Instance.Types.CONTROL, Instance.Types.HYBRID]) if (control_instances & set(instance.peers_from.all())) != set(control_instances):
if set(instance.peers_from.all()) != control_instances: instance.peers_from.add(*control_instances)
instance.peers_from.set(control_instances)
schedule_write_receptor_config() # keep method separate to make pytest mocking easier schedule_write_receptor_config() # keep method separate to make pytest mocking easier
else: else:
if instance.peers_from.exists(): if set(control_instances) & set(instance.peers_from.all()):
instance.peers_from.clear() instance.peers_from.remove(*control_instances)
schedule_write_receptor_config() schedule_write_receptor_config()
if created or instance.has_policy_changes(): if created or instance.has_policy_changes():

View File

@@ -210,7 +210,7 @@ function InstanceDetail({ setBreadcrumb, isK8s }) {
<Detail label={t`Instance Port`} value={instance.listener_port} /> <Detail label={t`Instance Port`} value={instance.listener_port} />
{(isExecutionNode || isHopNode) && ( {(isExecutionNode || isHopNode) && (
<Detail <Detail
label={t`Connection to control nodes`} label={t`Peers from control nodes`}
value={instance.peers_from_control_nodes ? t`On` : t`Off`} value={instance.peers_from_control_nodes ? t`On` : t`Off`}
/> />
)} )}

View File

@@ -63,8 +63,7 @@ function InstanceFormFields({ isEdit }) {
label={t`Listener Port`} label={t`Listener Port`}
name="listener_port" name="listener_port"
type="number" type="number"
tooltip={t`Select the port that Receptor will listen on for incoming connections. Default is 27199.`} tooltip={t`Select the port that Receptor will listen on for incoming connections, e.g. 27199.`}
isRequired
/> />
<FormGroup <FormGroup
fieldId="instance-type" fieldId="instance-type"
@@ -122,8 +121,8 @@ function InstanceFormFields({ isEdit }) {
<CheckboxField <CheckboxField
id="peers_from_control_nodes" id="peers_from_control_nodes"
name="peers_from_control_nodes" name="peers_from_control_nodes"
label={t`Connect to control nodes`} label={t`Peers from control nodes`}
tooltip={t`Connect this instance to control nodes. If disabled, instance will be connected only to peers selected.`} tooltip={t`If enabled, control nodes will peer to this instance automatically. If disabled, instance will be connected only to associated peers.`}
/> />
</FormGroup> </FormGroup>
</> </>
@@ -146,17 +145,16 @@ function InstanceForm({
description: instance.description || '', description: instance.description || '',
node_type: instance.node_type || 'execution', node_type: instance.node_type || 'execution',
node_state: instance.node_state || 'installed', node_state: instance.node_state || 'installed',
listener_port: instance.listener_port || 27199, listener_port: instance.listener_port,
enabled: instance.enabled || true, enabled: instance.enabled || true,
managed_by_policy: instance.managed_by_policy || true, managed_by_policy: instance.managed_by_policy || true,
peers_from_control_nodes: instance.peers_from_control_nodes peers_from_control_nodes: instance.peers_from_control_nodes || false,
? true
: !isEdit,
peers: instance_peers, peers: instance_peers,
}} }}
onSubmit={(values) => { onSubmit={(values) => {
handleSubmit({ handleSubmit({
...values, ...values,
listener_port: values.listener_port === '' ? null : values.listener_port,
peers: values.peers.map((peer) => peer.hostname || peer), peers: values.peers.map((peer) => peer.hostname || peer),
}); });
}} }}