diff --git a/app/api/network.py b/app/api/network.py index d47f628432a35cb140c347c6bfb05c5f172b9937..d8e4239e72f0db5c8e0b5a181afd42595ec893ec 100644 --- a/app/api/network.py +++ b/app/api/network.py @@ -141,11 +141,11 @@ def create_host(): .. :quickref: Network; Create new host :jsonparam name: hostname - :jsonparam machine_type: Physical|Virtual|... + :jsonparam device_type: Physical|Virtual|... :jsonparam description: (optional) description :jsonparam item_id: (optional) linked item primary key """ - return create_generic_model(models.Host, mandatory_fields=('name', 'machine_type')) + return create_generic_model(models.Host, mandatory_fields=('name', 'device_type')) @bp.route('/macs') diff --git a/app/factory.py b/app/factory.py index 947685f668fa23481ecc0c7a1ee99b8a770c0824..75430d162cf63fd9b93be27a45ab12b81270df80 100644 --- a/app/factory.py +++ b/app/factory.py @@ -104,7 +104,7 @@ def create_app(config=None): admin.add_view(AdminModelView(models.Domain, db.session)) admin.add_view(AdminModelView(models.NetworkScope, db.session)) admin.add_view(NetworkAdmin(models.Network, db.session, endpoint='networks')) - admin.add_view(AdminModelView(models.MachineType, db.session)) + admin.add_view(AdminModelView(models.DeviceType, db.session)) admin.add_view(AdminModelView(models.Host, db.session)) admin.add_view(AdminModelView(models.Interface, db.session)) admin.add_view(AdminModelView(models.Mac, db.session)) diff --git a/app/models.py b/app/models.py index fada30a80ebea18ac708e0a1af910b03534dc48f..9505953989f326e018711d47649daa977a31082c 100644 --- a/app/models.py +++ b/app/models.py @@ -587,12 +587,12 @@ class Tag(QRCodeMixin, db.Model): admin_only = db.Column(db.Boolean, nullable=False, default=False) -class MachineType(db.Model): - __tablename__ = 'machine_type' +class DeviceType(db.Model): + __tablename__ = 'device_type' id = db.Column(db.Integer, primary_key=True) name = db.Column(CIText, nullable=False, unique=True) - hosts = db.relationship('Host', backref='machine_type') + hosts = db.relationship('Host', backref='device_type') def __str__(self): return self.name @@ -608,15 +608,15 @@ class MachineType(db.Model): class Host(CreatedMixin, db.Model): name = db.Column(db.Text, nullable=False, unique=True) description = db.Column(db.Text) - machine_type_id = db.Column(db.Integer, db.ForeignKey('machine_type.id'), nullable=False) + device_type_id = db.Column(db.Integer, db.ForeignKey('device_type.id'), nullable=False) item_id = db.Column(db.Integer, db.ForeignKey('item.id')) interfaces = db.relationship('Interface', backref='host') def __init__(self, **kwargs): - # Automatically convert machine_type as an instance of its class if passed as a string - if 'machine_type' in kwargs: - kwargs['machine_type'] = utils.convert_to_model(kwargs['machine_type'], MachineType) + # Automatically convert device_type as an instance of its class if passed as a string + if 'device_type' in kwargs: + kwargs['device_type'] = utils.convert_to_model(kwargs['device_type'], DeviceType) super().__init__(**kwargs) def __str__(self): @@ -637,7 +637,7 @@ class Host(CreatedMixin, db.Model): d = super().to_dict() d.update({ 'name': self.name, - 'machine_type': str(self.machine_type), + 'device_type': str(self.device_type), 'description': self.description, 'item': utils.format_field(self.item), 'interfaces': [str(interface) for interface in self.interfaces], @@ -713,9 +713,9 @@ class Interface(CreatedMixin, db.Model): 'tags': [str(tag) for tag in self.tags], }) if self.host: - d['machine_type'] = str(self.host.machine_type) + d['device_type'] = str(self.host.device_type) else: - d['machine_type'] = None + d['device_type'] = None return d diff --git a/app/network/forms.py b/app/network/forms.py index 21d17633dba163c14bc70cbde98c019848f79356..ce2ab1b864eeb5d2822c8b0427c431c54bad448a 100644 --- a/app/network/forms.py +++ b/app/network/forms.py @@ -125,12 +125,12 @@ class HostForm(CSEntryForm): Unique(models.Host)], filters=[utils.lowercase_field]) description = TextAreaField('Description') - machine_type_id = SelectField('Machine Type') + device_type_id = SelectField('Device Type') item_id = SelectField('Item', coerce=utils.coerce_to_str_or_none) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.machine_type_id.choices = utils.get_model_choices(models.MachineType) + self.device_type_id.choices = utils.get_model_choices(models.DeviceType) self.item_id.choices = utils.get_model_choices(models.Item, allow_none=True, attr='ics_id') diff --git a/app/network/views.py b/app/network/views.py index 10f16e5d59d3c953ff73ca409e61afaccf394a08..8cc66ef860e5958d5800ccf3a9dfd1901be06ecc 100644 --- a/app/network/views.py +++ b/app/network/views.py @@ -48,7 +48,7 @@ def create_host(): if form.validate_on_submit(): network_id = form.network_id.data host = models.Host(name=form.name.data, - machine_type_id=form.machine_type_id.data, + device_type_id=form.device_type_id.data, description=form.description.data or None, item_id=form.item_id.data) # The total number of tags will always be quite small @@ -93,7 +93,7 @@ def edit_host(name): form = HostForm(request.form, obj=host) if form.validate_on_submit(): host.name = form.name.data - host.machine_type_id = form.machine_type_id.data + host.device_type_id = form.device_type_id.data host.item_id = form.item_id.data host.description = form.description.data or None current_app.logger.debug(f'Trying to update: {host!r}') @@ -113,7 +113,7 @@ def edit_host(name): @login_groups_accepted('admin', 'create') def create_interface(hostname): host = models.Host.query.filter_by(name=hostname).first_or_404() - random_mac = host.machine_type.name == 'Virtual' + random_mac = host.device_type.name == 'Virtual' form = InterfaceForm(request.form, host_id=host.id, interface_name=host.name, random_mac=random_mac) if form.validate_on_submit(): @@ -280,7 +280,7 @@ def create_scope(): @login_required def retrieve_hosts(): data = [(host.name, - str(host.machine_type), + str(host.device_type), host.description, interface.name, interface.ip, diff --git a/app/static/js/hosts.js b/app/static/js/hosts.js index 97b96b36512c68f4f4dcc0f22757ff686da89c7f..9ceee6d1d8fea9c78d05be7c0a4c31ff93446523 100644 --- a/app/static/js/hosts.js +++ b/app/static/js/hosts.js @@ -12,12 +12,12 @@ $(document).ready(function() { ); } - // Enable / disable item_id field depending on machine_type + // Enable / disable item_id field depending on device_type // Item can only be assigned for physical hosts // And check / uncheck random_mac checkbox - function update_machine_type_attributes() { - var machine_type = $("#machine_type_id option:selected").text(); - if( machine_type.startsWith("Physical") ) { + function update_device_type_attributes() { + var device_type = $("#device_type_id option:selected").text(); + if( device_type.startsWith("Physical") ) { $("#item_id").prop("disabled", false); $("#random_mac").prop("checked", false).change(); } else { @@ -62,11 +62,11 @@ $(document).ready(function() { // On register and edit host first page load if( $("#hostForm").length || $("#editHostForm").length ) { - update_machine_type_attributes(); + update_device_type_attributes(); } - $("#machine_type_id").on('change', function() { - update_machine_type_attributes(); + $("#device_type_id").on('change', function() { + update_device_type_attributes(); }); // Prefill interface name with hostname diff --git a/app/templates/network/create_host.html b/app/templates/network/create_host.html index 515296ea80267a167d89e4e44bde9c5f9f2b37db..0f8547678c9f5aee845eba44aa9620962bb7af78 100644 --- a/app/templates/network/create_host.html +++ b/app/templates/network/create_host.html @@ -7,7 +7,7 @@ <form id="hostForm" method="POST"> {{ form.hidden_tag() }} {{ render_field(form.name, class_="text-lowercase") }} - {{ render_field(form.machine_type_id) }} + {{ render_field(form.device_type_id) }} {{ render_field(form.description) }} {{ render_field(form.item_id, disabled=True) }} {{ render_field(form.network_id) }} diff --git a/app/templates/network/edit_host.html b/app/templates/network/edit_host.html index 6de72138aa6bd7ab871f8ea1c539aec031c3ca67..fb4c2cd72d10c71536de67b7a38db128a55213b3 100644 --- a/app/templates/network/edit_host.html +++ b/app/templates/network/edit_host.html @@ -19,7 +19,7 @@ <form id="editHostForm" method="POST"> {{ form.hidden_tag() }} {{ render_field(form.name, class_="text-lowercase") }} - {{ render_field(form.machine_type_id) }} + {{ render_field(form.device_type_id) }} {{ render_field(form.description) }} {{ render_field(form.item_id) }} <div class="form-group row"> diff --git a/app/templates/network/view_host.html b/app/templates/network/view_host.html index bb3818748338a900bdceef1aa86506a06feb0680..6da69299d49bd8eb491dbeb9de1803ac8e6b81aa 100644 --- a/app/templates/network/view_host.html +++ b/app/templates/network/view_host.html @@ -19,9 +19,9 @@ <dl class="row"> <dt class="col-sm-3">Hostname</dt> <dd class="col-sm-9">{{ host.name }}</dd> - <dt class="col-sm-3">Machine Type</dt> - <dd class="col-sm-9">{{ host.machine_type }}</dd> - {% if host.machine_type.name == 'Physical' %} + <dt class="col-sm-3">Device Type</dt> + <dd class="col-sm-9">{{ host.device_type }}</dd> + {% if host.device_type.name == 'Physical' %} <dt class="col-sm-3">Item</dt> <dd class="col-sm-9">{{ link_to_item(host.item) }}</dd> {% endif %} diff --git a/migrations/versions/e07c7bc870be_rename_machine_type_to_device_type.py b/migrations/versions/e07c7bc870be_rename_machine_type_to_device_type.py new file mode 100644 index 0000000000000000000000000000000000000000..59ece8341a253a1f713ed1879f4f69ff0fe75613 --- /dev/null +++ b/migrations/versions/e07c7bc870be_rename_machine_type_to_device_type.py @@ -0,0 +1,50 @@ +"""Rename machine_type to device_type + +Revision ID: e07c7bc870be +Revises: a73eeb144fa1 +Create Date: 2018-04-10 12:34:24.426512 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'e07c7bc870be' +down_revision = 'a73eeb144fa1' +branch_labels = None +depends_on = None + + +def upgrade(): + # Rename the table and constraints + op.rename_table('machine_type', 'device_type') + op.execute('ALTER INDEX pk_machine_type RENAME TO pk_device_type') + op.execute('ALTER TABLE device_type RENAME CONSTRAINT uq_machine_type_name TO uq_device_type_name') + # Rename the foreign key in the host table + op.alter_column('host', 'machine_type_id', new_column_name='device_type_id', existing_type=sa.Integer) + op.drop_constraint('fk_host_machine_type_id_machine_type', 'host', type_='foreignkey') + op.create_foreign_key( + op.f('fk_host_device_type_id_device_type'), + 'host', + 'device_type', + ['device_type_id'], + ['id'] + ) + + +def downgrade(): + # Rename the table and constraints + op.rename_table('device_type', 'machine_type') + op.execute('ALTER INDEX pk_device_type RENAME TO pk_machine_type') + op.execute('ALTER TABLE machine_type RENAME CONSTRAINT uq_device_type_name TO uq_machine_type_name') + # Rename the foreign key in the host table + op.alter_column('host', 'device_type_id', new_column_name='machine_type_id', existing_type=sa.Integer) + op.drop_constraint('fk_host_device_type_id_machine_type', 'host', type_='foreignkey') + op.create_foreign_key( + 'fk_host_machine_type_id_machine_type', + 'host', + 'machine_type', + ['machine_type_id'], + ['id'] + ) diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py index 597f36e64b71d2e5f1f49fbbecb06ab0ffe1a312..3b69217cbe699993ac4976fb2f22b8f47129099c 100644 --- a/tests/functional/conftest.py +++ b/tests/functional/conftest.py @@ -27,7 +27,7 @@ register(factories.ItemFactory) register(factories.NetworkScopeFactory) register(factories.NetworkFactory) register(factories.InterfaceFactory) -register(factories.MachineTypeFactory) +register(factories.DeviceTypeFactory) register(factories.HostFactory) register(factories.MacFactory) register(factories.DomainFactory) diff --git a/tests/functional/factories.py b/tests/functional/factories.py index b101dc6d39b8f5db5f5a61c7775e5cc1899ac428..787fbdc866abd70d1265f0a957e11f928f1e83bf 100644 --- a/tests/functional/factories.py +++ b/tests/functional/factories.py @@ -151,9 +151,9 @@ class InterfaceFactory(factory.alchemy.SQLAlchemyModelFactory): user = factory.SubFactory(UserFactory) -class MachineTypeFactory(factory.alchemy.SQLAlchemyModelFactory): +class DeviceTypeFactory(factory.alchemy.SQLAlchemyModelFactory): class Meta: - model = models.MachineType + model = models.DeviceType sqlalchemy_session = common.Session sqlalchemy_session_persistence = 'commit' @@ -168,7 +168,7 @@ class HostFactory(factory.alchemy.SQLAlchemyModelFactory): name = factory.Sequence(lambda n: f'host{n}') user = factory.SubFactory(UserFactory) - machine_type = factory.SubFactory(MachineTypeFactory) + device_type = factory.SubFactory(DeviceTypeFactory) class MacFactory(factory.alchemy.SQLAlchemyModelFactory): diff --git a/tests/functional/test_api.py b/tests/functional/test_api.py index 6ee8513c211ea65f5a8f7609ed8ff48ea818401c..1393553cbc44c4a7eb1c74daedd002a2c03c959e 100644 --- a/tests/functional/test_api.py +++ b/tests/functional/test_api.py @@ -642,7 +642,7 @@ def test_create_interface(client, network_factory, user_token): response = post(client, f'{API_URL}/network/interfaces', data=data, token=user_token) assert response.status_code == 201 assert {'id', 'network', 'ip', 'name', 'mac', 'domain', - 'host', 'machine_type', 'cnames', 'tags', 'created_at', + 'host', 'device_type', 'cnames', 'tags', 'created_at', 'updated_at', 'user'} == set(response.json.keys()) assert response.json['network'] == network.vlan_name assert response.json['ip'] == '192.168.1.20' @@ -758,22 +758,22 @@ def test_get_hosts(client, host_factory, readonly_token): check_input_is_subset_of_response(response, (host1.to_dict(), host2.to_dict())) -def test_create_host(client, item_factory, machine_type_factory, user_token): +def test_create_host(client, item_factory, device_type_factory, user_token): item = item_factory() - machine_type = machine_type_factory(name='Virtual') - # check that name and machine_type are mandatory + device_type = device_type_factory(name='Virtual') + # check that name and device_type are mandatory response = post(client, f'{API_URL}/network/hosts', data={}, token=user_token) check_response_message(response, "Missing mandatory field 'name'", 422) response = post(client, f'{API_URL}/network/hosts', data={'name': 'myhost'}, token=user_token) - check_response_message(response, "Missing mandatory field 'machine_type'", 422) - response = post(client, f'{API_URL}/network/hosts', data={'machine_type': 'Physical'}, token=user_token) + check_response_message(response, "Missing mandatory field 'device_type'", 422) + response = post(client, f'{API_URL}/network/hosts', data={'device_type': 'Physical'}, token=user_token) check_response_message(response, "Missing mandatory field 'name'", 422) data = {'name': 'my-hostname', - 'machine_type': machine_type.name} + 'device_type': device_type.name} response = post(client, f'{API_URL}/network/hosts', data=data, token=user_token) assert response.status_code == 201 - assert {'id', 'name', 'machine_type', 'description', + assert {'id', 'name', 'device_type', 'description', 'item', 'interfaces', 'created_at', 'updated_at', 'user'} == set(response.json.keys()) assert response.json['name'] == data['name'] @@ -784,7 +784,7 @@ def test_create_host(client, item_factory, machine_type_factory, user_token): # Check that we can pass an item_id data2 = {'name': 'another-hostname', - 'machine_type': machine_type.name, + 'device_type': device_type.name, 'item_id': item.id} response = post(client, f'{API_URL}/network/hosts', data=data2, token=user_token) assert response.status_code == 201 @@ -793,10 +793,10 @@ def test_create_host(client, item_factory, machine_type_factory, user_token): assert models.Host.query.count() == 2 -def test_create_host_as_consultant(client, item_factory, machine_type_factory, consultant_token): - machine_type = machine_type_factory() +def test_create_host_as_consultant(client, item_factory, device_type_factory, consultant_token): + device_type = device_type_factory() data = {'name': 'my-hostname', - 'machine_type': machine_type.name} + 'device_type': device_type.name} response = post(client, f'{API_URL}/network/hosts', data=data, token=consultant_token) assert response.status_code == 201