diff --git a/etc/magnum/policy.json b/etc/magnum/policy.json index 43fc95e318..74b3f84b4e 100644 --- a/etc/magnum/policy.json +++ b/etc/magnum/policy.json @@ -27,13 +27,6 @@ "rc:get_all": "rule:default", "rc:update": "rule:default", - "service:create": "rule:default", - "service:delete": "rule:default", - "service:detail": "rule:default", - "service:get": "rule:default", - "service:get_all": "rule:default", - "service:update": "rule:default", - "container:create": "rule:admin_or_user", "container:delete": "rule:admin_or_user", "container:detail": "rule:default", diff --git a/magnum/conductor/api.py b/magnum/conductor/api.py index 838cf329e9..4402b2f488 100644 --- a/magnum/conductor/api.py +++ b/magnum/conductor/api.py @@ -40,27 +40,6 @@ class API(rpc_service.API): def bay_update(self, bay): return self._call('bay_update', bay=bay) - # Service Operations - - def service_create(self, service): - return self._call('service_create', service=service) - - def service_update(self, service_ident, bay_ident, manifest): - return self._call('service_update', service_ident=service_ident, - bay_ident=bay_ident, manifest=manifest) - - def service_list(self, context, bay_ident): - return self._call('service_list', bay_ident=bay_ident) - - def service_delete(self, service_ident, bay_ident): - return self._call('service_delete', - service_ident=service_ident, - bay_ident=bay_ident) - - def service_show(self, context, service_ident, bay_ident): - return self._call('service_show', service_ident=service_ident, - bay_ident=bay_ident) - # ReplicationController Operations def rc_create(self, rc): diff --git a/magnum/conductor/handlers/k8s_conductor.py b/magnum/conductor/handlers/k8s_conductor.py index c077c73105..c5ba548a8e 100644 --- a/magnum/conductor/handlers/k8s_conductor.py +++ b/magnum/conductor/handlers/k8s_conductor.py @@ -38,159 +38,6 @@ class Handler(object): def __init__(self): super(Handler, self).__init__() - def service_create(self, context, service): - LOG.debug("service_create") - bay = conductor_utils.retrieve_bay(context, service.bay_uuid) - self.k8s_api = k8s.create_k8s_api(context, bay) - manifest = k8s_manifest.parse(service.manifest) - try: - resp = self.k8s_api.create_namespaced_service(body=manifest, - namespace='default') - except rest.ApiException as err: - raise exception.KubernetesAPIFailed(err=err) - - if resp is None: - raise exception.ServiceCreationFailed(bay_uuid=service.bay_uuid) - - service['uuid'] = resp.metadata.uid - service['name'] = resp.metadata.name - service['labels'] = ast.literal_eval(resp.metadata.labels) - service['selector'] = ast.literal_eval(resp.spec.selector) - service['ip'] = resp.spec.cluster_ip - service_value = [] - for p in resp.spec.ports: - ports = p.to_dict() - if not ports['name']: - ports['name'] = 'k8s-service' - service_value.append(ports) - - service['ports'] = service_value - - return service - - def service_update(self, context, service_ident, bay_ident, manifest): - LOG.debug("service_update %s", service_ident) - bay = conductor_utils.retrieve_bay(context, bay_ident) - self.k8s_api = k8s.create_k8s_api(context, bay) - if uuidutils.is_uuid_like(service_ident): - service = objects.Service.get_by_uuid(context, - service_ident, - bay.uuid, - self.k8s_api) - else: - service = objects.Service.get_by_name(context, - service_ident, - bay.uuid, - self.k8s_api) - service_ident = service.name - try: - resp = self.k8s_api.replace_namespaced_service( - name=str(service_ident), - body=manifest, - namespace='default') - except rest.ApiException as err: - raise exception.KubernetesAPIFailed(err=err) - - if resp is None: - raise exception.ServiceNotFound(service=service.uuid) - - service['uuid'] = resp.metadata.uid - service['name'] = resp.metadata.name - service['project_id'] = context.project_id - service['user_id'] = context.user_id - service['bay_uuid'] = bay.uuid - service['labels'] = ast.literal_eval(resp.metadata.labels) - if not resp.spec.selector: - service['selector'] = {} - else: - service['selector'] = ast.literal_eval(resp.spec.selector) - service['ip'] = resp.spec.cluster_ip - service_value = [] - for p in resp.spec.ports: - ports = p.to_dict() - if not ports['name']: - ports['name'] = 'k8s-service' - service_value.append(ports) - - service['ports'] = service_value - - return service - - def service_delete(self, context, service_ident, bay_ident): - LOG.debug("service_delete %s", service_ident) - bay = conductor_utils.retrieve_bay(context, bay_ident) - self.k8s_api = k8s.create_k8s_api(context, bay) - if uuidutils.is_uuid_like(service_ident): - service = objects.Service.get_by_uuid(context, service_ident, - bay.uuid, self.k8s_api) - service_name = service.name - else: - service_name = service_ident - if conductor_utils.object_has_stack(context, bay.uuid): - try: - - self.k8s_api.delete_namespaced_service(name=str(service_name), - namespace='default') - except rest.ApiException as err: - if err.status == 404: - pass - else: - raise exception.KubernetesAPIFailed(err=err) - - def service_show(self, context, service_ident, bay_ident): - LOG.debug("service_show %s", service_ident) - bay = conductor_utils.retrieve_bay(context, bay_ident) - self.k8s_api = k8s.create_k8s_api(context, bay) - if uuidutils.is_uuid_like(service_ident): - service = objects.Service.get_by_uuid(context, service_ident, - bay.uuid, self.k8s_api) - else: - service = objects.Service.get_by_name(context, service_ident, - bay.uuid, self.k8s_api) - - return service - - def service_list(self, context, bay_ident): - bay = conductor_utils.retrieve_bay(context, bay_ident) - self.k8s_api = k8s.create_k8s_api(context, bay) - try: - resp = self.k8s_api.list_namespaced_service(namespace='default') - except rest.ApiException as err: - raise exception.KubernetesAPIFailed(err=err) - - if resp is None: - raise exception.ServiceListNotFound(bay_uuid=bay.uuid) - - services = [] - for service_entry in resp.items: - service = {} - service['uuid'] = service_entry.metadata.uid - service['name'] = service_entry.metadata.name - service['project_id'] = context.project_id - service['user_id'] = context.user_id - service['bay_uuid'] = bay.uuid - service['labels'] = ast.literal_eval( - service_entry.metadata.labels) - if not service_entry.spec.selector: - service['selector'] = {} - else: - service['selector'] = ast.literal_eval( - service_entry.spec.selector) - service['ip'] = service_entry.spec.cluster_ip - service_value = [] - for p in service_entry.spec.ports: - ports = p.to_dict() - if not ports['name']: - ports['name'] = 'k8s-service' - service_value.append(ports) - - service['ports'] = service_value - - service_obj = objects.Service(context, **service) - services.append(service_obj) - - return services - # Replication Controller Operations def rc_create(self, context, rc): LOG.debug("rc_create") diff --git a/magnum/db/api.py b/magnum/db/api.py index fb03a6de56..023a18d166 100644 --- a/magnum/db/api.py +++ b/magnum/db/api.py @@ -288,88 +288,6 @@ class Connection(object): :raises: ContainerNotFound """ - @abc.abstractmethod - def get_service_list(self, context, filters=None, limit=None, - marker=None, sort_key=None, sort_dir=None): - """Get matching services. - - Return a list of the specified columns for all services that match the - specified filters. - - :param context: The security context - :param filters: Filters to apply. Defaults to None. - - :param limit: Maximum number of services to return. - :param marker: the last item of the previous page; we return the next - result set. - :param sort_key: Attribute by which results should be sorted. - :param sort_dir: direction in which results should be sorted. - (asc, desc) - :returns: A list of tuples of the specified columns. - """ - - @abc.abstractmethod - def create_service(self, values): - """Create a new service. - - :param values: A dict containing several items used to identify - and track the service, and several dicts which are - passed into the Drivers when managing this service. - For example: - - :: - - { - 'uuid': uuidutils.generate_uuid(), - 'name': 'example', - 'type': 'virt' - } - :returns: A service. - """ - - @abc.abstractmethod - def get_service_by_id(self, context, service_id): - """Return a service. - - :param context: The security context - :param service_id: The id of a service. - :returns: A service. - """ - - @abc.abstractmethod - def get_service_by_uuid(self, context, service_uuid): - """Return a service. - - :param context: The security context - :param service_uuid: The uuid of a service. - :returns: A service. - """ - - @abc.abstractmethod - def get_service_by_name(self, context, service_name): - """Return a service. - - :param context: The security context - :param service_name: The name of a service - :returns: A service. - """ - - @abc.abstractmethod - def destroy_service(self, service_id): - """Destroy a service and all associated interfaces. - - :param service_id: The id or uuid of a service. - """ - - @abc.abstractmethod - def update_service(self, service_id, values): - """Update properties of a service. - - :param service_id: The id or uuid of a service. - :returns: A service. - :raises: ServiceNotFound - """ - @abc.abstractmethod def get_rc_list(self, context, filters=None, limit=None, marker=None, sort_key=None, sort_dir=None): diff --git a/magnum/db/sqlalchemy/alembic/versions/085e601a39f6_remove_service.py b/magnum/db/sqlalchemy/alembic/versions/085e601a39f6_remove_service.py new file mode 100644 index 0000000000..fee6c0c21c --- /dev/null +++ b/magnum/db/sqlalchemy/alembic/versions/085e601a39f6_remove_service.py @@ -0,0 +1,28 @@ +# 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. +"""remove service object + +Revision ID: 085e601a39f6 +Revises: a1136d335540 +Create Date: 2016-05-25 12:05:30.790282 + +""" + +# revision identifiers, used by Alembic. +revision = '085e601a39f6' +down_revision = 'a1136d335540' + +from alembic import op + + +def upgrade(): + op.drop_table('service') diff --git a/magnum/db/sqlalchemy/api.py b/magnum/db/sqlalchemy/api.py index c73bb83bd0..b64e286e5c 100644 --- a/magnum/db/sqlalchemy/api.py +++ b/magnum/db/sqlalchemy/api.py @@ -193,11 +193,6 @@ class Connection(api.Connection): def destroy_bay(self, bay_id): def destroy_bay_resources(session, bay_uuid): """Checks whether the bay does not have resources.""" - query = model_query(models.Service, session=session) - query = self._add_services_filters(query, {'bay_uuid': bay_uuid}) - if query.count() != 0: - query.delete() - query = model_query(models.ReplicationController, session=session) query = self._add_rcs_filters(query, {'bay_uuid': bay_uuid}) if query.count() != 0: @@ -472,105 +467,6 @@ class Connection(api.Connection): ref.update(values) return ref - def _add_services_filters(self, query, filters): - if filters is None: - filters = {} - - if 'bay_uuid' in filters: - query = query.filter_by(bay_uuid=filters['bay_uuid']) - if 'name' in filters: - query = query.filter_by(name=filters['name']) - if 'ip' in filters: - query = query.filter_by(ip=filters['ip']) - if 'ports' in filters: - query = query.filter_by(ports=filters['ports']) - - return query - - def get_service_list(self, context, filters=None, limit=None, marker=None, - sort_key=None, sort_dir=None): - query = model_query(models.Service) - query = self._add_tenant_filters(context, query) - query = self._add_services_filters(query, filters) - return _paginate_query(models.Service, limit, marker, - sort_key, sort_dir, query) - - def create_service(self, values): - # ensure defaults are present for new services - if not values.get('uuid'): - values['uuid'] = uuidutils.generate_uuid() - - service = models.Service() - service.update(values) - try: - service.save() - except db_exc.DBDuplicateEntry: - raise exception.ServiceAlreadyExists(uuid=values['uuid']) - return service - - def get_service_by_id(self, context, service_id): - query = model_query(models.Service) - query = self._add_tenant_filters(context, query) - query = query.filter_by(id=service_id) - try: - return query.one() - except NoResultFound: - raise exception.ServiceNotFound(service=service_id) - - def get_service_by_uuid(self, context, service_uuid): - query = model_query(models.Service) - query = self._add_tenant_filters(context, query) - query = query.filter_by(uuid=service_uuid) - try: - return query.one() - except NoResultFound: - raise exception.ServiceNotFound(service=service_uuid) - - def get_service_by_name(self, context, service_name): - query = model_query(models.Service) - query = self._add_tenant_filters(context, query) - query = query.filter_by(name=service_name) - try: - return query.one() - except MultipleResultsFound: - raise exception.Conflict('Multiple services exist with same name.' - ' Please use the service uuid instead.') - except NoResultFound: - raise exception.ServiceNotFound(service=service_name) - - def destroy_service(self, service_id): - session = get_session() - with session.begin(): - query = model_query(models.Service, session=session) - query = add_identity_filter(query, service_id) - count = query.delete() - if count != 1: - raise exception.ServiceNotFound(service_id) - - def update_service(self, service_id, values): - # NOTE(dtantsur): this can lead to very strange errors - if 'uuid' in values: - msg = _("Cannot overwrite UUID for an existing Service.") - raise exception.InvalidParameterValue(err=msg) - - return self._do_update_service(service_id, values) - - def _do_update_service(self, service_id, values): - session = get_session() - with session.begin(): - query = model_query(models.Service, session=session) - query = add_identity_filter(query, service_id) - try: - ref = query.with_lockmode('update').one() - except NoResultFound: - raise exception.ServiceNotFound(service=service_id) - - if 'provision_state' in values: - values['provision_updated_at'] = timeutils.utcnow() - - ref.update(values) - return ref - def _add_rcs_filters(self, query, filters): if filters is None: filters = {} diff --git a/magnum/db/sqlalchemy/models.py b/magnum/db/sqlalchemy/models.py index 5d8dbab8ce..6eaa0ddd33 100644 --- a/magnum/db/sqlalchemy/models.py +++ b/magnum/db/sqlalchemy/models.py @@ -195,26 +195,6 @@ class Container(Base): environment = Column(JSONEncodedDict) -class Service(Base): - """Represents a software service.""" - - __tablename__ = 'service' - __table_args__ = ( - schema.UniqueConstraint('uuid', name='uniq_service0uuid'), - table_args() - ) - id = Column(Integer, primary_key=True) - uuid = Column(String(36)) - name = Column(String(255)) - bay_uuid = Column(String(36)) - labels = Column(JSONEncodedDict) - selector = Column(JSONEncodedDict) - ip = Column(String(36)) - ports = Column(JSONEncodedList) - project_id = Column(String(255)) - user_id = Column(String(255)) - - class ReplicationController(Base): """Represents a pod replication controller.""" diff --git a/magnum/objects/__init__.py b/magnum/objects/__init__.py index 91a964e52e..621e3b42ab 100644 --- a/magnum/objects/__init__.py +++ b/magnum/objects/__init__.py @@ -18,7 +18,6 @@ from magnum.objects import certificate from magnum.objects import container from magnum.objects import magnum_service from magnum.objects import replicationcontroller as rc -from magnum.objects import service from magnum.objects import x509keypair @@ -27,7 +26,6 @@ Bay = bay.Bay BayModel = baymodel.BayModel MagnumService = magnum_service.MagnumService ReplicationController = rc.ReplicationController -Service = service.Service X509KeyPair = x509keypair.X509KeyPair Certificate = certificate.Certificate __all__ = (Bay, @@ -35,6 +33,5 @@ __all__ = (Bay, Container, MagnumService, ReplicationController, - Service, X509KeyPair, Certificate) diff --git a/magnum/objects/service.py b/magnum/objects/service.py deleted file mode 100644 index 12088a7ad8..0000000000 --- a/magnum/objects/service.py +++ /dev/null @@ -1,137 +0,0 @@ -# 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. - -import ast - -from k8sclient.client import rest -from oslo_versionedobjects import fields - -from magnum.common import exception -from magnum.db import api as dbapi -from magnum.objects import base -from magnum.objects import fields as magnum_fields - - -@base.MagnumObjectRegistry.register -class Service(base.MagnumPersistentObject, base.MagnumObject, - base.MagnumObjectDictCompat): - # Version 1.0: Initial version - VERSION = '1.0' - - dbapi = dbapi.get_instance() - - fields = { - 'id': fields.IntegerField(), - 'uuid': fields.StringField(nullable=True), - 'name': fields.StringField(nullable=True), - 'project_id': fields.StringField(nullable=True), - 'user_id': fields.StringField(nullable=True), - 'bay_uuid': fields.StringField(nullable=True), - 'labels': fields.DictOfStringsField(nullable=True), - 'selector': fields.DictOfStringsField(nullable=True), - 'ip': fields.StringField(nullable=True), - 'ports': magnum_fields.ListOfDictsField(nullable=True), - 'manifest_url': fields.StringField(nullable=True), - 'manifest': fields.StringField(nullable=True), - } - - @base.remotable_classmethod - def get_by_uuid(cls, context, uuid, bay_uuid, k8s_api): - """Find a service based on service uuid and UUID of the Bay - - :param context: Security context - :param uuid: the uuid of a service. - :param bay_uuid: the UUID of the Bay - :param k8s_api: k8s API object - - :returns: a :class:`Service` object. - """ - try: - resp = k8s_api.list_namespaced_service(namespace='default') - except rest.ApiException as err: - raise exception.KubernetesAPIFailed(err=err) - - if resp is None: - raise exception.ServiceListNotFound(bay_uuid=bay_uuid) - - service = {} - for service_entry in resp.items: - if service_entry.metadata.uid == uuid: - service['uuid'] = service_entry.metadata.uid - service['name'] = service_entry.metadata.name - service['project_id'] = context.project_id - service['user_id'] = context.user_id - service['bay_uuid'] = bay_uuid - service['labels'] = ast.literal_eval( - service_entry.metadata.labels) - if not service_entry.spec.selector: - service['selector'] = {} - else: - service['selector'] = ast.literal_eval( - service_entry.spec.selector) - service['ip'] = service_entry.spec.cluster_ip - service_value = [] - for p in service_entry.spec.ports: - ports = p.to_dict() - if not ports['name']: - ports['name'] = 'k8s-service' - service_value.append(ports) - - service['ports'] = service_value - - service_obj = Service(context, **service) - return service_obj - raise exception.ServiceNotFound(service=uuid) - - @base.remotable_classmethod - def get_by_name(cls, context, name, bay_uuid, k8s_api): - """Find a service based on service name and UUID of the Bay - - :param context: Security context - :param name: the name of a service. - :param bay_uuid: the UUID of the Bay - :param k8s_api: k8s API object - - :returns: a :class:`Service` object. - """ - try: - resp = k8s_api.read_namespaced_service(name=name, - namespace='default') - except rest.ApiException as err: - raise exception.KubernetesAPIFailed(err=err) - - if resp is None: - raise exception.ServiceNotFound(service=name) - - service = {} - service['uuid'] = resp.metadata.uid - service['name'] = resp.metadata.name - service['project_id'] = context.project_id - service['user_id'] = context.user_id - service['bay_uuid'] = bay_uuid - service['labels'] = ast.literal_eval(resp.metadata.labels) - if not resp.spec.selector: - service['selector'] = {} - else: - service['selector'] = ast.literal_eval(resp.spec.selector) - service['ip'] = resp.spec.cluster_ip - service_value = [] - for p in resp.spec.ports: - ports = p.to_dict() - if not ports['name']: - ports['name'] = 'k8s-service' - service_value.append(ports) - - service['ports'] = service_value - - service_obj = Service(context, **service) - return service_obj diff --git a/magnum/tests/fake_policy.py b/magnum/tests/fake_policy.py index a031208c23..87d18f0d37 100644 --- a/magnum/tests/fake_policy.py +++ b/magnum/tests/fake_policy.py @@ -41,13 +41,6 @@ policy_data = """ "rc:get_all": "", "rc:update": "", - "service:create": "", - "service:delete": "", - "service:detail": "", - "service:get": "", - "service:get_all": "", - "service:update": "", - "container:create": "", "container:delete": "", "container:detail": "", diff --git a/magnum/tests/unit/api/controllers/v1/test_bay.py b/magnum/tests/unit/api/controllers/v1/test_bay.py index 03907d41b9..35f4d4b42e 100644 --- a/magnum/tests/unit/api/controllers/v1/test_bay.py +++ b/magnum/tests/unit/api/controllers/v1/test_bay.py @@ -647,12 +647,6 @@ class TestDelete(api_base.FunctionalTest): self.assertEqual('application/json', response.content_type) self.assertTrue(response.json['errors']) - def test_delete_bay_with_services(self): - obj_utils.create_test_service(self.context, bay_uuid=self.bay.uuid) - response = self.delete('/bays/%s' % self.bay.uuid, - expect_errors=True) - self.assertEqual(204, response.status_int) - def test_delete_bay_with_replication_controllers(self): obj_utils.create_test_rc(self.context, bay_uuid=self.bay.uuid) response = self.delete('/bays/%s' % self.bay.uuid, diff --git a/magnum/tests/unit/conductor/handlers/test_k8s_conductor.py b/magnum/tests/unit/conductor/handlers/test_k8s_conductor.py index 77831e9c5b..86fa390e4b 100644 --- a/magnum/tests/unit/conductor/handlers/test_k8s_conductor.py +++ b/magnum/tests/unit/conductor/handlers/test_k8s_conductor.py @@ -27,9 +27,6 @@ class TestK8sConductor(base.TestCase): super(TestK8sConductor, self).setUp() self.kube_handler = k8s_conductor.Handler() - def mock_service(self): - return objects.Service({}) - def mock_rc(self): return objects.ReplicationController({}) @@ -39,137 +36,6 @@ class TestK8sConductor(base.TestCase): def mock_baymodel(self): return objects.BayModel({}) - @patch('magnum.objects.Bay.get_by_name') - @patch('magnum.conductor.k8s_api.create_k8s_api') - @patch('ast.literal_eval') - def test_service_create_with_success(self, - mock_ast, - mock_kube_api, - mock_get_bay): - fake_service = mock.MagicMock() - fake_service.name = 'test-name' - - expected_service = mock.MagicMock() - expected_service.bay_uuid = 'test-bay-uuid' - expected_service.name = 'test-name' - expected_service.uuid = 'test-uuid' - manifest = {"key": "value"} - expected_service.manifest = '{"key": "value"}' - mock_ast.return_value = {} - - with patch('magnum.conductor.k8s_api.create_k8s_api') as \ - mock_kube_api: - self.kube_handler.service_create(self.context, expected_service) - (mock_kube_api.return_value.create_namespaced_service - .assert_called_once_with(body=manifest, namespace='default')) - - @patch('magnum.objects.Bay.get_by_name') - def test_service_create_with_failure(self, mock_get_bay): - expected_service = mock.MagicMock() - expected_service.create = mock.MagicMock() - manifest = {"key": "value"} - expected_service.manifest = '{"key": "value"}' - - with patch('magnum.conductor.k8s_api.create_k8s_api') as \ - mock_kube_api: - err = rest.ApiException(status=404) - (mock_kube_api.return_value.create_namespaced_service - .side_effect) = err - - self.assertRaises(exception.KubernetesAPIFailed, - self.kube_handler.service_create, - self.context, expected_service) - (mock_kube_api.return_value.create_namespaced_service - .assert_called_once_with(body=manifest, namespace='default')) - - @patch('magnum.conductor.utils.object_has_stack') - @patch('magnum.objects.Service.get_by_name') - @patch('magnum.objects.Bay.get_by_name') - def test_service_delete_with_success( - self, mock_bay_get_by_name, - mock_service_get_by_name, - mock_object_has_stack): - mock_bay = mock.MagicMock() - mock_bay_get_by_name.return_value = mock_bay - - mock_service = mock.MagicMock() - mock_service.name = 'test-service' - mock_service.uuid = 'test-uuid' - mock_service.bay_uuid = 'test-bay-uuid' - mock_service_get_by_name.return_value = mock_service - - mock_object_has_stack.return_value = True - with patch('magnum.conductor.k8s_api.create_k8s_api') as \ - mock_kube_api: - self.kube_handler.service_delete(self.context, - mock_service.name, - mock_service.bay_uuid) - (mock_kube_api.return_value.delete_namespaced_service - .assert_called_once_with( - name=mock_service.name, namespace='default')) - - @patch('magnum.conductor.utils.object_has_stack') - @patch('magnum.objects.Service.get_by_uuid') - @patch('magnum.objects.Bay.get_by_name') - def test_service_delete_with_failure( - self, mock_bay_get_by_name, - mock_service_get_by_uuid, - mock_object_has_stack): - mock_bay = mock.MagicMock() - mock_bay_get_by_name.return_value = mock_bay - - mock_service = mock.MagicMock() - mock_service.name = 'test-service' - mock_service.uuid = 'test-uuid' - mock_service.bay_uuid = 'test-bay-uuid' - mock_service_get_by_uuid.return_value = mock_service - - mock_object_has_stack.return_value = True - with patch('magnum.conductor.k8s_api.create_k8s_api') as \ - mock_kube_api: - err = rest.ApiException(status=500) - (mock_kube_api.return_value.delete_namespaced_service - .side_effect) = err - - self.assertRaises(exception.KubernetesAPIFailed, - self.kube_handler.service_delete, - self.context, mock_service.name, - mock_service.bay_uuid) - (mock_kube_api.return_value.delete_namespaced_service - .assert_called_once_with( - name=mock_service.name, namespace='default')) - self.assertFalse(mock_service.destroy.called) - - @patch('magnum.conductor.utils.object_has_stack') - @patch('magnum.objects.Service.get_by_uuid') - @patch('magnum.objects.Bay.get_by_name') - def test_service_delete_succeeds_when_not_found( - self, mock_bay_get_by_name, - mock_service_get_by_uuid, - mock_object_has_stack): - mock_bay = mock.MagicMock() - mock_bay_get_by_name.return_value = mock_bay - - mock_service = mock.MagicMock() - mock_service.name = 'test-service' - mock_service.uuid = 'test-uuid' - mock_service.bay_uuid = 'test-bay-uuid' - mock_service_get_by_uuid.return_value = mock_service - - mock_object_has_stack.return_value = True - with patch('magnum.conductor.k8s_api.create_k8s_api') as \ - mock_kube_api: - err = rest.ApiException(status=404) - (mock_kube_api.return_value.delete_namespaced_service - .side_effect) = err - - self.kube_handler.service_delete(self.context, - mock_service.name, - mock_service.bay_uuid) - (mock_kube_api.return_value.delete_namespaced_service - .assert_called_once_with( - name=mock_service.name, namespace='default')) - @patch('magnum.conductor.utils.retrieve_bay') @patch('ast.literal_eval') def test_rc_create_with_success(self, mock_ast, mock_retrieve): @@ -363,70 +229,3 @@ class TestK8sConductor(base.TestCase): .assert_called_once_with(body=expected_rc.manifest, name=name_rc, namespace='default')) - - @patch('magnum.objects.Service.get_by_name') - @patch('magnum.objects.Service.get_by_uuid') - @patch('magnum.objects.Bay.get_by_name') - @patch('ast.literal_eval') - def test_service_update_with_success(self, mock_ast, - mock_bay_get_by_name, - mock_service_get_by_uuid, - mock_service_get_by_name): - mock_bay = mock.MagicMock() - mock_bay_get_by_name.return_value = mock_bay - - expected_service = mock.MagicMock() - expected_service.uuid = 'test-uuid' - expected_service.name = 'test-name' - expected_service.bay_uuid = 'test-bay-uuid' - expected_service.manifest = '{"key": "value"}' - mock_ast.return_value = {} - - mock_service_get_by_name.return_value = expected_service - mock_service_get_by_uuid.return_value = expected_service - service_name = expected_service.name - - with patch('magnum.conductor.k8s_api.create_k8s_api') as \ - mock_kube_api: - self.kube_handler.service_update(self.context, - expected_service.name, - expected_service.bay_uuid, - expected_service.manifest) - (mock_kube_api.return_value.replace_namespaced_service - .assert_called_once_with(body=expected_service.manifest, - name=service_name, - namespace='default')) - - @patch('magnum.objects.Service.get_by_name') - @patch('magnum.objects.Service.get_by_uuid') - @patch('magnum.objects.Bay.get_by_name') - def test_service_update_with_failure(self, mock_bay_get_by_name, - mock_service_get_by_uuid, - mock_service_get_by_name): - mock_bay = mock.MagicMock() - mock_bay_get_by_name.return_value = mock_bay - - expected_service = mock.MagicMock() - expected_service.uuid = 'test-uuid' - expected_service.name = 'test-name' - expected_service.bay_uuid = 'test-bay-uuid' - expected_service.manifest = '{"key": "value"}' - mock_service_get_by_uuid.return_value = expected_service - mock_service_get_by_name.return_value = expected_service - service_name = expected_service.name - - with patch('magnum.conductor.k8s_api.create_k8s_api') as \ - mock_kube_api: - err = rest.ApiException(status=404) - (mock_kube_api.return_value.replace_namespaced_service - .side_effect) = err - - self.assertRaises(exception.KubernetesAPIFailed, - self.kube_handler.service_update, - self.context, expected_service.name, - expected_service.bay_uuid, - expected_service.manifest) - (mock_kube_api.return_value.replace_namespaced_service - .assert_called_once_with(body=expected_service.manifest, - name=service_name, - namespace='default')) diff --git a/magnum/tests/unit/conductor/test_rpcapi.py b/magnum/tests/unit/conductor/test_rpcapi.py index 51d749ba09..2f25b3b9df 100644 --- a/magnum/tests/unit/conductor/test_rpcapi.py +++ b/magnum/tests/unit/conductor/test_rpcapi.py @@ -30,7 +30,6 @@ class RPCAPITestCase(base.DbTestCase): self.fake_bay = dbutils.get_test_bay(driver='fake-driver') self.fake_container = dbutils.get_test_container(driver='fake-driver') self.fake_rc = dbutils.get_test_rc(driver='fake-driver') - self.fake_service = dbutils.get_test_service(driver='fake-driver') self.fake_certificate = objects.Certificate.from_db_bay(self.fake_bay) self.fake_certificate.csr = 'fake-csr' @@ -99,32 +98,6 @@ class RPCAPITestCase(base.DbTestCase): version='1.1', bay=self.fake_bay['name']) - def test_service_create(self): - self._test_rpcapi('service_create', - 'call', - version='1.0', - service=self.fake_service) - - def test_service_update(self): - self._test_rpcapi('service_update', - 'call', - version='1.0', - service_ident=self.fake_service['uuid'], - bay_ident=self.fake_service['bay_uuid'], - manifest={}) - - def test_service_delete(self): - self._test_rpcapi('service_delete', - 'call', - version='1.0', - service_ident=self.fake_service['uuid'], - bay_ident=self.fake_service['bay_uuid']) - self._test_rpcapi('service_delete', - 'call', - version='1.1', - service_ident=self.fake_service['uuid'], - bay_ident=self.fake_service['bay_uuid']) - def test_rc_create(self): self._test_rpcapi('rc_create', 'call', diff --git a/magnum/tests/unit/conductor/test_utils.py b/magnum/tests/unit/conductor/test_utils.py index 4e5e2d136e..969ab45b02 100644 --- a/magnum/tests/unit/conductor/test_utils.py +++ b/magnum/tests/unit/conductor/test_utils.py @@ -27,13 +27,6 @@ class TestConductorUtils(base.TestCase): mock_bay_get_by_uuid.assert_called_once_with(expected_context, expected_bay_uuid) - @patch('magnum.objects.Bay.get_by_uuid') - def test_retrieve_bay_from_service(self, - mock_bay_get_by_uuid): - service = objects.Service({}) - service.bay_uuid = '5d12f6fd-a196-4bf0-ae4c-1f639a523a52' - self._test_retrieve_bay(service.bay_uuid, mock_bay_get_by_uuid) - @patch('magnum.objects.Bay.get_by_uuid') def test_retrieve_bay_from_rc(self, mock_bay_get_by_uuid): diff --git a/magnum/tests/unit/db/test_bay.py b/magnum/tests/unit/db/test_bay.py index 96fc8ddc64..5f8644c3ad 100644 --- a/magnum/tests/unit/db/test_bay.py +++ b/magnum/tests/unit/db/test_bay.py @@ -192,24 +192,6 @@ class DbBayTestCase(base.DbTestCase): self.dbapi.destroy_bay, '12345678-9999-0000-aaaa-123456789012') - def test_destroy_bay_that_has_services(self): - bay = utils.create_test_bay() - service = utils.create_test_service(bay_uuid=bay.uuid) - self.assertEqual(bay.uuid, service.bay_uuid) - self.dbapi.destroy_bay(bay.id) - self.assertRaises(exception.ServiceNotFound, - self.dbapi.get_service_by_id, - self.context, service.id) - - def test_destroy_bay_that_has_services_by_uuid(self): - bay = utils.create_test_bay() - service = utils.create_test_service(bay_uuid=bay.uuid) - self.assertEqual(bay.uuid, service.bay_uuid) - self.dbapi.destroy_bay(bay.id) - self.assertRaises(exception.ServiceNotFound, - self.dbapi.get_service_by_id, - self.context, service.id) - def test_destroy_bay_that_has_rc(self): bay = utils.create_test_bay() rc = utils.create_test_rc(bay_uuid=bay.uuid) diff --git a/magnum/tests/unit/db/test_service.py b/magnum/tests/unit/db/test_service.py deleted file mode 100644 index 3365dd5ed2..0000000000 --- a/magnum/tests/unit/db/test_service.py +++ /dev/null @@ -1,178 +0,0 @@ -# Copyright 2015 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -"""Tests for manipulating Services via the DB API""" - -from oslo_utils import uuidutils -import six - -from magnum.common import exception -from magnum.tests.unit.db import base -from magnum.tests.unit.db import utils as utils - - -class DbServiceTestCase(base.DbTestCase): - - def setUp(self): - # This method creates a service for every test and - # replaces a test for creating a service. - super(DbServiceTestCase, self).setUp() - self.bay = utils.create_test_bay() - self.service = utils.create_test_service(bay_uuid=self.bay.uuid) - - def test_create_service_duplicated_uuid(self): - self.assertRaises(exception.ServiceAlreadyExists, - utils.create_test_service, - uuid=self.service.uuid, - bay_uuid=self.bay.uuid) - - def test_get_service_by_id(self): - res = self.dbapi.get_service_by_id(self.context, self.service.id) - self.assertEqual(self.service.id, res.id) - self.assertEqual(self.service.uuid, res.uuid) - - def test_get_service_by_uuid(self): - res = self.dbapi.get_service_by_uuid(self.context, self.service.uuid) - self.assertEqual(self.service.id, res.id) - self.assertEqual(self.service.uuid, res.uuid) - - def test_get_service_by_name(self): - res = self.dbapi.get_service_by_name(self.context, self.service.name) - self.assertEqual(self.service.id, res.id) - self.assertEqual(self.service.uuid, res.uuid) - - def test_get_service_by_name_multiple_service(self): - utils.create_test_service(bay_uuid=self.bay.uuid, - uuid=uuidutils.generate_uuid()) - self.assertRaises(exception.Conflict, self.dbapi.get_service_by_name, - self.context, self.service.name) - - def test_get_service_by_name_not_found(self): - self.assertRaises(exception.ServiceNotFound, - self.dbapi.get_service_by_name, - self.context, 'not_found') - - def test_get_service_that_does_not_exist(self): - self.assertRaises(exception.ServiceNotFound, - self.dbapi.get_service_by_id, self.context, 999) - self.assertRaises(exception.ServiceNotFound, - self.dbapi.get_service_by_uuid, - self.context, - uuidutils.generate_uuid()) - - def test_get_service_list(self): - uuids = [self.service.uuid] - for i in range(1, 6): - service = utils.create_test_service( - bay_uuid=self.bay.uuid, - uuid=uuidutils.generate_uuid()) - uuids.append(six.text_type(service.uuid)) - res = self.dbapi.get_service_list(self.context) - res_uuids = [r.uuid for r in res] - self.assertEqual(sorted(uuids), sorted(res_uuids)) - - def test_get_service_list_sorted(self): - uuids = [self.service.uuid] - for _ in range(5): - service = utils.create_test_service( - uuid=uuidutils.generate_uuid()) - uuids.append(six.text_type(service.uuid)) - res = self.dbapi.get_service_list(self.context, sort_key='uuid') - res_uuids = [r.uuid for r in res] - self.assertEqual(sorted(uuids), res_uuids) - - self.assertRaises(exception.InvalidParameterValue, - self.dbapi.get_service_list, - self.context, - sort_key='foo') - - def test_get_service_list_with_filters(self): - bay1 = utils.get_test_bay(id=11, uuid=uuidutils.generate_uuid()) - bay2 = utils.get_test_bay(id=12, uuid=uuidutils.generate_uuid()) - self.dbapi.create_bay(bay1) - self.dbapi.create_bay(bay2) - - service1 = utils.create_test_service( - name='service-one', - uuid=uuidutils.generate_uuid(), - bay_uuid=bay1['uuid'], - ports=[{'port': 8000}]) - service2 = utils.create_test_service( - name='service-two', - uuid=uuidutils.generate_uuid(), - bay_uuid=bay2['uuid'], - ports=[{'port': 8001}]) - - res = self.dbapi.get_service_list(self.context, - filters={'bay_uuid': bay1['uuid']}) - self.assertEqual([service1.id], [r.id for r in res]) - - res = self.dbapi.get_service_list(self.context, - filters={'bay_uuid': bay2['uuid']}) - self.assertEqual([service2.id], [r.id for r in res]) - - res = self.dbapi.get_service_list(self.context, - filters={'name': 'service-one'}) - self.assertEqual([service1.id], [r.id for r in res]) - - res = self.dbapi.get_service_list(self.context, - filters={'name': 'bad-service'}) - self.assertEqual([], [r.id for r in res]) - - res = self.dbapi.get_service_list(self.context, - filters={'ports': [{'port': 8000}]}) - self.assertEqual([service1.id], [r.id for r in res]) - - res = self.dbapi.get_service_list(self.context, - filters={'ports': [{'port': 8001}]}) - self.assertEqual([service2.id], [r.id for r in res]) - - def test_get_service_list_bay_not_exist(self): - res = self.dbapi.get_service_list(self.context, filters={ - 'bay_uuid': self.bay.uuid}) - self.assertEqual(1, len(res)) - res = self.dbapi.get_service_list(self.context, filters={ - 'bay_uuid': uuidutils.generate_uuid()}) - self.assertEqual(0, len(res)) - - def test_destroy_service_by_uuid(self): - self.assertIsNotNone(self.dbapi.get_service_by_uuid(self.context, - self.service.uuid)) - self.dbapi.destroy_service(self.service.uuid) - self.assertRaises(exception.ServiceNotFound, - self.dbapi.get_service_by_uuid, - self.context, self.service.uuid) - - def test_destroy_service_that_does_not_exist(self): - self.assertRaises(exception.ServiceNotFound, - self.dbapi.destroy_service, - uuidutils.generate_uuid()) - - def test_update_service(self): - old_name = self.service.name - new_name = 'new-service' - self.assertNotEqual(old_name, new_name) - res = self.dbapi.update_service(self.service.id, {'name': new_name}) - self.assertEqual(new_name, res.name) - - def test_update_service_not_found(self): - service_uuid = uuidutils.generate_uuid() - self.assertRaises(exception.ServiceNotFound, self.dbapi.update_service, - service_uuid, {'port': 80}) - - def test_update_service_uuid(self): - self.assertRaises(exception.InvalidParameterValue, - self.dbapi.update_service, self.service.id, - {'uuid': ''}) diff --git a/magnum/tests/unit/db/utils.py b/magnum/tests/unit/db/utils.py index b31b082f08..6b40ef09da 100644 --- a/magnum/tests/unit/db/utils.py +++ b/magnum/tests/unit/db/utils.py @@ -111,38 +111,6 @@ def create_test_bay(**kw): return dbapi.create_bay(bay) -def get_test_service(**kw): - return { - 'id': kw.get('id', 42), - 'uuid': kw.get('uuid', '10a47dd1-4874-4298-91cf-eff046dbdb8d'), - 'name': kw.get('name', 'service1'), - 'project_id': kw.get('project_id', 'fake_project'), - 'user_id': kw.get('user_id', 'fake_user'), - 'bay_uuid': kw.get('bay_uuid', '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'), - 'labels': kw.get('labels', {'name': 'foo'}), - 'selector': kw.get('selector', {'name': 'foo'}), - 'ip': kw.get('ip', '172.17.2.2'), - 'ports': kw.get('ports', [{'port': 80}]), - 'created_at': kw.get('created_at'), - 'updated_at': kw.get('updated_at'), - } - - -def create_test_service(**kw): - """Create test service entry in DB and return Service DB object. - - Function to be used to create test Service objects in the database. - :param kw: kwargs with overriding values for service's attributes. - :returns: Test Service DB object. - """ - service = get_test_service(**kw) - # Let DB generate ID if it isn't specified explicitly - if 'id' not in kw: - del service['id'] - dbapi = db_api.get_instance() - return dbapi.create_service(service) - - def get_test_container(**kw): return { 'id': kw.get('id', 42), diff --git a/magnum/tests/unit/objects/test_objects.py b/magnum/tests/unit/objects/test_objects.py index a628089665..f23dc052c7 100644 --- a/magnum/tests/unit/objects/test_objects.py +++ b/magnum/tests/unit/objects/test_objects.py @@ -363,7 +363,6 @@ object_data = { 'Container': '1.3-e2d9d2e8a8844d421148cd9fde6c6bd6', 'MyObj': '1.0-b43567e512438205e32f4e95ca616697', 'ReplicationController': '1.0-a471c2429c212ed91833cfcf0f934eab', - 'Service': '1.0-f4a1c5a4618708824a553568c1ada0ea', 'X509KeyPair': '1.2-d81950af36c59a71365e33ce539d24f9', 'MagnumService': '1.0-2d397ec59b0046bd5ec35cd3e06efeca', } diff --git a/magnum/tests/unit/objects/test_service.py b/magnum/tests/unit/objects/test_service.py deleted file mode 100644 index 436167003b..0000000000 --- a/magnum/tests/unit/objects/test_service.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright 2015 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -import mock - -from magnum import objects -from magnum.tests.unit.db import base -from magnum.tests.unit.db import utils - - -class TestServiceObject(base.DbTestCase): - - def setUp(self): - super(TestServiceObject, self).setUp() - self.fake_service = utils.get_test_service() - - @mock.patch('magnum.conductor.k8s_api.create_k8s_api') - @mock.patch('ast.literal_eval') - def test_get_by_uuid(self, mock_ast, mock_kube_api): - uuid = self.fake_service['uuid'] - bay_uuid = self.fake_service['bay_uuid'] - mock_ast.return_value = {} - - k8s_api_mock = mock.MagicMock() - mock_kube_api.return_value = k8s_api_mock - - fake_obj = mock.MagicMock() - - items = [ - { - 'metadata': { - 'uid': '10a47dd1-4874-4298-91cf-eff046dbdb8d', - 'name': 'fake-name', - 'labels': {} - }, - 'spec': { - 'selector': {}, - 'cluster_ip': '10.98.100.19', - 'ports': [ - { - 'port': 80 - } - ] - } - } - ] - - fake_obj.items = items - fake_obj.items[0] = mock.MagicMock() - fake_obj.items[0].metadata = mock.MagicMock() - fake_obj.items[0].metadata.uid = '10a47dd1-4874-4298-91cf-eff046dbdb8d' - fake_obj.items[0].metadata.name = 'fake-name' - fake_obj.items[0].spec = mock.MagicMock() - fake_obj.items[0].spec.selector = {} - fake_obj.items[0].spec.cluster_ip = '10.98.100.19' - - k8s_api_mock.list_namespaced_service.return_value = fake_obj - - objects.Service.get_by_uuid(self.context, - uuid, bay_uuid, - k8s_api_mock) - - (k8s_api_mock.list_namespaced_service.assert_called_once_with( - namespace='default')) - - @mock.patch('magnum.conductor.k8s_api.create_k8s_api') - @mock.patch('ast.literal_eval') - def test_get_by_name(self, mock_ast, mock_kube_api): - name = self.fake_service['name'] - bay_uuid = self.fake_service['bay_uuid'] - mock_ast.return_value = {} - - k8s_api_mock = mock.MagicMock() - mock_kube_api.return_value = k8s_api_mock - fake_service = mock.MagicMock() - fake_service.metadata.uid = 'fake-uuid' - fake_service.metadata.name = 'fake-name' - fake_service.spec.ports.port = ["1234"] - fake_service.spec.selector = {} - fake_service.spec.cluster_ip = '192.10.10.10' - fake_service.metadata.labels = mock_ast.return_value - k8s_api_mock.read_namespaced_service.return_value = fake_service - objects.Service.get_by_name(self.context, - name, bay_uuid, - k8s_api_mock) - (k8s_api_mock.read_namespaced_service.assert_called_once_with( - name=name, - namespace='default')) diff --git a/magnum/tests/unit/objects/utils.py b/magnum/tests/unit/objects/utils.py index c9ebfa8a3b..c428eaaa9f 100644 --- a/magnum/tests/unit/objects/utils.py +++ b/magnum/tests/unit/objects/utils.py @@ -87,33 +87,6 @@ def create_test_bay(context, **kw): return bay -def get_test_service(context, **kw): - """Return a Service object with appropriate attributes. - - NOTE: The object leaves the attributes marked as changed, such - that a create() could be used to commit it to the DB. - """ - db_service = db_utils.get_test_service(**kw) - # Let DB generate ID if it isn't specified explicitly - if 'id' not in kw: - del db_service['id'] - service = objects.Service(context) - for key in db_service: - setattr(service, key, db_service[key]) - return service - - -def create_test_service(context, **kw): - """Create and return a test service object. - - Create a service in the DB and return a Service object with appropriate - attributes. - """ - service = get_test_service(context, **kw) - service.manifest = '{"foo": "bar"}' - return service - - def get_test_rc(context, **kw): """Return a ReplicationController object with appropriate attributes.