diff --git a/app/models.py b/app/models.py index 981fbe08071451b769e8eb8c25f63cfd462e5e19..a71ee67c381a1dbc2e6ec34fa23d0c4aae4179a6 100644 --- a/app/models.py +++ b/app/models.py @@ -1047,6 +1047,7 @@ class AnsibleGroupType(Enum): NETWORK = "NETWORK" DEVICE_TYPE = "DEVICE_TYPE" IOC = "IOC" + HOSTNAME = "HOSTNAME" def __str__(self): return self.name @@ -1151,6 +1152,12 @@ class AnsibleGroup(CreatedMixin, SearchableMixin, db.Model): ) if self.type == AnsibleGroupType.IOC: return Host.query.filter(Host.is_ioc.is_(True)).order_by(Host.name).all() + if self.type == AnsibleGroupType.HOSTNAME: + return ( + Host.query.filter(Host.name.startswith(self.name)) + .order_by(Host.name) + .all() + ) @hosts.setter def hosts(self, value): diff --git a/docs/_static/ansible/view_ansible_hostname_group.png b/docs/_static/ansible/view_ansible_hostname_group.png new file mode 100644 index 0000000000000000000000000000000000000000..9e4026f33c9859cea2a9ceec10b2230fd367ebd8 Binary files /dev/null and b/docs/_static/ansible/view_ansible_hostname_group.png differ diff --git a/docs/network.rst b/docs/network.rst index 07076685ac3d6897484c25a7d431e98c36c51946..a8fe8811a8bfb8b3bcf35210850bc34848f9d1ae 100644 --- a/docs/network.rst +++ b/docs/network.rst @@ -265,6 +265,15 @@ Click submit. You can see the list of hosts part of the ICSVMs network: .. image:: _static/ansible/view_ansible_network_group.png +There are two additional dynamic groups: *IOC* and *HOSTNAME*. +The *IOC* type is supposed to be used to create a unique **iocs** group. It gathers all the hosts which have the IOC checkbox selected. + +The *HOSTNAME* type is used to define a group which will include all hosts that start with the same name as the group. +The **sw-tn-g02** group will include all hosts that start with that prefix: + +.. image:: _static/ansible/view_ansible_hostname_group.png + + Groups of groups ~~~~~~~~~~~~~~~~ diff --git a/migrations/versions/b1eda5cb7d9d_add_hostname_ansible_group_type.py b/migrations/versions/b1eda5cb7d9d_add_hostname_ansible_group_type.py new file mode 100644 index 0000000000000000000000000000000000000000..d7d4a49cb0e490ebb990cda31d459619e2939882 --- /dev/null +++ b/migrations/versions/b1eda5cb7d9d_add_hostname_ansible_group_type.py @@ -0,0 +1,26 @@ +"""Add HOSTNAME Ansible group type + +Revision ID: b1eda5cb7d9d +Revises: acd72492f46f +Create Date: 2020-03-04 20:37:15.636489 + +""" +from alembic import op + + +# revision identifiers, used by Alembic. +revision = "b1eda5cb7d9d" +down_revision = "acd72492f46f" +branch_labels = None +depends_on = None + + +def upgrade(): + op.execute("COMMIT") + op.execute("ALTER TYPE ansible_group_type ADD VALUE 'HOSTNAME'") + + +def downgrade(): + # Removing an individual value from an enum type isn't supported + # https://www.postgresql.org/docs/current/datatype-enum.html + pass diff --git a/tests/functional/test_models.py b/tests/functional/test_models.py index 4eadeb3be86fa2f8dc51f9598638692c51be4a20..187918145914b34bdb61e0be4b5bf5f16df8986a 100644 --- a/tests/functional/test_models.py +++ b/tests/functional/test_models.py @@ -396,6 +396,8 @@ def test_ansible_group_is_dynamic(ansible_group_factory): assert group3.is_dynamic group4 = ansible_group_factory(type=models.AnsibleGroupType.IOC) assert group4.is_dynamic + group5 = ansible_group_factory(type=models.AnsibleGroupType.HOSTNAME) + assert group5.is_dynamic def test_ansible_groups_children(ansible_group_factory, host_factory): @@ -546,6 +548,21 @@ def test_ansible_dynamic_ioc_group(ansible_group_factory, host_factory): assert group.hosts == [host1, host2] +def test_ansible_dynamic_hostname_group(ansible_group_factory, host_factory): + host1 = host_factory(name="sw-gpn-rtp-01") + host2 = host_factory(name="sw-gpn-cso-campus-01") + host3 = host_factory(name="sw-tn-g02-lcr-01") + host4 = host_factory(name="sw-tn-g02-vbox-01") + host_factory(name="host1", is_ioc=False) + host_factory(name="foo-sw-tn-g02", is_ioc=False) + group1 = ansible_group_factory(name="sw-gpn", type=models.AnsibleGroupType.HOSTNAME) + group2 = ansible_group_factory( + name="sw-tn-g02", type=models.AnsibleGroupType.HOSTNAME + ) + assert group1.hosts == [host2, host1] + assert group2.hosts == [host3, host4] + + @pytest.mark.parametrize("status", [None, "FINISHED", "FAILED", "STARTED"]) def test_no_task_waiting(status, user, task_factory): if status is None: