diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 693faa3cbc..be4d5581e2 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -4776,7 +4776,7 @@ class InstanceSerializer(BaseSerializer): class Meta: model = Instance - read_only_fields = ('uuid', 'hostname', 'version') + read_only_fields = ('uuid', 'hostname', 'version', 'node_type') fields = ( "id", "type", @@ -4799,6 +4799,7 @@ class InstanceSerializer(BaseSerializer): "mem_capacity", "enabled", "managed_by_policy", + "node_type", ) def get_related(self, obj): diff --git a/awx/main/management/commands/provision_instance.py b/awx/main/management/commands/provision_instance.py index 06ca4470ac..6e145a9baf 100644 --- a/awx/main/management/commands/provision_instance.py +++ b/awx/main/management/commands/provision_instance.py @@ -18,11 +18,12 @@ class Command(BaseCommand): def add_arguments(self, parser): parser.add_argument('--hostname', dest='hostname', type=str, help='Hostname used during provisioning') + parser.add_argument('--node_type', type=str, default="hybrid", choices=["control", "execution", "hybrid"], help='Instance Node type') - def _register_hostname(self, hostname): + def _register_hostname(self, hostname, node_type): if not hostname: return - (changed, instance) = Instance.objects.register(uuid=self.uuid, hostname=hostname) + (changed, instance) = Instance.objects.register(uuid=self.uuid, hostname=hostname, node_type=node_type) if changed: print('Successfully registered instance {}'.format(hostname)) else: @@ -35,6 +36,6 @@ class Command(BaseCommand): raise CommandError("Specify `--hostname` to use this command.") self.uuid = settings.SYSTEM_UUID self.changed = False - self._register_hostname(options.get('hostname')) + self._register_hostname(options.get('hostname'), options.get('node_type')) if self.changed: print('(changed: True)') diff --git a/awx/main/managers.py b/awx/main/managers.py index f620555df1..b26d476fd1 100644 --- a/awx/main/managers.py +++ b/awx/main/managers.py @@ -111,11 +111,13 @@ class InstanceManager(models.Manager): return node[0] raise RuntimeError("No instance found with the current cluster host id") - def register(self, uuid=None, hostname=None, ip_address=None): + def register(self, uuid=None, hostname=None, ip_address=None, node_type=None): if not uuid: uuid = settings.SYSTEM_UUID if not hostname: hostname = settings.CLUSTER_HOST_ID + if not node_type: + node_type = "hybrid" with advisory_lock('instance_registration_%s' % hostname): if settings.AWX_AUTO_DEPROVISION_INSTANCES: # detect any instances with the same IP address. @@ -131,13 +133,19 @@ class InstanceManager(models.Manager): instance = self.filter(hostname=hostname) if instance.exists(): instance = instance.get() + update_fields = [] if instance.ip_address != ip_address: instance.ip_address = ip_address - instance.save(update_fields=['ip_address']) + update_fields.append('ip_address') + if instance.node_type != node_type: + instance.node_type = node_type + update_fields.append('node_type') + if update_fields: + instance.save(update_fields=update_fields) return (True, instance) else: return (False, instance) - instance = self.create(uuid=uuid, hostname=hostname, ip_address=ip_address, capacity=0) + instance = self.create(uuid=uuid, hostname=hostname, ip_address=ip_address, capacity=0, node_type=node_type) return (True, instance) def get_or_register(self): diff --git a/awx/main/migrations/0152_instance_node_type.py b/awx/main/migrations/0152_instance_node_type.py new file mode 100644 index 0000000000..1adcb16c9f --- /dev/null +++ b/awx/main/migrations/0152_instance_node_type.py @@ -0,0 +1,22 @@ +# Generated by Django 2.2.20 on 2021-07-26 19:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('main', '0151_rename_managed_by_tower'), + ] + + operations = [ + migrations.AddField( + model_name='instance', + name='node_type', + field=models.CharField( + choices=[('control', 'Control plane node'), ('execution', 'Execution plane node'), ('hybrid', 'Controller and execution')], + default='hybrid', + max_length=16, + ), + ), + ] diff --git a/awx/main/models/ha.py b/awx/main/models/ha.py index a132a2ae6c..5f4657b230 100644 --- a/awx/main/models/ha.py +++ b/awx/main/models/ha.py @@ -86,6 +86,8 @@ class Instance(HasPolicyEditsMixin, BaseModel): default=0, editable=False, ) + NODE_TYPE_CHOICES = [("control", "Control plane node"), ("execution", "Execution plane node"), ("hybrid", "Controller and execution")] + node_type = models.CharField(default='hybrid', choices=NODE_TYPE_CHOICES, max_length=16) class Meta: app_label = 'main'