Remove ReplicationController object
Following the removal of service [1], pod [2] and container [3], remove COE specific object ReplicationController. This change also removes k8s_conductor. [1] I4f06bb779caa0ad369a2b96b4714e1bf2db8acc6 [2] I8c2499ccb97aae39d80868ce02fbef292d762c10 [3] I288fa7a9717519b1ae8195820975676d99b4d6d2 Change-Id: Ica100c8d2dfdd7dc709feb1f5cdc5a3f3d6c7318 Partially-Implements: blueprint delete-container-endpoint Partially-Implements: blueprint bay-driverschanges/05/352905/2
parent
2e7b98f702
commit
e6a29fb252
|
@ -39,8 +39,6 @@ There are several different types of objects in the magnum system:
|
|||
machine
|
||||
* **Service:** An abstraction which defines a logical set of pods and a policy
|
||||
by which to access them
|
||||
* **ReplicationController:** An abstraction for managing a group of pods to
|
||||
ensure a specified number of resources are running
|
||||
* **Container:** A Docker container
|
||||
|
||||
Two binaries work together to compose the magnum system. The first binary
|
||||
|
|
|
@ -87,7 +87,6 @@ magnum/tests/unit/objects/test_objects.py::
|
|||
'Container': '1.1-22b40e8eed0414561ca921906b189820',
|
||||
'MyObj': '1.0-b43567e512438205e32f4e95ca616697',
|
||||
'Pod': '1.0-69b579203c6d726be7878c606626e438',
|
||||
'ReplicationController': '1.0-782b7deb9307b2807101541b7e58b8a2',
|
||||
'Service': '1.0-d4b8c0f3a234aec35d273196e18f7ed1',
|
||||
'X509KeyPair': '1.0-fd008eba0fbc390e0e5da247bba4eedd',
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ from magnum.conductor.handlers import bay_conductor
|
|||
from magnum.conductor.handlers import ca_conductor
|
||||
from magnum.conductor.handlers import conductor_listener
|
||||
from magnum.conductor.handlers import indirection_api
|
||||
from magnum.conductor.handlers import k8s_conductor
|
||||
from magnum.i18n import _LI
|
||||
from magnum import version
|
||||
|
||||
|
@ -50,7 +49,6 @@ def main():
|
|||
conductor_id = short_id.generate_id()
|
||||
endpoints = [
|
||||
indirection_api.Handler(),
|
||||
k8s_conductor.Handler(),
|
||||
bay_conductor.Handler(),
|
||||
conductor_listener.Handler(),
|
||||
ca_conductor.Handler(),
|
||||
|
|
|
@ -273,24 +273,6 @@ class PodCreationFailed(Invalid):
|
|||
message = _("Pod creation failed in Bay %(bay_uuid)s.")
|
||||
|
||||
|
||||
class ReplicationControllerNotFound(ResourceNotFound):
|
||||
message = _("ReplicationController %(rc)s could not be found.")
|
||||
|
||||
|
||||
class ReplicationControllerAlreadyExists(Conflict):
|
||||
message = _("A ReplicationController with UUID %(uuid)s already exists.")
|
||||
|
||||
|
||||
class ReplicationControllerListNotFound(ResourceNotFound):
|
||||
message = _("ReplicationController list could not be found"
|
||||
" for Bay %(bay_uuid)s.")
|
||||
|
||||
|
||||
class ReplicationControllerCreationFailed(Invalid):
|
||||
message = _("ReplicationController creation failed"
|
||||
" for Bay %(bay_uuid)s.")
|
||||
|
||||
|
||||
class ServiceNotFound(ResourceNotFound):
|
||||
message = _("Service %(service)s could not be found.")
|
||||
|
||||
|
|
|
@ -40,25 +40,6 @@ class API(rpc_service.API):
|
|||
def bay_update(self, bay):
|
||||
return self._call('bay_update', bay=bay)
|
||||
|
||||
# ReplicationController Operations
|
||||
|
||||
def rc_create(self, rc):
|
||||
return self._call('rc_create', rc=rc)
|
||||
|
||||
def rc_update(self, rc_ident, bay_ident, manifest):
|
||||
return self._call('rc_update', rc_ident=rc_ident,
|
||||
bay_ident=bay_ident, manifest=manifest)
|
||||
|
||||
def rc_list(self, context, bay_ident):
|
||||
return self._call('rc_list', bay_ident=bay_ident)
|
||||
|
||||
def rc_delete(self, rc_ident, bay_ident):
|
||||
return self._call('rc_delete', rc_ident=rc_ident, bay_ident=bay_ident)
|
||||
|
||||
def rc_show(self, context, rc_ident, bay_ident):
|
||||
return self._call('rc_show', rc_ident=rc_ident,
|
||||
bay_ident=bay_ident)
|
||||
|
||||
# CA operations
|
||||
|
||||
def sign_certificate(self, bay, certificate):
|
||||
|
|
|
@ -1,167 +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.
|
||||
|
||||
|
||||
from k8sclient.client import rest
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from magnum.common import exception
|
||||
from magnum.common import k8s_manifest
|
||||
from magnum.conductor import k8s_api as k8s
|
||||
from magnum.conductor import utils as conductor_utils
|
||||
from magnum import objects
|
||||
|
||||
import ast
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Handler(object):
|
||||
"""Magnum Kubernetes RPC handler.
|
||||
|
||||
These are the backend operations. They are executed by the backend service.
|
||||
API calls via AMQP (within the ReST API) trigger the handlers to be called.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super(Handler, self).__init__()
|
||||
|
||||
# Replication Controller Operations
|
||||
def rc_create(self, context, rc):
|
||||
LOG.debug("rc_create")
|
||||
bay = conductor_utils.retrieve_bay(context, rc.bay_uuid)
|
||||
self.k8s_api = k8s.create_k8s_api(context, bay)
|
||||
manifest = k8s_manifest.parse(rc.manifest)
|
||||
try:
|
||||
resp = self.k8s_api.create_namespaced_replication_controller(
|
||||
body=manifest,
|
||||
namespace='default')
|
||||
except rest.ApiException as err:
|
||||
raise exception.KubernetesAPIFailed(err=err)
|
||||
|
||||
if resp is None:
|
||||
raise exception.ReplicationControllerCreationFailed(
|
||||
bay_uuid=rc.bay_uuid)
|
||||
|
||||
rc['uuid'] = resp.metadata.uid
|
||||
rc['name'] = resp.metadata.name
|
||||
rc['images'] = [c.image for c in resp.spec.template.spec.containers]
|
||||
rc['labels'] = ast.literal_eval(resp.metadata.labels)
|
||||
rc['replicas'] = resp.status.replicas
|
||||
return rc
|
||||
|
||||
def rc_update(self, context, rc_ident, bay_ident, manifest):
|
||||
LOG.debug("rc_update %s", rc_ident)
|
||||
bay = conductor_utils.retrieve_bay(context, bay_ident)
|
||||
self.k8s_api = k8s.create_k8s_api(context, bay)
|
||||
if uuidutils.is_uuid_like(rc_ident):
|
||||
rc = objects.ReplicationController.get_by_uuid(context, rc_ident,
|
||||
bay.uuid,
|
||||
self.k8s_api)
|
||||
else:
|
||||
rc = objects.ReplicationController.get_by_name(context, rc_ident,
|
||||
bay.uuid,
|
||||
self.k8s_api)
|
||||
try:
|
||||
resp = self.k8s_api.replace_namespaced_replication_controller(
|
||||
name=str(rc.name),
|
||||
body=manifest,
|
||||
namespace='default')
|
||||
except rest.ApiException as err:
|
||||
raise exception.KubernetesAPIFailed(err=err)
|
||||
|
||||
if resp is None:
|
||||
raise exception.ReplicationControllerNotFound(rc=rc.uuid)
|
||||
|
||||
rc['uuid'] = resp.metadata.uid
|
||||
rc['name'] = resp.metadata.name
|
||||
rc['project_id'] = context.project_id
|
||||
rc['user_id'] = context.user_id
|
||||
rc['images'] = [c.image for c in resp.spec.template.spec.containers]
|
||||
rc['bay_uuid'] = bay.uuid
|
||||
rc['labels'] = ast.literal_eval(resp.metadata.labels)
|
||||
rc['replicas'] = resp.status.replicas
|
||||
|
||||
return rc
|
||||
|
||||
def rc_delete(self, context, rc_ident, bay_ident):
|
||||
LOG.debug("rc_delete %s", rc_ident)
|
||||
bay = conductor_utils.retrieve_bay(context, bay_ident)
|
||||
self.k8s_api = k8s.create_k8s_api(context, bay)
|
||||
if uuidutils.is_uuid_like(rc_ident):
|
||||
rc = objects.ReplicationController.get_by_uuid(context, rc_ident,
|
||||
bay.uuid,
|
||||
self.k8s_api)
|
||||
rc_name = rc.name
|
||||
else:
|
||||
rc_name = rc_ident
|
||||
if conductor_utils.object_has_stack(context, bay.uuid):
|
||||
try:
|
||||
self.k8s_api.delete_namespaced_replication_controller(
|
||||
name=str(rc_name),
|
||||
body={},
|
||||
namespace='default')
|
||||
except rest.ApiException as err:
|
||||
if err.status == 404:
|
||||
pass
|
||||
else:
|
||||
raise exception.KubernetesAPIFailed(err=err)
|
||||
|
||||
def rc_show(self, context, rc_ident, bay_ident):
|
||||
LOG.debug("rc_show %s", rc_ident)
|
||||
bay = conductor_utils.retrieve_bay(context, bay_ident)
|
||||
self.k8s_api = k8s.create_k8s_api(context, bay)
|
||||
if uuidutils.is_uuid_like(rc_ident):
|
||||
rc = objects.ReplicationController.get_by_uuid(context, rc_ident,
|
||||
bay.uuid,
|
||||
self.k8s_api)
|
||||
else:
|
||||
rc = objects.ReplicationController.get_by_name(context, rc_ident,
|
||||
bay.uuid,
|
||||
self.k8s_api)
|
||||
|
||||
return rc
|
||||
|
||||
def rc_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_replication_controller(
|
||||
namespace='default')
|
||||
except rest.ApiException as err:
|
||||
raise exception.KubernetesAPIFailed(err=err)
|
||||
|
||||
if resp is None:
|
||||
raise exception.ReplicationControllerListNotFound(
|
||||
bay_uuid=bay.uuid)
|
||||
|
||||
rcs = []
|
||||
for entry in resp._items:
|
||||
rc = {}
|
||||
rc['uuid'] = entry.metadata.uid
|
||||
rc['name'] = entry.metadata.name
|
||||
rc['project_id'] = context.project_id
|
||||
rc['user_id'] = context.user_id
|
||||
rc['images'] = [
|
||||
c.image for c in entry.spec.template.spec.containers]
|
||||
rc['bay_uuid'] = bay.uuid
|
||||
# Convert string to dictionary
|
||||
rc['labels'] = ast.literal_eval(entry.metadata.labels)
|
||||
rc['replicas'] = entry.status.replicas
|
||||
|
||||
rc_obj = objects.ReplicationController(context, **rc)
|
||||
rcs.append(rc_obj)
|
||||
|
||||
return rcs
|
|
@ -204,86 +204,6 @@ class Connection(object):
|
|||
:raises: BayModelNotFound
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_rc_list(self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
"""Get matching ReplicationControllers.
|
||||
|
||||
Return a list of the specified columns for all rcs that match the
|
||||
specified filters.
|
||||
|
||||
:param context: The security context
|
||||
:param filters: Filters to apply. Defaults to None.
|
||||
|
||||
:param limit: Maximum number of pods 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_rc(self, values):
|
||||
"""Create a new ReplicationController.
|
||||
|
||||
:param values: A dict containing several items used to identify
|
||||
and track the rc, and several dicts which are passed
|
||||
into the Drivers when managing this pod. For example:
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
'uuid': uuidutils.generate_uuid(),
|
||||
'name': 'example',
|
||||
'images': '["myimage"]'
|
||||
}
|
||||
:returns: A ReplicationController.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_rc_by_id(self, context, rc_id):
|
||||
"""Return a ReplicationController.
|
||||
|
||||
:param context: The security context
|
||||
:param rc_id: The id of a rc.
|
||||
:returns: A ReplicationController.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_rc_by_uuid(self, context, rc_uuid):
|
||||
"""Return a ReplicationController.
|
||||
|
||||
:param context: The security context
|
||||
:param rc_uuid: The uuid of a ReplicationController.
|
||||
:returns: A ReplicationController.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_rc_by_name(self, context, rc_name):
|
||||
"""Return a ReplicationController.
|
||||
|
||||
:param context: The security context
|
||||
:param rc_name: The name of a ReplicationController.
|
||||
:returns: A ReplicationController.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def destroy_rc(self, rc_id):
|
||||
"""Destroy a ReplicationController and all associated interfaces.
|
||||
|
||||
:param rc_id: The id or uuid of a ReplicationController.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_rc(self, rc_id, values):
|
||||
"""Update properties of a ReplicationController.
|
||||
|
||||
:param rc_id: The id or uuid of a ReplicationController.
|
||||
:returns: A ReplicationController.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_x509keypair(self, values):
|
||||
"""Create a new x509keypair.
|
||||
|
|
|
@ -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 replication controller
|
||||
|
||||
Revision ID: 859fb45df249
|
||||
Revises: 1f196a3dabae
|
||||
Create Date: 2016-08-09 13:46:24.052528
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '859fb45df249'
|
||||
down_revision = '1f196a3dabae'
|
||||
|
||||
from alembic import op
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.drop_table('replicationcontroller')
|
|
@ -191,24 +191,16 @@ class Connection(api.Connection):
|
|||
raise exception.BayNotFound(bay=bay_uuid)
|
||||
|
||||
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.ReplicationController, session=session)
|
||||
query = self._add_rcs_filters(query, {'bay_uuid': bay_uuid})
|
||||
if query.count() != 0:
|
||||
query.delete()
|
||||
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(models.Bay, session=session)
|
||||
query = add_identity_filter(query, bay_id)
|
||||
|
||||
try:
|
||||
bay_ref = query.one()
|
||||
query.one()
|
||||
except NoResultFound:
|
||||
raise exception.BayNotFound(bay=bay_id)
|
||||
|
||||
destroy_bay_resources(session, bay_ref['uuid'])
|
||||
query.delete()
|
||||
|
||||
def update_bay(self, bay_id, values):
|
||||
|
@ -365,100 +357,6 @@ class Connection(api.Connection):
|
|||
ref.update(values)
|
||||
return ref
|
||||
|
||||
def _add_rcs_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 'replicas' in filters:
|
||||
query = query.filter_by(replicas=filters['replicas'])
|
||||
|
||||
return query
|
||||
|
||||
def get_rc_list(self, context, filters=None, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None):
|
||||
query = model_query(models.ReplicationController)
|
||||
query = self._add_tenant_filters(context, query)
|
||||
query = self._add_rcs_filters(query, filters)
|
||||
return _paginate_query(models.ReplicationController, limit, marker,
|
||||
sort_key, sort_dir, query)
|
||||
|
||||
def create_rc(self, values):
|
||||
# ensure defaults are present for new ReplicationController
|
||||
if not values.get('uuid'):
|
||||
values['uuid'] = uuidutils.generate_uuid()
|
||||
|
||||
rc = models.ReplicationController()
|
||||
rc.update(values)
|
||||
try:
|
||||
rc.save()
|
||||
except db_exc.DBDuplicateEntry:
|
||||
raise exception.ReplicationControllerAlreadyExists(
|
||||
uuid=values['uuid'])
|
||||
return rc
|
||||
|
||||
def get_rc_by_id(self, context, rc_id):
|
||||
query = model_query(models.ReplicationController)
|
||||
query = self._add_tenant_filters(context, query)
|
||||
query = query.filter_by(id=rc_id)
|
||||
try:
|
||||
return query.one()
|
||||
except NoResultFound:
|
||||
raise exception.ReplicationControllerNotFound(rc=rc_id)
|
||||
|
||||
def get_rc_by_uuid(self, context, rc_uuid):
|
||||
query = model_query(models.ReplicationController)
|
||||
query = self._add_tenant_filters(context, query)
|
||||
query = query.filter_by(uuid=rc_uuid)
|
||||
try:
|
||||
return query.one()
|
||||
except NoResultFound:
|
||||
raise exception.ReplicationControllerNotFound(rc=rc_uuid)
|
||||
|
||||
def get_rc_by_name(self, context, rc_name):
|
||||
query = model_query(models.ReplicationController)
|
||||
query = self._add_tenant_filters(context, query)
|
||||
query = query.filter_by(name=rc_name)
|
||||
try:
|
||||
return query.one()
|
||||
except MultipleResultsFound:
|
||||
raise exception.Conflict('Multiple rcs exist with same name.'
|
||||
' Please use the rc uuid instead.')
|
||||
except NoResultFound:
|
||||
raise exception.ReplicationControllerNotFound(rc=rc_name)
|
||||
|
||||
def destroy_rc(self, rc_id):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(models.ReplicationController, session=session)
|
||||
query = add_identity_filter(query, rc_id)
|
||||
count = query.delete()
|
||||
if count != 1:
|
||||
raise exception.ReplicationControllerNotFound(rc_id)
|
||||
|
||||
def update_rc(self, rc_id, values):
|
||||
if 'uuid' in values:
|
||||
msg = _("Cannot overwrite UUID for an existing rc.")
|
||||
raise exception.InvalidParameterValue(err=msg)
|
||||
|
||||
return self._do_update_rc(rc_id, values)
|
||||
|
||||
def _do_update_rc(self, rc_id, values):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(models.ReplicationController, session=session)
|
||||
query = add_identity_filter(query, rc_id)
|
||||
try:
|
||||
ref = query.with_lockmode('update').one()
|
||||
except NoResultFound:
|
||||
raise exception.ReplicationControllerNotFound(rc=rc_id)
|
||||
|
||||
ref.update(values)
|
||||
return ref
|
||||
|
||||
def create_x509keypair(self, values):
|
||||
# ensure defaults are present for new x509keypairs
|
||||
if not values.get('uuid'):
|
||||
|
|
|
@ -179,26 +179,6 @@ class BayModel(Base):
|
|||
master_lb_enabled = Column(Boolean, default=False)
|
||||
|
||||
|
||||
class ReplicationController(Base):
|
||||
"""Represents a pod replication controller."""
|
||||
|
||||
__tablename__ = 'replicationcontroller'
|
||||
__table_args__ = (
|
||||
schema.UniqueConstraint('uuid',
|
||||
name='uniq_replicationcontroller0uuid'),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
uuid = Column(String(36))
|
||||
name = Column(String(255))
|
||||
bay_uuid = Column(String(36))
|
||||
images = Column(JSONEncodedList)
|
||||
labels = Column(JSONEncodedDict)
|
||||
replicas = Column(Integer())
|
||||
project_id = Column(String(255))
|
||||
user_id = Column(String(255))
|
||||
|
||||
|
||||
class X509KeyPair(Base):
|
||||
"""X509KeyPair"""
|
||||
__tablename__ = 'x509keypair'
|
||||
|
|
|
@ -40,10 +40,6 @@ msgstr "'add' と 'replace' 処理には、値が必要です。"
|
|||
msgid "'manifest' can't be empty"
|
||||
msgstr "「マニフェスト」は空にできません"
|
||||
|
||||
#, python-format
|
||||
msgid "A ReplicationController with UUID %(uuid)s already exists."
|
||||
msgstr "UUID %(uuid)s の複製コントローラーは既に存在します。"
|
||||
|
||||
#, python-format
|
||||
msgid "A baymodel with UUID %(uuid)s already exists."
|
||||
msgstr "UUID %(uuid)s のベイモデルは既に存在します。"
|
||||
|
@ -341,10 +337,6 @@ msgstr ""
|
|||
"OpenStack サービスとの通信に使用する Identity サービスカタログ内のリージョ"
|
||||
"ン。"
|
||||
|
||||
#, python-format
|
||||
msgid "ReplicationController %(rc)s could not be found."
|
||||
msgstr "複製コントローラー %(rc)s が見つかりませんでした。"
|
||||
|
||||
msgid "Request not acceptable."
|
||||
msgstr "要求は受け入れられませんでした。"
|
||||
|
||||
|
|
|
@ -16,19 +16,16 @@ from magnum.objects import bay
|
|||
from magnum.objects import baymodel
|
||||
from magnum.objects import certificate
|
||||
from magnum.objects import magnum_service
|
||||
from magnum.objects import replicationcontroller as rc
|
||||
from magnum.objects import x509keypair
|
||||
|
||||
|
||||
Bay = bay.Bay
|
||||
BayModel = baymodel.BayModel
|
||||
MagnumService = magnum_service.MagnumService
|
||||
ReplicationController = rc.ReplicationController
|
||||
X509KeyPair = x509keypair.X509KeyPair
|
||||
Certificate = certificate.Certificate
|
||||
__all__ = (Bay,
|
||||
BayModel,
|
||||
MagnumService,
|
||||
ReplicationController,
|
||||
X509KeyPair,
|
||||
Certificate)
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
# Copyright 2015 IBM Corp.
|
||||
#
|
||||
# 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
|
||||
|
||||
|
||||
@base.MagnumObjectRegistry.register
|
||||
class ReplicationController(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),
|
||||
'images': fields.ListOfStringsField(nullable=True),
|
||||
'bay_uuid': fields.StringField(nullable=True),
|
||||
'labels': fields.DictOfStringsField(nullable=True),
|
||||
'replicas': fields.IntegerField(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):
|
||||
"""Return a :class:`ReplicationController` object based on uuid.
|
||||
|
||||
:param context: Security context
|
||||
:param uuid: the uuid of a ReplicationController.
|
||||
:param bay_uuid: the UUID of the Bay.
|
||||
|
||||
:returns: a :class:`ReplicationController` object.
|
||||
"""
|
||||
try:
|
||||
resp = k8s_api.list_namespaced_replication_controller(
|
||||
namespace='default')
|
||||
except rest.ApiException as err:
|
||||
raise exception.KubernetesAPIFailed(err=err)
|
||||
|
||||
if resp is None:
|
||||
raise exception.ReplicationControllerListNotFound(
|
||||
bay_uuid=bay_uuid)
|
||||
|
||||
rc = {}
|
||||
for entry in resp.items:
|
||||
if entry.metadata.uid == uuid:
|
||||
rc['uuid'] = entry.metadata.uid
|
||||
rc['name'] = entry.metadata.name
|
||||
rc['project_id'] = context.project_id
|
||||
rc['user_id'] = context.user_id
|
||||
rc['images'] = [
|
||||
c.image for c in entry.spec.template.spec.containers]
|
||||
rc['bay_uuid'] = bay_uuid
|
||||
# Convert string to dictionary
|
||||
rc['labels'] = ast.literal_eval(entry.metadata.labels)
|
||||
rc['replicas'] = entry.status.replicas
|
||||
|
||||
rc_obj = ReplicationController(context, **rc)
|
||||
return rc_obj
|
||||
|
||||
raise exception.ReplicationControllerNotFound(rc=uuid)
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_name(cls, context, name, bay_uuid, k8s_api):
|
||||
"""Return a :class:`ReplicationController` object based on name.
|
||||
|
||||
:param context: Security context
|
||||
:param name: the name of a ReplicationController.
|
||||
:param bay_uuid: the UUID of the Bay.
|
||||
|
||||
:returns: a :class:`ReplicationController` object.
|
||||
"""
|
||||
try:
|
||||
resp = k8s_api.read_namespaced_replication_controller(
|
||||
name=name,
|
||||
namespace='default')
|
||||
except rest.ApiException as err:
|
||||
raise exception.KubernetesAPIFailed(err=err)
|
||||
|
||||
if resp is None:
|
||||
raise exception.ReplicationControllerNotFound(rc=name)
|
||||
|
||||
rc = {}
|
||||
rc['uuid'] = resp.metadata.uid
|
||||
rc['name'] = resp.metadata.name
|
||||
rc['project_id'] = context.project_id
|
||||
rc['user_id'] = context.user_id
|
||||
rc['images'] = [c.image for c in resp.spec.template.spec.containers]
|
||||
rc['bay_uuid'] = bay_uuid
|
||||
# Convert string to dictionary
|
||||
rc['labels'] = ast.literal_eval(resp.metadata.labels)
|
||||
rc['replicas'] = resp.status.replicas
|
||||
|
||||
rc_obj = ReplicationController(context, **rc)
|
||||
return rc_obj
|
|
@ -25,7 +25,6 @@ import magnum.common.service
|
|||
import magnum.common.x509.config
|
||||
import magnum.conductor.config
|
||||
import magnum.conductor.handlers.bay_conductor
|
||||
import magnum.conductor.handlers.k8s_conductor
|
||||
import magnum.db
|
||||
import magnum.drivers.common.template_def
|
||||
|
||||
|
|
|
@ -780,12 +780,6 @@ class TestDelete(api_base.FunctionalTest):
|
|||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertTrue(response.json['errors'])
|
||||
|
||||
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,
|
||||
expect_errors=True)
|
||||
self.assertEqual(204, response.status_int)
|
||||
|
||||
def test_delete_bay_with_name_not_found(self):
|
||||
response = self.delete('/bays/not_found', expect_errors=True)
|
||||
self.assertEqual(404, response.status_int)
|
||||
|
|
|
@ -1,231 +0,0 @@
|
|||
# Copyright 2014 NEC Corporation. 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.
|
||||
|
||||
from k8sclient.client import rest
|
||||
import mock
|
||||
from mock import patch
|
||||
|
||||
from magnum.common import exception
|
||||
from magnum.conductor.handlers import k8s_conductor
|
||||
from magnum import objects
|
||||
from magnum.tests import base
|
||||
|
||||
|
||||
class TestK8sConductor(base.TestCase):
|
||||
def setUp(self):
|
||||
super(TestK8sConductor, self).setUp()
|
||||
self.kube_handler = k8s_conductor.Handler()
|
||||
|
||||
def mock_rc(self):
|
||||
return objects.ReplicationController({})
|
||||
|
||||
def mock_bay(self):
|
||||
return objects.Bay({})
|
||||
|
||||
def mock_baymodel(self):
|
||||
return objects.BayModel({})
|
||||
|
||||
@patch('magnum.conductor.utils.retrieve_bay')
|
||||
@patch('ast.literal_eval')
|
||||
def test_rc_create_with_success(self, mock_ast, mock_retrieve):
|
||||
expected_rc = mock.MagicMock()
|
||||
manifest = {"key": "value"}
|
||||
expected_rc.name = 'test-name'
|
||||
expected_rc.uuid = 'test-uuid'
|
||||
expected_rc.bay_uuid = 'test-bay-uuid'
|
||||
expected_rc.manifest = '{"key": "value"}'
|
||||
mock_ast.return_value = {}
|
||||
|
||||
with patch('magnum.conductor.k8s_api.create_k8s_api') as \
|
||||
mock_kube_api:
|
||||
self.kube_handler.rc_create({}, expected_rc)
|
||||
(mock_kube_api.return_value
|
||||
.create_namespaced_replication_controller
|
||||
.assert_called_once_with(body=manifest, namespace='default'))
|
||||
|
||||
@patch('magnum.conductor.utils.retrieve_bay')
|
||||
def test_rc_create_with_failure(self, mock_retrieve):
|
||||
expected_rc = mock.MagicMock()
|
||||
manifest = {"key": "value"}
|
||||
expected_rc.manifest = '{"key": "value"}'
|
||||
|
||||
with patch('magnum.conductor.k8s_api.create_k8s_api') as \
|
||||
mock_kube_api:
|
||||
err = rest.ApiException(status=500)
|
||||
(mock_kube_api.return_value
|
||||
.create_namespaced_replication_controller.side_effect) = err
|
||||
|
||||
self.assertRaises(exception.KubernetesAPIFailed,
|
||||
self.kube_handler.rc_create,
|
||||
self.context, expected_rc)
|
||||
(mock_kube_api.return_value
|
||||
.create_namespaced_replication_controller
|
||||
.assert_called_once_with(body=manifest, namespace='default'))
|
||||
|
||||
@patch('magnum.conductor.utils.object_has_stack')
|
||||
@patch('magnum.objects.ReplicationController.get_by_name')
|
||||
@patch('magnum.objects.Bay.get_by_name')
|
||||
def test_rc_delete_with_success(self, mock_bay_get_by_name,
|
||||
mock_rc_get_by_name,
|
||||
mock_object_has_stack):
|
||||
mock_bay = mock.MagicMock()
|
||||
mock_bay_get_by_name.return_value = mock_bay
|
||||
|
||||
mock_rc = mock.MagicMock()
|
||||
mock_rc.name = 'test-rc'
|
||||
mock_rc.uuid = 'test-uuid'
|
||||
mock_rc_get_by_name.return_value = mock_rc
|
||||
bay_uuid = 'test-bay-uuid'
|
||||
|
||||
mock_object_has_stack.return_value = True
|
||||
with patch('magnum.conductor.k8s_api.create_k8s_api') as \
|
||||
mock_kube_api:
|
||||
self.kube_handler.rc_delete(self.context, mock_rc.name, bay_uuid)
|
||||
(mock_kube_api.return_value
|
||||
.delete_namespaced_replication_controller
|
||||
.assert_called_once_with(name=mock_rc.name, body={},
|
||||
namespace='default'))
|
||||
|
||||
@patch('magnum.conductor.utils.object_has_stack')
|
||||
@patch('magnum.objects.ReplicationController.get_by_uuid')
|
||||
@patch('magnum.objects.Bay.get_by_name')
|
||||
def test_rc_delete_with_failure(self, mock_bay_get_by_name,
|
||||
mock_rc_get_by_uuid,
|
||||
mock_object_has_stack):
|
||||
mock_bay = mock.MagicMock()
|
||||
mock_bay_get_by_name.return_value = mock_bay
|
||||
|
||||
mock_rc = mock.MagicMock()
|
||||
mock_rc.name = 'test-rc'
|
||||
mock_rc.uuid = 'test-uuid'
|
||||
mock_rc.bay_uuid = 'test-bay-uuid'
|
||||
mock_rc_get_by_uuid.return_value = mock_rc
|
||||
|
||||
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_replication_controller.side_effect) = err
|
||||
|
||||
self.assertRaises(exception.KubernetesAPIFailed,
|
||||
self.kube_handler.rc_delete,
|
||||
self.context, mock_rc.name,
|
||||
mock_rc.bay_uuid)
|
||||
|
||||
(mock_kube_api.return_value
|
||||
.delete_namespaced_replication_controller
|
||||
.assert_called_once_with(name=mock_rc.name, body={},
|
||||
namespace='default'))
|
||||
self.assertFalse(mock_rc.destroy.called)
|
||||
|
||||
@patch('magnum.conductor.utils.object_has_stack')
|
||||
@patch('magnum.objects.ReplicationController.get_by_uuid')
|
||||
@patch('magnum.objects.Bay.get_by_name')
|
||||
def test_rc_delete_succeeds_when_not_found(
|
||||
self, mock_bay_get_by_name,
|
||||
mock_rc_get_by_uuid,
|
||||
mock_object_has_stack):
|
||||
mock_bay = mock.MagicMock()
|
||||
mock_bay_get_by_name.return_value = mock_bay
|
||||
|
||||
mock_rc = mock.MagicMock()
|
||||
mock_rc.name = 'test-rc'
|
||||
mock_rc.uuid = 'test-uuid'
|
||||
mock_rc.bay_uuid = 'test-bay-uuid'
|
||||
mock_rc_get_by_uuid.return_value = mock_rc
|
||||
|
||||
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_replication_controller.side_effect) = err
|
||||
|
||||
self.kube_handler.rc_delete(self.context,
|
||||
mock_rc.name,
|
||||
mock_rc.bay_uuid)
|
||||
|
||||
(mock_kube_api.return_value
|
||||
.delete_namespaced_replication_controller
|
||||
.assert_called_once_with(name=mock_rc.name, body={},
|
||||
namespace='default'))
|
||||
|
||||
@patch('magnum.objects.ReplicationController.get_by_name')
|
||||
@patch('magnum.objects.ReplicationController.get_by_uuid')
|
||||
@patch('magnum.objects.Bay.get_by_name')
|
||||
@patch('ast.literal_eval')
|
||||
def test_rc_update_with_success(self, mock_ast,
|
||||
mock_bay_get_by_name,
|
||||
mock_rc_get_by_uuid,
|
||||
mock_rc_get_by_name):
|
||||
mock_bay = mock.MagicMock()
|
||||
mock_bay_get_by_name.return_value = mock_bay
|
||||
|
||||
expected_rc = mock.MagicMock()
|
||||
expected_rc.uuid = 'test-uuid'
|
||||
expected_rc.name = 'test-name'
|
||||
expected_rc.bay_uuid = 'test-bay-uuid'
|
||||
expected_rc.manifest = '{"key": "value"}'
|
||||
mock_ast.return_value = {}
|
||||
mock_rc_get_by_uuid.return_value = expected_rc
|
||||
mock_rc_get_by_name.return_value = expected_rc
|
||||
name_rc = expected_rc.name
|
||||
|
||||
with patch('magnum.conductor.k8s_api.create_k8s_api') as \
|
||||
mock_kube_api:
|
||||
self.kube_handler.rc_update(self.context, expected_rc.name,
|
||||
expected_rc.bay_uuid,
|
||||
expected_rc.manifest)
|
||||
(mock_kube_api.return_value
|
||||
.replace_namespaced_replication_controller
|
||||
.assert_called_once_with(body=expected_rc.manifest,
|
||||
name=name_rc,
|
||||
namespace='default'))
|
||||
|
||||
@patch('magnum.objects.ReplicationController.get_by_name')
|
||||
@patch('magnum.objects.ReplicationController.get_by_uuid')
|
||||
@patch('magnum.objects.Bay.get_by_name')
|
||||
def test_rc_update_with_failure(self, mock_bay_get_by_name,
|
||||
mock_rc_get_by_uuid,
|
||||
mock_rc_get_by_name):
|
||||
mock_bay = mock.MagicMock()
|
||||
mock_bay_get_by_name.return_value = mock_bay
|
||||
|
||||
expected_rc = mock.MagicMock()
|
||||
expected_rc.uuid = 'test-uuid'
|
||||
expected_rc.name = 'test-name'
|
||||
expected_rc.bay_uuid = 'test-bay-uuid'
|
||||
mock_rc_get_by_uuid.return_value = expected_rc
|
||||
mock_rc_get_by_name.return_value = expected_rc
|
||||
expected_rc.manifest = '{"key": "value"}'
|
||||
name_rc = expected_rc.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_replication_controller
|
||||
.side_effect) = err
|
||||
|
||||
self.assertRaises(exception.KubernetesAPIFailed,
|
||||
self.kube_handler.rc_update,
|
||||
self.context, expected_rc.name,
|
||||
expected_rc.bay_uuid,
|
||||
expected_rc.manifest)
|
||||
(mock_kube_api.return_value
|
||||
.replace_namespaced_replication_controller
|
||||
.assert_called_once_with(body=expected_rc.manifest,
|
||||
name=name_rc,
|
||||
namespace='default'))
|
|
@ -28,7 +28,6 @@ class RPCAPITestCase(base.DbTestCase):
|
|||
def setUp(self):
|
||||
super(RPCAPITestCase, self).setUp()
|
||||
self.fake_bay = dbutils.get_test_bay(driver='fake-driver')
|
||||
self.fake_rc = dbutils.get_test_rc(driver='fake-driver')
|
||||
self.fake_certificate = objects.Certificate.from_db_bay(self.fake_bay)
|
||||
self.fake_certificate.csr = 'fake-csr'
|
||||
|
||||
|
@ -97,33 +96,6 @@ class RPCAPITestCase(base.DbTestCase):
|
|||
version='1.1',
|
||||
bay=self.fake_bay['name'])
|
||||
|
||||
def test_rc_create(self):
|
||||
self._test_rpcapi('rc_create',
|
||||
'call',
|
||||
version='1.0',
|
||||
rc=self.fake_rc)
|
||||
|
||||
def test_rc_update(self):
|
||||
self._test_rpcapi('rc_update',
|
||||
'call',
|
||||
version='1.0',
|
||||
rc_ident=self.fake_rc['uuid'],
|
||||
bay_ident=self.fake_rc['bay_uuid'],
|
||||
manifest={})
|
||||
|
||||
def test_rc_delete(self):
|
||||
self._test_rpcapi('rc_delete',
|
||||
'call',
|
||||
version='1.0',
|
||||
rc_ident=self.fake_rc['uuid'],
|
||||
bay_ident=self.fake_rc['bay_uuid'])
|
||||
|
||||
self._test_rpcapi('rc_delete',
|
||||
'call',
|
||||
version='1.1',
|
||||
rc_ident=self.fake_rc['uuid'],
|
||||
bay_ident=self.fake_rc['bay_uuid'])
|
||||
|
||||
def test_ping_conductor(self):
|
||||
self._test_rpcapi('ping_conductor',
|
||||
'call',
|
||||
|
|
|
@ -27,14 +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_rc(self,
|
||||
mock_bay_get_by_uuid):
|
||||
rc = objects.ReplicationController({})
|
||||
rc.bay_uuid = '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'
|
||||
self._test_retrieve_bay(rc.bay_uuid,
|
||||
mock_bay_get_by_uuid)
|
||||
|
||||
@patch('magnum.objects.BayModel.get_by_uuid')
|
||||
def test_retrieve_baymodel(self, mock_baymodel_get_by_uuid):
|
||||
expected_context = 'context'
|
||||
|
|
|
@ -23,44 +23,47 @@ from magnum.tests.unit.db import base
|
|||
class SqlAlchemyCustomTypesTestCase(base.DbTestCase):
|
||||
|
||||
def test_JSONEncodedDict_default_value(self):
|
||||
# Create rc w/o labels
|
||||
rc1_id = uuidutils.generate_uuid()
|
||||
self.dbapi.create_rc({'uuid': rc1_id})
|
||||
rc1 = sa_api.model_query(
|
||||
models.ReplicationController).filter_by(uuid=rc1_id).one()
|
||||
self.assertEqual({}, rc1.labels)
|
||||
# Create baymodel w/o labels
|
||||
baymodel1_id = uuidutils.generate_uuid()
|
||||
self.dbapi.create_baymodel({'uuid': baymodel1_id})
|
||||
baymodel1 = sa_api.model_query(
|
||||
models.BayModel).filter_by(uuid=baymodel1_id).one()
|
||||
self.assertEqual({}, baymodel1.labels)
|
||||
|
||||
# Create rc with labels
|
||||
rc2_id = uuidutils.generate_uuid()
|
||||
self.dbapi.create_rc({'uuid': rc2_id, 'labels': {'bar': 'foo'}})
|
||||
rc2 = sa_api.model_query(
|
||||
models.ReplicationController).filter_by(uuid=rc2_id).one()
|
||||
self.assertEqual('foo', rc2.labels['bar'])
|
||||
# Create baymodel with labels
|
||||
baymodel2_id = uuidutils.generate_uuid()
|
||||
self.dbapi.create_baymodel(
|
||||
{'uuid': baymodel2_id, 'labels': {'bar': 'foo'}})
|
||||
baymodel2 = sa_api.model_query(
|
||||
models.BayModel).filter_by(uuid=baymodel2_id).one()
|
||||
self.assertEqual('foo', baymodel2.labels['bar'])
|
||||
|
||||
def test_JSONEncodedDict_type_check(self):
|
||||
self.assertRaises(db_exc.DBError,
|
||||
self.dbapi.create_rc,
|
||||
self.dbapi.create_baymodel,
|
||||
{'labels':
|
||||
['this is not a dict']})
|
||||
|
||||
def test_JSONEncodedList_default_value(self):
|
||||
# Create rc w/o images
|
||||
rc1_id = uuidutils.generate_uuid()
|
||||
self.dbapi.create_rc({'uuid': rc1_id})
|
||||
rc1 = sa_api.model_query(
|
||||
models.ReplicationController).filter_by(uuid=rc1_id).one()
|
||||
self.assertEqual([], rc1.images)
|
||||
# Create bay w/o master_addresses
|
||||
bay1_id = uuidutils.generate_uuid()
|
||||
self.dbapi.create_bay({'uuid': bay1_id})
|
||||
bay1 = sa_api.model_query(
|
||||
models.Bay).filter_by(uuid=bay1_id).one()
|
||||
self.assertEqual([], bay1.master_addresses)
|
||||
|
||||
# Create rc with images
|
||||
rc2_id = uuidutils.generate_uuid()
|
||||
self.dbapi.create_rc({'uuid': rc2_id,
|
||||
'images': ['myimage1', 'myimage2']})
|
||||
rc2 = sa_api.model_query(
|
||||
models.ReplicationController).filter_by(uuid=rc2_id).one()
|
||||
self.assertEqual(['myimage1', 'myimage2'], rc2.images)
|
||||
# Create bay with master_addresses
|
||||
bay2_id = uuidutils.generate_uuid()
|
||||
self.dbapi.create_bay({'uuid': bay2_id,
|
||||
'master_addresses': ['mymaster_address1',
|
||||
'mymaster_address2']})
|
||||
bay2 = sa_api.model_query(
|
||||
models.Bay).filter_by(uuid=bay2_id).one()
|
||||
self.assertEqual(['mymaster_address1', 'mymaster_address2'],
|
||||
bay2.master_addresses)
|
||||
|
||||
def test_JSONEncodedList_type_check(self):
|
||||
self.assertRaises(db_exc.DBError,
|
||||
self.dbapi.create_rc,
|
||||
{'images':
|
||||
self.dbapi.create_bay,
|
||||
{'master_addresses':
|
||||
{'this is not a list': 'test'}})
|
||||
|
|
|
@ -192,24 +192,6 @@ class DbBayTestCase(base.DbTestCase):
|
|||
self.dbapi.destroy_bay,
|
||||
'12345678-9999-0000-aaaa-123456789012')
|
||||
|
||||
def test_destroy_bay_that_has_rc(self):
|
||||
bay = utils.create_test_bay()
|
||||
rc = utils.create_test_rc(bay_uuid=bay.uuid)
|
||||
self.assertEqual(bay.uuid, rc.bay_uuid)
|
||||
self.dbapi.destroy_bay(bay.id)
|
||||
self.assertRaises(exception.ReplicationControllerNotFound,
|
||||
self.dbapi.get_rc_by_id,
|
||||
self.context, rc.id)
|
||||
|
||||
def test_destroy_bay_that_has_rc_by_uuid(self):
|
||||
bay = utils.create_test_bay()
|
||||
rc = utils.create_test_rc(bay_uuid=bay.uuid)
|
||||
self.assertEqual(bay.uuid, rc.bay_uuid)
|
||||
self.dbapi.destroy_bay(bay.uuid)
|
||||
self.assertRaises(exception.ReplicationControllerNotFound,
|
||||
self.dbapi.get_rc_by_id,
|
||||
self.context, rc.id)
|
||||
|
||||
def test_update_bay(self):
|
||||
bay = utils.create_test_bay()
|
||||
old_nc = bay.node_count
|
||||
|
|
|
@ -1,142 +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 DbRCTestCase(base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
# This method creates a replication controller for every test and
|
||||
# replaces a test for creating a replication controller.
|
||||
super(DbRCTestCase, self).setUp()
|
||||
self.bay = utils.create_test_bay()
|
||||
self.rc = utils.create_test_rc(bay_uuid=self.bay.uuid)
|
||||
|
||||
def test_create_rc_duplicated_uuid(self):
|
||||
self.assertRaises(exception.ReplicationControllerAlreadyExists,
|
||||
utils.create_test_rc,
|
||||
uuid=self.rc.uuid,
|
||||
bay_uuid=self.bay.uuid)
|
||||
|
||||
def test_get_rc_by_id(self):
|
||||
rc = self.dbapi.get_rc_by_id(self.context, self.rc.id)
|
||||
self.assertEqual(self.rc.id, rc.id)
|
||||
self.assertEqual(self.rc.uuid, rc.uuid)
|
||||
|
||||
def test_get_rc_by_uuid(self):
|
||||
rc = self.dbapi.get_rc_by_uuid(self.context, self.rc.uuid)
|
||||
self.assertEqual(self.rc.id, rc.id)
|
||||
self.assertEqual(self.rc.uuid, rc.uuid)
|
||||
|
||||
def test_get_rc_by_name(self):
|
||||
res = self.dbapi.get_rc_by_name(self.context, self.rc.name)
|
||||
self.assertEqual(self.rc.name, res.name)
|
||||
self.assertEqual(self.rc.uuid, res.uuid)
|
||||
|
||||
def test_get_rc_by_name_multiple_rcs(self):
|
||||
utils.create_test_rc(bay_uuid=self.bay.uuid,
|
||||
uuid=uuidutils.generate_uuid())
|
||||
self.assertRaises(exception.Conflict, self.dbapi.get_rc_by_name,
|
||||
self.context, self.rc.name)
|
||||
|
||||
def test_get_rc_by_name_not_found(self):
|
||||
self.assertRaises(exception.ReplicationControllerNotFound,
|
||||
self.dbapi.get_rc_by_name, self.context,
|
||||
'not_found')
|
||||
|
||||
def test_get_rc_that_does_not_exist(self):
|
||||
self.assertRaises(exception.ReplicationControllerNotFound,
|
||||
self.dbapi.get_rc_by_id, self.context, 999)
|
||||
self.assertRaises(exception.ReplicationControllerNotFound,
|
||||
self.dbapi.get_rc_by_uuid,
|
||||
self.context,
|
||||
uuidutils.generate_uuid())
|
||||
|
||||
def test_get_rc_list(self):
|
||||
uuids = [self.rc.uuid]
|
||||
for i in range(1, 6):
|
||||
rc = utils.create_test_rc(
|
||||
bay_uuid=self.bay.uuid,
|
||||
uuid=uuidutils.generate_uuid())
|
||||
uuids.append(six.text_type(rc.uuid))
|
||||
rc = self.dbapi.get_rc_list(self.context)
|
||||
rc_uuids = [r.uuid for r in rc]
|
||||
self.assertEqual(sorted(uuids), sorted(rc_uuids))
|
||||
|
||||
def test_get_rc_list_sorted(self):
|
||||
uuids = [self.rc.uuid]
|
||||
for _ in range(5):
|
||||
rc = utils.create_test_rc(uuid=uuidutils.generate_uuid())
|
||||
uuids.append(six.text_type(rc.uuid))
|
||||
res = self.dbapi.get_rc_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_rc_list,
|
||||
self.context,
|
||||
sort_key='foo')
|
||||
|
||||
def test_get_rc_list_bay_not_exist(self):
|
||||
rc = self.dbapi.get_rc_list(self.context, filters={
|
||||
'bay_uuid': self.bay.uuid})
|
||||
self.assertEqual(1, len(rc))
|
||||
rc = self.dbapi.get_rc_list(self.context, filters={
|
||||
'bay_uuid': uuidutils.generate_uuid()})
|
||||
self.assertEqual(0, len(rc))
|
||||
|
||||
def test_destroy_rc(self):
|
||||
self.dbapi.destroy_rc(self.rc.id)
|
||||
self.assertRaises(exception.ReplicationControllerNotFound,
|
||||
self.dbapi.get_rc_by_id, self.context, self.rc.id)
|
||||
|
||||
def test_destroy_rc_by_uuid(self):
|
||||
self.assertIsNotNone(self.dbapi.get_rc_by_uuid(self.context,
|
||||
self.rc.uuid))
|
||||
self.dbapi.destroy_rc(self.rc.uuid)
|
||||
self.assertRaises(exception.ReplicationControllerNotFound,
|
||||
self.dbapi.get_rc_by_uuid,
|
||||
self.context, self.rc.uuid)
|
||||
|
||||
def test_destroy_rc_that_does_not_exist(self):
|
||||
self.assertRaises(exception.ReplicationControllerNotFound,
|
||||
self.dbapi.destroy_rc,
|
||||
uuidutils.generate_uuid())
|
||||
|
||||
def test_update_rc(self):
|
||||
old_name = self.rc.name
|
||||
new_name = 'new-rc'
|
||||
self.assertNotEqual(old_name, new_name)
|
||||
res = self.dbapi.update_rc(self.rc.id, {'name': new_name})
|
||||
self.assertEqual(new_name, res.name)
|
||||
|
||||
def test_update_rc_not_found(self):
|
||||
rc_uuid = uuidutils.generate_uuid()
|
||||
self.assertRaises(exception.ReplicationControllerNotFound,
|
||||
self.dbapi.update_rc,
|
||||
rc_uuid, {'replica': 4})
|
||||
|
||||
def test_update_rc_uuid(self):
|
||||
self.assertRaises(exception.InvalidParameterValue,
|
||||
self.dbapi.update_rc, self.rc.id,
|
||||
{'uuid': ''})
|
|
@ -121,40 +121,6 @@ def create_test_bay(**kw):
|
|||
return dbapi.create_bay(bay)
|
||||
|
||||
|
||||
def get_test_rc(**kw):
|
||||
return {
|
||||
'id': kw.get('id', 42),
|
||||
'uuid': kw.get('uuid', '10a47dd1-4874-4298-91cf-eff046dbdb8d'),
|
||||
'name': kw.get('name', 'replication_controller'),
|
||||
'project_id': kw.get('project_id', 'fake_project'),
|
||||
'user_id': kw.get('user_id', 'fake_user'),
|
||||
'images': kw.get('images', ['steak/for-dinner']),
|
||||
'bay_uuid': kw.get('bay_uuid', '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'),
|
||||
'labels': kw.get('labels', {'name': 'foo'}),
|
||||
'replicas': kw.get('replicas', 3),
|
||||
'manifest_url': kw.get('file:///tmp/rc.yaml'),
|
||||
'created_at': kw.get('created_at'),
|
||||
'updated_at': kw.get('updated_at'),
|
||||
}
|
||||
|
||||
|
||||
def create_test_rc(**kw):
|
||||
"""Create test rc entry in DB and return ReplicationController DB object.
|
||||
|
||||
Function to be used to create test ReplicationController objects in the
|
||||
database.
|
||||
:param kw: kwargs with overriding values for
|
||||
replication controller's attributes.
|
||||
:returns: Test ReplicationController DB object.
|
||||
"""
|
||||
replication_controller = get_test_rc(**kw)
|
||||
# Let DB generate ID if it isn't specified explicitly
|
||||
if 'id' not in kw:
|
||||
del replication_controller['id']
|
||||
dbapi = db_api.get_instance()
|
||||
return dbapi.create_rc(replication_controller)
|
||||
|
||||
|
||||
def get_test_x509keypair(**kw):
|
||||
return {
|
||||
'id': kw.get('id', 42),
|
||||
|
|
|
@ -367,7 +367,6 @@ object_data = {
|
|||
'Certificate': '1.0-2aff667971b85c1edf8d15684fd7d5e2',
|
||||
'MyObj': '1.0-b43567e512438205e32f4e95ca616697',
|
||||
'MyObj': '1.0-34c4b1aadefd177b13f9a2f894cc23cd',
|
||||
'ReplicationController': '1.0-a471c2429c212ed91833cfcf0f934eab',
|
||||
'X509KeyPair': '1.2-d81950af36c59a71365e33ce539d24f9',
|
||||
'MagnumService': '1.0-2d397ec59b0046bd5ec35cd3e06efeca',
|
||||
}
|
||||
|
|
|
@ -1,95 +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
|
||||