diff --git a/nailgun/nailgun/api/v1/handlers/dashboard_entry.py b/nailgun/nailgun/api/v1/handlers/cluster_plugin_link.py similarity index 79% rename from nailgun/nailgun/api/v1/handlers/dashboard_entry.py rename to nailgun/nailgun/api/v1/handlers/cluster_plugin_link.py index 76bb6d1423..b2cd5bd954 100644 --- a/nailgun/nailgun/api/v1/handlers/dashboard_entry.py +++ b/nailgun/nailgun/api/v1/handlers/cluster_plugin_link.py @@ -16,17 +16,22 @@ from nailgun.api.v1.handlers import base from nailgun.api.v1.handlers.base import content -from nailgun.api.v1.validators import dashboard_entry +from nailgun.api.v1.validators import cluster_plugin_link from nailgun.errors import errors from nailgun import objects -class DashboardEntryHandler(base.SingleHandler): +class ClusterPluginLinkHandler(base.SingleHandler): - validator = dashboard_entry.DashboardEntryValidator - single = objects.DashboardEntry + validator = cluster_plugin_link.ClusterPluginLinkValidator + single = objects.ClusterPluginLink def GET(self, cluster_id, obj_id): + """:returns: JSONized REST object. + + :http: * 200 (OK) + * 404 (dashboard entry not found in db) + """ self.get_object_or_404(objects.Cluster, cluster_id) obj = self.get_object_or_404(self.single, obj_id) @@ -37,6 +42,7 @@ class DashboardEntryHandler(base.SingleHandler): """:returns: JSONized REST object. :http: * 200 (OK) + * 400 (invalid object data specified) * 404 (object not found in db) """ obj = self.get_object_or_404(self.single, obj_id) @@ -52,6 +58,7 @@ class DashboardEntryHandler(base.SingleHandler): """:returns: JSONized REST object. :http: * 200 (OK) + * 400 (invalid object data specified) * 404 (object not found in db) """ return self.PUT(cluster_id, obj_id) @@ -60,7 +67,7 @@ class DashboardEntryHandler(base.SingleHandler): def DELETE(self, cluster_id, obj_id): """:returns: JSONized REST object. - :http: * 200 (OK) + :http: * 204 (OK) * 404 (object not found in db) """ d_e = self.get_object_or_404(self.single, obj_id) @@ -68,14 +75,14 @@ class DashboardEntryHandler(base.SingleHandler): raise self.http(204) -class DashboardEntryCollectionHandler(base.CollectionHandler): +class ClusterPluginLinkCollectionHandler(base.CollectionHandler): - collection = objects.DashboardEntryCollection - validator = dashboard_entry.DashboardEntryValidator + collection = objects.ClusterPluginLinkCollection + validator = cluster_plugin_link.ClusterPluginLinkValidator @content def GET(self, cluster_id): - """:returns: Collection of JSONized DashboardEntry objects. + """:returns: Collection of JSONized ClusterPluginLink objects. :http: * 200 (OK) * 404 (cluster not found in db) diff --git a/nailgun/nailgun/api/v1/urls.py b/nailgun/nailgun/api/v1/urls.py index e78c3227c7..fd6ce8104a 100644 --- a/nailgun/nailgun/api/v1/urls.py +++ b/nailgun/nailgun/api/v1/urls.py @@ -38,10 +38,10 @@ from nailgun.api.v1.handlers.cluster import VmwareAttributesDefaultsHandler from nailgun.api.v1.handlers.cluster import VmwareAttributesHandler from nailgun.api.v1.handlers.component import ComponentCollectionHandler -from nailgun.api.v1.handlers.dashboard_entry \ - import DashboardEntryCollectionHandler -from nailgun.api.v1.handlers.dashboard_entry \ - import DashboardEntryHandler +from nailgun.api.v1.handlers.cluster_plugin_link \ + import ClusterPluginLinkCollectionHandler +from nailgun.api.v1.handlers.cluster_plugin_link \ + import ClusterPluginLinkHandler from nailgun.api.v1.handlers.logs import LogEntryCollectionHandler from nailgun.api.v1.handlers.logs import LogPackageDefaultConfig @@ -217,10 +217,10 @@ urls = ( r'/clusters/(?P\d+)/vmware_attributes/defaults/?$', VmwareAttributesDefaultsHandler, - r'/clusters/(?P\d+)/dashboard_entries/?$', - DashboardEntryCollectionHandler, - r'/clusters/(?P\d+)/dashboard_entries/(?P\d+)/?$', - DashboardEntryHandler, + r'/clusters/(?P\d+)/plugin_links/?$', + ClusterPluginLinkCollectionHandler, + r'/clusters/(?P\d+)/plugin_links/(?P\d+)/?$', + ClusterPluginLinkHandler, r'/nodegroups/?$', NodeGroupCollectionHandler, @@ -378,5 +378,5 @@ def public_urls(): r'/nodes/?$': ['POST'], r'/nodes/agent/?$': ['PUT'], r'/version/?$': ['GET'], - r'/clusters/(?P\d+)/dashboard_entries/?$': ['POST'] + r'/clusters/(?P\d+)/plugin_links/?$': ['POST'] } diff --git a/nailgun/nailgun/api/v1/validators/dashboard_entry.py b/nailgun/nailgun/api/v1/validators/cluster_plugin_link.py similarity index 61% rename from nailgun/nailgun/api/v1/validators/dashboard_entry.py rename to nailgun/nailgun/api/v1/validators/cluster_plugin_link.py index 3abbaf1cb1..dfb4840aba 100644 --- a/nailgun/nailgun/api/v1/validators/dashboard_entry.py +++ b/nailgun/nailgun/api/v1/validators/cluster_plugin_link.py @@ -15,24 +15,28 @@ from nailgun.api.v1.validators.base import BasicValidator -from nailgun.api.v1.validators.json_schema import dashboard_entry +from nailgun.api.v1.validators.json_schema import cluster_plugin_link -class DashboardEntryValidator(BasicValidator): - - collection_schema = dashboard_entry.DASHBOARD_ENTRIES_SCHEMA +class ClusterPluginLinkValidator(BasicValidator): + collection_schema = cluster_plugin_link.CLUSTER_PLUGIN_LINKS_SCHEMA @classmethod def validate(cls, data): - parsed = super(DashboardEntryValidator, cls).validate(data) - cls.validate_schema(parsed, dashboard_entry.DASHBOARD_ENTRY_SCHEMA) + parsed = super(ClusterPluginLinkValidator, cls).validate(data) + cls.validate_schema( + parsed, + cluster_plugin_link.CLUSTER_PLUGIN_LINK_SCHEMA + ) return parsed @classmethod def validate_update(cls, data, instance): - parsed = super(DashboardEntryValidator, cls).validate(data) - cls.validate_schema(parsed, - dashboard_entry.DASHBOARD_ENTRY_UPDATE_SCHEMA) + parsed = super(ClusterPluginLinkValidator, cls).validate(data) + cls.validate_schema( + parsed, + cluster_plugin_link.CLUSTER_PLUGIN_LINK_UPDATE_SCHEMA + ) return parsed @classmethod diff --git a/nailgun/nailgun/api/v1/validators/json_schema/dashboard_entry.py b/nailgun/nailgun/api/v1/validators/json_schema/cluster_plugin_link.py similarity index 73% rename from nailgun/nailgun/api/v1/validators/json_schema/dashboard_entry.py rename to nailgun/nailgun/api/v1/validators/json_schema/cluster_plugin_link.py index 49b8206b51..059e1d549f 100644 --- a/nailgun/nailgun/api/v1/validators/json_schema/dashboard_entry.py +++ b/nailgun/nailgun/api/v1/validators/json_schema/cluster_plugin_link.py @@ -13,29 +13,33 @@ # License for the specific language governing permissions and limitations # under the License. -DASHBOARD_ENTRY_SCHEMA = { +CLUSTER_PLUGIN_LINK_SCHEMA = { '$schema': 'http://json-schema.org/draft-04/schema#', 'type': 'object', 'properties': { 'id': {'type': 'integer'}, 'title': {'type': 'string', 'maxLength': 50, 'minLength': 1}, 'url': {'type': 'string'}, - 'description': {'type': 'string'} + 'description': {'type': 'string'}, + 'hidden': {'type': 'boolean'} }, - 'required': ['title', 'url'] + 'required': ['title', 'url'], + 'additionalProperties': False } -DASHBOARD_ENTRIES_SCHEMA = { +CLUSTER_PLUGIN_LINKS_SCHEMA = { '$schema': 'http://json-schema.org/draft-04/schema#', 'type': 'array', - 'items': DASHBOARD_ENTRY_SCHEMA} + 'items': CLUSTER_PLUGIN_LINK_SCHEMA} -DASHBOARD_ENTRY_UPDATE_SCHEMA = { +CLUSTER_PLUGIN_LINK_UPDATE_SCHEMA = { '$schema': 'http://json-schema.org/draft-04/schema#', 'type': 'object', 'properties': { 'title': {'type': 'string', 'maxLength': 50, 'minLength': 1}, 'url': {'type': 'string'}, - 'description': {'type': 'string'} - } + 'description': {'type': 'string'}, + 'hidden': {'type': 'boolean'} + }, + 'additionalProperties': False } diff --git a/nailgun/nailgun/db/migration/alembic_migrations/versions/fuel_8_0.py b/nailgun/nailgun/db/migration/alembic_migrations/versions/fuel_8_0.py index b0e21a3623..ca5987750b 100644 --- a/nailgun/nailgun/db/migration/alembic_migrations/versions/fuel_8_0.py +++ b/nailgun/nailgun/db/migration/alembic_migrations/versions/fuel_8_0.py @@ -106,7 +106,7 @@ def upgrade(): upgrade_cluster_plugins() upgrade_add_baremetal_net() upgrade_with_components() - dashboard_entries_upgrade() + cluster_plugin_links_upgrade() upgrade_master_settings() upgrade_all_network_data_from_string_to_appropriate_data_type() @@ -114,7 +114,7 @@ def upgrade(): def downgrade(): downgrade_all_network_data_to_string() downgrade_master_settings() - dashboard_entries_downgrade() + cluster_plugin_links_downgrade() downgrade_with_components() downgrade_add_baremetal_net() downgrade_cluster_plugins() @@ -513,23 +513,25 @@ def downgrade_with_components(): op.drop_column('releases', 'components_metadata') -def dashboard_entries_upgrade(): +def cluster_plugin_links_upgrade(): op.create_table( - 'dashboard_entries', + 'cluster_plugin_links', sa.Column('id', sa.Integer(), nullable=False), sa.Column('cluster_id', sa.Integer(), nullable=False), sa.Column('title', sa.Text(), nullable=False), sa.Column('url', sa.Text(), nullable=False), sa.Column('description', sa.Text()), + sa.Column( + 'hidden', + sa.Boolean(), + nullable=False, + server_default='false' + ), sa.ForeignKeyConstraint(['cluster_id'], ['clusters.id'], ), sa.PrimaryKeyConstraint('id') ) - op.create_index('dashboard_entries_cluster_id_key', - 'dashboard_entries', ['cluster_id']) - - -def dashboard_entries_downgrade(): - op.drop_table('dashboard_entries') + op.create_index('cluster_plugin_links_cluster_id_key', + 'cluster_plugin_links', ['cluster_id']) def upgrade_all_network_data_from_string_to_appropriate_data_type(): @@ -592,3 +594,7 @@ def ip_type_to_string(table_name, column_name, string_len): column_name, string_len) ) + + +def cluster_plugin_links_downgrade(): + op.drop_table('cluster_plugin_links') diff --git a/nailgun/nailgun/db/sqlalchemy/models/__init__.py b/nailgun/nailgun/db/sqlalchemy/models/__init__.py index e01a4a4815..6bf4a8fb06 100644 --- a/nailgun/nailgun/db/sqlalchemy/models/__init__.py +++ b/nailgun/nailgun/db/sqlalchemy/models/__init__.py @@ -43,7 +43,7 @@ from nailgun.db.sqlalchemy.models.network_config import NeutronConfig from nailgun.db.sqlalchemy.models.network_config import NovaNetworkConfig from nailgun.db.sqlalchemy.models.notification import Notification -from nailgun.db.sqlalchemy.models.dashboard_entry import DashboardEntry +from nailgun.db.sqlalchemy.models.cluster_plugin_link import ClusterPluginLink from nailgun.db.sqlalchemy.models.task import Task diff --git a/nailgun/nailgun/db/sqlalchemy/models/cluster.py b/nailgun/nailgun/db/sqlalchemy/models/cluster.py index a2fedf59ef..1c5452665b 100644 --- a/nailgun/nailgun/db/sqlalchemy/models/cluster.py +++ b/nailgun/nailgun/db/sqlalchemy/models/cluster.py @@ -88,8 +88,8 @@ class Cluster(Base): nodes = relationship( "Node", backref="cluster", cascade="delete", order_by='Node.id') tasks = relationship("Task", backref="cluster", cascade="delete") - dashboard_entries = relationship( - "DashboardEntry", backref="cluster", cascade="delete") + plugin_links = relationship( + "ClusterPluginLink", backref="cluster", cascade="delete") attributes = relationship("Attributes", uselist=False, backref="cluster", cascade="delete") changes_list = relationship("ClusterChanges", backref="cluster", diff --git a/nailgun/nailgun/db/sqlalchemy/models/dashboard_entry.py b/nailgun/nailgun/db/sqlalchemy/models/cluster_plugin_link.py similarity index 81% rename from nailgun/nailgun/db/sqlalchemy/models/dashboard_entry.py rename to nailgun/nailgun/db/sqlalchemy/models/cluster_plugin_link.py index c2c7dd2331..a975330d74 100644 --- a/nailgun/nailgun/db/sqlalchemy/models/dashboard_entry.py +++ b/nailgun/nailgun/db/sqlalchemy/models/cluster_plugin_link.py @@ -14,6 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. +from sqlalchemy import Boolean from sqlalchemy import Column from sqlalchemy import ForeignKey from sqlalchemy import Integer @@ -22,10 +23,11 @@ from sqlalchemy import Text from nailgun.db.sqlalchemy.models.base import Base -class DashboardEntry(Base): - __tablename__ = 'dashboard_entries' +class ClusterPluginLink(Base): + __tablename__ = 'cluster_plugin_links' id = Column(Integer, primary_key=True) - cluster_id = Column(Integer, ForeignKey('clusters.id')) + cluster_id = Column(Integer, ForeignKey('clusters.id'), nullable=False) title = Column(Text, nullable=False) url = Column(Text, nullable=False) description = Column(Text) + hidden = Column(Boolean, default=False) diff --git a/nailgun/nailgun/objects/__init__.py b/nailgun/nailgun/objects/__init__.py index 402a0e2f4c..be56838774 100644 --- a/nailgun/nailgun/objects/__init__.py +++ b/nailgun/nailgun/objects/__init__.py @@ -55,5 +55,5 @@ from nailgun.objects.plugin import ClusterPlugins from nailgun.objects.network_group import NetworkGroup from nailgun.objects.network_group import NetworkGroupCollection -from nailgun.objects.dashboard_entry import DashboardEntry -from nailgun.objects.dashboard_entry import DashboardEntryCollection +from nailgun.objects.cluster_plugin_link import ClusterPluginLink +from nailgun.objects.cluster_plugin_link import ClusterPluginLinkCollection diff --git a/nailgun/nailgun/objects/dashboard_entry.py b/nailgun/nailgun/objects/cluster_plugin_link.py similarity index 61% rename from nailgun/nailgun/objects/dashboard_entry.py rename to nailgun/nailgun/objects/cluster_plugin_link.py index 937f12fe4a..04f2ce74bc 100644 --- a/nailgun/nailgun/objects/dashboard_entry.py +++ b/nailgun/nailgun/objects/cluster_plugin_link.py @@ -14,27 +14,28 @@ # License for the specific language governing permissions and limitations # under the License. -from nailgun.db.sqlalchemy.models import dashboard_entry \ - as dashboard_entry_db_model +from nailgun.db.sqlalchemy.models import cluster_plugin_link \ + as cluster_plugin_link_db_model from nailgun.objects import base -from nailgun.objects.serializers import dashboard_entry +from nailgun.objects.serializers import cluster_plugin_link -class DashboardEntry(base.NailgunObject): +class ClusterPluginLink(base.NailgunObject): - model = dashboard_entry_db_model.DashboardEntry - serializer = dashboard_entry.DashboardEntrySerializer + model = cluster_plugin_link_db_model.ClusterPluginLink + serializer = cluster_plugin_link.ClusterPluginLinkSerializer -class DashboardEntryCollection(base.NailgunCollection): +class ClusterPluginLinkCollection(base.NailgunCollection): - single = DashboardEntry + single = ClusterPluginLink @classmethod def get_by_cluster_id(cls, cluster_id): - if cluster_id == '': - return cls.filter_by(None, cluster_id=None) - return cls.filter_by(None, cluster_id=cluster_id) + if cluster_id is not None: + return cls.filter_by(None, cluster_id=cluster_id) + else: + return cls.all() @classmethod def create_with_cluster_id(cls, data, cluster_id): diff --git a/nailgun/nailgun/objects/serializers/dashboard_entry.py b/nailgun/nailgun/objects/serializers/cluster_plugin_link.py similarity index 89% rename from nailgun/nailgun/objects/serializers/dashboard_entry.py rename to nailgun/nailgun/objects/serializers/cluster_plugin_link.py index b2c76fd0c4..9f7b44e6bb 100644 --- a/nailgun/nailgun/objects/serializers/dashboard_entry.py +++ b/nailgun/nailgun/objects/serializers/cluster_plugin_link.py @@ -17,11 +17,12 @@ from nailgun.objects.serializers.base import BasicSerializer -class DashboardEntrySerializer(BasicSerializer): +class ClusterPluginLinkSerializer(BasicSerializer): fields = ( "id", "title", "url", - "description" + "description", + "hidden" ) diff --git a/nailgun/nailgun/statistics/fuel_statistics/installation_info.py b/nailgun/nailgun/statistics/fuel_statistics/installation_info.py index eac188751d..9c451e5abf 100644 --- a/nailgun/nailgun/statistics/fuel_statistics/installation_info.py +++ b/nailgun/nailgun/statistics/fuel_statistics/installation_info.py @@ -195,8 +195,8 @@ class InstallationInfo(object): vmware_attributes_editable, self.vmware_attributes_white_list ), - 'dashboard_entries': self.get_dashboard_entries( - cluster.dashboard_entries), + 'plugin_links': self.get_cluster_plugin_links( + cluster.plugin_links), 'net_provider': cluster.net_provider, 'fuel_version': cluster.fuel_version, 'is_customized': cluster.is_customized, @@ -306,9 +306,9 @@ class InstallationInfo(object): groups_info.append(group_info) return groups_info - def get_dashboard_entries(self, dashboard_entries): + def get_cluster_plugin_links(self, plugin_links): return [{'title': e.title, 'description': e.description, 'id': e.id} - for e in dashboard_entries] + for e in plugin_links] def get_installation_info(self): clusters_info = self.get_clusters_info() diff --git a/nailgun/nailgun/test/base.py b/nailgun/nailgun/test/base.py index cc49f4f4d9..2768f36559 100644 --- a/nailgun/nailgun/test/base.py +++ b/nailgun/nailgun/test/base.py @@ -23,6 +23,7 @@ except ImportError: import mock import os import re +import six import time import uuid @@ -53,7 +54,7 @@ from nailgun.logger import logger from nailgun.db.sqlalchemy.fixman import load_fake_deployment_tasks from nailgun.db.sqlalchemy.fixman import load_fixture from nailgun.db.sqlalchemy.fixman import upload_fixture -from nailgun.db.sqlalchemy.models import DashboardEntry +from nailgun.db.sqlalchemy.models import ClusterPluginLink from nailgun.db.sqlalchemy.models import NodeAttributes from nailgun.db.sqlalchemy.models import NodeNICInterface from nailgun.db.sqlalchemy.models import Notification @@ -447,22 +448,23 @@ class EnvironmentManager(object): ClusterPlugins.set_attributes(cluster.id, plugin.id, enabled=True) return plugin - def create_dashboard_entry(self, **kwargs): + def create_cluster_plugin_link(self, **kwargs): dash_data = { "title": "title", "url": "url", "description": "description", - "cluster_id": None + "cluster_id": None, + "hidden": False } if kwargs: dash_data.update(kwargs) - dashboard_entry = DashboardEntry() - dashboard_entry.cluster_id = dash_data.get("cluster_id") - for f, v in dash_data.iteritems(): - setattr(dashboard_entry, f, v) - self.db.add(dashboard_entry) + cluster_plugin_link = ClusterPluginLink() + cluster_plugin_link.cluster_id = dash_data.get("cluster_id") + for f, v in six.iteritems(dash_data): + setattr(cluster_plugin_link, f, v) + self.db.add(cluster_plugin_link) self.db.commit() - return dashboard_entry + return cluster_plugin_link def default_metadata(self): item = self.find_item_by_pk_model( diff --git a/nailgun/nailgun/test/integration/test_cluster_plugin_links_collection_handler.py b/nailgun/nailgun/test/integration/test_cluster_plugin_links_collection_handler.py new file mode 100644 index 0000000000..65df3bcbb3 --- /dev/null +++ b/nailgun/nailgun/test/integration/test_cluster_plugin_links_collection_handler.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- + +# Copyright 2015 Mirantis, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +from nailgun.test.base import BaseIntegrationTest +from nailgun.utils import reverse +from oslo.serialization import jsonutils + + +class TestAssignmentHandlers(BaseIntegrationTest): + def setUp(self): + super(TestAssignmentHandlers, self).setUp() + self.cluster = self.env.create( + cluster_kwargs={"api": True}, + nodes_kwargs=[{}] + ) + self.cluster_data = { + 'title': 'test title', + 'url': 'http://test.com/url', + 'description': 'short description' + } + + def test_cluster_plugin_links_list_empty(self): + resp = self.app.get( + reverse( + 'ClusterPluginLinkCollectionHandler', + kwargs={'cluster_id': self.cluster['id']} + ), + headers=self.default_headers + ) + self.assertEqual(200, resp.status_code) + self.assertItemsEqual([], resp.json_body) + + def test_cluster_plugin_link_creation(self): + resp = self.app.post( + reverse( + 'ClusterPluginLinkCollectionHandler', + kwargs={'cluster_id': self.cluster['id']} + ), + params=jsonutils.dumps(self.cluster_data), + headers=self.default_headers + ) + self.assertEqual(201, resp.status_code) + + plugin_link = self.env.clusters[0].plugin_links[0] + self.assertEqual(self.cluster_data['title'], plugin_link.title) + self.assertEqual(self.cluster_data['url'], plugin_link.url) + self.assertEqual( + self.cluster_data['description'], + plugin_link.description + ) + + def test_cluster_plugin_link_fail_creation(self): + resp = self.app.post( + reverse( + 'ClusterPluginLinkCollectionHandler', + kwargs={'cluster_id': self.cluster['id']} + ), + jsonutils.dumps({ + 'title': self.cluster_data['title'], + 'description': self.cluster_data['description'] + }), + headers=self.default_headers, + expect_errors=True + ) + self.assertEqual(400, resp.status_code) + self.assertItemsEqual([], self.env.clusters[0].plugin_links) diff --git a/nailgun/nailgun/test/integration/test_cluster_plugin_links_handler.py b/nailgun/nailgun/test/integration/test_cluster_plugin_links_handler.py new file mode 100644 index 0000000000..80e61a5139 --- /dev/null +++ b/nailgun/nailgun/test/integration/test_cluster_plugin_links_handler.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- + +# Copyright 2015 Mirantis, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from nailgun.db.sqlalchemy.models.cluster_plugin_link import ClusterPluginLink +from nailgun.test.base import BaseIntegrationTest +from nailgun.utils import reverse +from oslo.serialization import jsonutils + + +class TestHandlers(BaseIntegrationTest): + + def setUp(self): + super(TestHandlers, self).setUp() + self.cluster = self.env.create_cluster(api=False) + self.cluster_plugin_link = self.env \ + .create_cluster_plugin_link(cluster_id=self.cluster.id) + + def test_cluster_plugin_link_update(self): + cluster_plugin_link_update = { + 'title': 'new title 2', + 'description': 'new description 2' + } + + resp = self.app.put( + reverse( + 'ClusterPluginLinkHandler', + kwargs={'cluster_id': self.cluster['id'], + 'obj_id': self.cluster_plugin_link.id} + ), + jsonutils.dumps(cluster_plugin_link_update), + headers=self.default_headers + ) + self.assertEqual(self.cluster_plugin_link.id, resp.json_body['id']) + self.assertEqual('new title 2', resp.json_body['title']) + self.assertEqual('new description 2', resp.json_body['description']) + self.assertEqual(self.cluster_plugin_link.url, resp.json_body['url']) + + def test_cluster_plugin_link_get_with_cluster(self): + resp = self.app.get( + reverse( + 'ClusterPluginLinkHandler', + kwargs={'cluster_id': self.cluster['id'], + 'obj_id': self.cluster_plugin_link.id} + ), + headers=self.default_headers + ) + self.assertEqual(200, resp.status_code) + self.assertEqual(self.cluster_plugin_link.id, resp.json_body['id']) + self.assertEqual(self.cluster_plugin_link.title, + resp.json_body['title']) + self.assertEqual(self.cluster_plugin_link.url, resp.json_body['url']) + self.assertEqual(self.cluster_plugin_link.description, + resp.json_body['description']) + self.assertEqual(self.cluster_plugin_link.hidden, + resp.json_body['hidden']) + + def test_cluster_plugin_link_not_found(self): + resp = self.app.get( + reverse( + 'ClusterPluginLinkHandler', + kwargs={'cluster_id': self.cluster['id'], + 'obj_id': self.cluster_plugin_link.id + 1} + ), + headers=self.default_headers, + expect_errors=True + ) + self.assertEqual(404, resp.status_code) + + def test_cluster_plugin_link_delete(self): + resp = self.app.delete( + reverse( + 'ClusterPluginLinkHandler', + kwargs={'cluster_id': self.cluster['id'], + 'obj_id': self.cluster_plugin_link.id} + ), + headers=self.default_headers, + ) + self.assertEqual(204, resp.status_code) + + d_e_query = self.db.query(ClusterPluginLink) \ + .filter_by(cluster_id=self.cluster.id) + self.assertEquals(d_e_query.count(), 0) + + def test_cluster_plugin_link_patch(self): + cluster_plugin_link_update = { + 'title': 'new title 3', + 'description': 'new description 3', + 'hidden': True + } + + resp = self.app.patch( + reverse( + 'ClusterPluginLinkHandler', + kwargs={'cluster_id': self.cluster['id'], + 'obj_id': self.cluster_plugin_link.id} + ), + jsonutils.dumps(cluster_plugin_link_update), + headers=self.default_headers + ) + self.assertEqual(self.cluster_plugin_link.id, resp.json_body['id']) + self.assertEqual('new title 3', resp.json_body['title']) + self.assertEqual('new description 3', resp.json_body['description']) + self.assertEqual(self.cluster_plugin_link.url, resp.json_body['url']) + self.assertEqual(True, resp.json_body['hidden']) diff --git a/nailgun/nailgun/test/unit/fuel_statistics_tests/test_installation_info.py b/nailgun/nailgun/test/unit/fuel_statistics_tests/test_installation_info.py index eddfad325a..b1bc1409e4 100644 --- a/nailgun/nailgun/test/unit/fuel_statistics_tests/test_installation_info.py +++ b/nailgun/nailgun/test/unit/fuel_statistics_tests/test_installation_info.py @@ -371,6 +371,7 @@ class TestInstallationInfo(BaseTestCase): ('plugins', 'installed_plugins'), ('networking_configs', 'network_configuration'), ('release_id', 'release'), + ('cluster_plugin_links', 'plugin_links'), ) for name_from, name_to in rename_fields: cluster_schema.pop(name_from) diff --git a/nailgun/nailgun/test/unit/test_dashboard_entry_collection_handler.py b/nailgun/nailgun/test/unit/test_dashboard_entry_collection_handler.py deleted file mode 100644 index c2a52a12c3..0000000000 --- a/nailgun/nailgun/test/unit/test_dashboard_entry_collection_handler.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2015 Mirantis, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -from nailgun.test.base import BaseIntegrationTest -from nailgun.utils import reverse -from oslo.serialization import jsonutils - - -class TestAssignmentHandlers(BaseIntegrationTest): - def test_dashboard_entries_list_empty(self): - cluster = self.env.create( - cluster_kwargs={"api": True}, - nodes_kwargs=[{}] - ) - - resp = self.app.get( - reverse( - 'DashboardEntryCollectionHandler', - kwargs={'cluster_id': cluster['id']} - ), - headers=self.default_headers - ) - self.assertEqual(200, resp.status_code) - self.assertEqual([], resp.json_body) - - def test_dashboard_entry_creation(self): - cluster = self.env.create( - cluster_kwargs={"api": True}, - nodes_kwargs=[{}] - ) - - title = 'test title' - url = 'http://test.com/url' - description = 'short description' - resp = self.app.post( - reverse( - 'DashboardEntryCollectionHandler', - kwargs={'cluster_id': cluster['id']} - ), - params=jsonutils.dumps({ - "title": title, - "url": url, - "description": description - }), - headers=self.default_headers - ) - self.assertEqual(resp.status_code, 201) - - dashboard_entry = self.env.clusters[0].dashboard_entries[0] - self.assertEqual(dashboard_entry.title, title) - self.assertEqual(dashboard_entry.url, url) - self.assertEqual(dashboard_entry.description, description) - - def test_dashboard_entry_fail_creation(self): - cluster = self.env.create( - cluster_kwargs={"api": True}, - nodes_kwargs=[{}] - ) - - title = 'test title' - description = 'short description' - - resp = self.app.post( - reverse( - 'DashboardEntryCollectionHandler', - kwargs={'cluster_id': cluster['id']} - ), - jsonutils.dumps({ - 'title': title, - 'description': description - }), - headers=self.default_headers, - expect_errors=True - ) - self.assertEqual(resp.status_code, 400) - self.assertEqual(len(self.env.clusters[0].dashboard_entries), 0) diff --git a/nailgun/nailgun/test/unit/test_dashboard_entry_handler.py b/nailgun/nailgun/test/unit/test_dashboard_entry_handler.py deleted file mode 100644 index a751d351e2..0000000000 --- a/nailgun/nailgun/test/unit/test_dashboard_entry_handler.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2015 Mirantis, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from nailgun.db.sqlalchemy.models.dashboard_entry import DashboardEntry -from nailgun.test.base import BaseIntegrationTest -from nailgun.utils import reverse -from oslo.serialization import jsonutils - - -class TestHandlers(BaseIntegrationTest): - - def test_dashboard_entry_update(self): - cluster = self.env.create_cluster(api=False) - dashboard_entry = self.env \ - .create_dashboard_entry(cluster_id=cluster.id) - - dashboard_entry_update = { - 'title': 'new title 2', - 'description': 'new description 2' - } - - resp = self.app.put( - reverse( - 'DashboardEntryHandler', - kwargs={'cluster_id': cluster['id'], - 'obj_id': dashboard_entry.id} - ), - jsonutils.dumps(dashboard_entry_update), - headers=self.default_headers - ) - self.assertEqual(dashboard_entry.id, resp.json_body['id']) - self.assertEqual('new title 2', resp.json_body['title']) - self.assertEqual('new description 2', resp.json_body['description']) - self.assertEqual(dashboard_entry.url, resp.json_body['url']) - - def test_dashboard_entry_get_with_cluster(self): - cluster = self.env.create_cluster(api=False) - dashboard_entry = self.env \ - .create_dashboard_entry(cluster_id=cluster.id) - - resp = self.app.get( - reverse( - 'DashboardEntryHandler', - kwargs={'cluster_id': cluster['id'], - 'obj_id': dashboard_entry.id} - ), - headers=self.default_headers - ) - self.assertEqual(200, resp.status_code) - self.assertEqual(dashboard_entry.id, resp.json_body['id']) - self.assertEqual(dashboard_entry.title, resp.json_body['title']) - self.assertEqual(dashboard_entry.url, resp.json_body['url']) - self.assertEqual(dashboard_entry.description, - resp.json_body['description']) - - def test_dashboard_entry_not_found(self): - cluster = self.env.create_cluster(api=False) - dashboard_entry = self.env \ - .create_dashboard_entry(cluster_id=cluster.id) - resp = self.app.get( - reverse( - 'DashboardEntryHandler', - kwargs={'cluster_id': cluster['id'], - 'obj_id': dashboard_entry.id + 1} - ), - headers=self.default_headers, - expect_errors=True - ) - self.assertEqual(404, resp.status_code) - - def test_dashboard_entry_delete(self): - cluster = self.env.create_cluster(api=False) - dashboard_entry = self.env \ - .create_dashboard_entry(cluster_id=cluster.id) - resp = self.app.delete( - reverse( - 'DashboardEntryHandler', - kwargs={'cluster_id': cluster['id'], - 'obj_id': dashboard_entry.id} - ), - headers=self.default_headers, - ) - self.assertEqual(204, resp.status_code) - - d_e_query = self.db.query(DashboardEntry) \ - .filter_by(cluster_id=cluster.id) - self.assertEquals(d_e_query.count(), 0) - - def test_dashboard_entry_patch(self): - cluster = self.env.create_cluster(api=False) - dashboard_entry = self.env \ - .create_dashboard_entry(cluster_id=cluster.id) - - dashboard_entry_update = { - 'title': 'new title 3', - 'description': 'new description 3' - } - - resp = self.app.patch( - reverse( - 'DashboardEntryHandler', - kwargs={'cluster_id': cluster['id'], - 'obj_id': dashboard_entry.id} - ), - jsonutils.dumps(dashboard_entry_update), - headers=self.default_headers - ) - self.assertEqual(dashboard_entry.id, resp.json_body['id']) - self.assertEqual('new title 3', resp.json_body['title']) - self.assertEqual('new description 3', resp.json_body['description']) - self.assertEqual(dashboard_entry.url, resp.json_body['url']) diff --git a/nailgun/nailgun/test/unit/test_migration_fuel_8_0.py b/nailgun/nailgun/test/unit/test_migration_fuel_8_0.py index c0662891bc..e9bbc952c5 100644 --- a/nailgun/nailgun/test/unit/test_migration_fuel_8_0.py +++ b/nailgun/nailgun/test/unit/test_migration_fuel_8_0.py @@ -472,3 +472,21 @@ class TestMasterSettingsMigration(base.BaseAlembicMigrationTest): bootstrap_settings, jsonutils.loads(result.scalar())['bootstrap'] ) + + +class TestClusterPluginLinks(base.BaseAlembicMigrationTest): + def test_cluster_plugin_links_creation(self): + clusters = self.meta.tables['clusters'] + cluster_plugin_links = self.meta.tables['cluster_plugin_links'] + + cluster_id = db.execute(sa.select([clusters])).scalar() + + db.execute( + cluster_plugin_links.insert(), + [{ + 'cluster_id': cluster_id, + 'title': 'title', + 'url': 'http://www.zzz.com', + 'description': 'description', + 'hidden': False + }])