diff --git a/awx/main/migrations/0156_capture_mesh_topology.py b/awx/main/migrations/0156_capture_mesh_topology.py new file mode 100644 index 0000000000..90f5a5e0a2 --- /dev/null +++ b/awx/main/migrations/0156_capture_mesh_topology.py @@ -0,0 +1,44 @@ +# Generated by Django 2.2.20 on 2021-12-17 19:26 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('main', '0155_improved_health_check'), + ] + + operations = [ + migrations.AlterField( + model_name='instance', + name='node_type', + field=models.CharField( + choices=[ + ('control', 'Control plane node'), + ('execution', 'Execution plane node'), + ('hybrid', 'Controller and execution'), + ('hop', 'Message-passing node, no execution capability'), + ], + default='hybrid', + max_length=16, + ), + ), + migrations.CreateModel( + name='InstanceLink', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('source', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='main.Instance')), + ('target', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reverse_peers', to='main.Instance')), + ], + options={ + 'unique_together': {('source', 'target')}, + }, + ), + migrations.AddField( + model_name='instance', + name='peers', + field=models.ManyToManyField(through='main.InstanceLink', to='main.Instance'), + ), + ] diff --git a/awx/main/models/__init__.py b/awx/main/models/__init__.py index f439a692fb..ed49b98083 100644 --- a/awx/main/models/__init__.py +++ b/awx/main/models/__init__.py @@ -47,6 +47,7 @@ from awx.main.models.execution_environments import ExecutionEnvironment # noqa from awx.main.models.activity_stream import ActivityStream # noqa from awx.main.models.ha import ( # noqa Instance, + InstanceLink, InstanceGroup, TowerScheduleState, ) diff --git a/awx/main/models/ha.py b/awx/main/models/ha.py index ea9f7d8d0e..c21c66b8df 100644 --- a/awx/main/models/ha.py +++ b/awx/main/models/ha.py @@ -54,6 +54,14 @@ class HasPolicyEditsMixin(HasEditsMixin): return self._values_have_edits(new_values) +class InstanceLink(BaseModel): + source = models.ForeignKey('Instance', on_delete=models.CASCADE, related_name='+') + target = models.ForeignKey('Instance', on_delete=models.CASCADE, related_name='reverse_peers') + + class Meta: + unique_together = ('source', 'target') + + class Instance(HasPolicyEditsMixin, BaseModel): """A model representing an AWX instance running against this database.""" @@ -116,9 +124,16 @@ 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_CHOICES = [ + ("control", "Control plane node"), + ("execution", "Execution plane node"), + ("hybrid", "Controller and execution"), + ("hop", "Message-passing node, no execution capability"), + ] node_type = models.CharField(default='hybrid', choices=NODE_TYPE_CHOICES, max_length=16) + peers = models.ManyToManyField('self', symmetrical=False, through=InstanceLink, through_fields=('source', 'target')) + class Meta: app_label = 'main' ordering = ("hostname",)