Remove pod object
Following on from removing the k8s specific APIs in I1f6f04a35dfbb39f217487fea104ded035b75569 the objects associated with these APIs need removal. Remove the pod object, drop the db table and remove references to the pod object. Change-Id: I8c2499ccb97aae39d80868ce02fbef292d762c10 Partially-Implements: blueprint delete-container-endpoint
This commit is contained in:
parent
988593e11f
commit
d20e5ef715
@ -20,13 +20,6 @@
|
||||
"baymodel:update": "rule:default",
|
||||
"baymodel:publish": "rule:admin_or_owner",
|
||||
|
||||
"pod:create": "rule:default",
|
||||
"pod:delete": "rule:default",
|
||||
"pod:detail": "rule:default",
|
||||
"pod:get": "rule:default",
|
||||
"pod:get_all": "rule:default",
|
||||
"pod:update": "rule:default",
|
||||
|
||||
"rc:create": "rule:default",
|
||||
"rc:delete": "rule:default",
|
||||
"rc:detail": "rule:default",
|
||||
|
@ -61,26 +61,6 @@ class API(rpc_service.API):
|
||||
return self._call('service_show', service_ident=service_ident,
|
||||
bay_ident=bay_ident)
|
||||
|
||||
# Pod Operations
|
||||
|
||||
def pod_create(self, pod):
|
||||
return self._call('pod_create', pod=pod)
|
||||
|
||||
def pod_list(self, context, bay_ident):
|
||||
return self._call('pod_list', bay_ident=bay_ident)
|
||||
|
||||
def pod_update(self, pod_ident, bay_ident, manifest):
|
||||
return self._call('pod_update', pod_ident=pod_ident,
|
||||
bay_ident=bay_ident, manifest=manifest)
|
||||
|
||||
def pod_delete(self, pod_ident, bay_ident):
|
||||
return self._call('pod_delete', pod_ident=pod_ident,
|
||||
bay_ident=bay_ident)
|
||||
|
||||
def pod_show(self, context, pod_ident, bay_ident):
|
||||
return self._call('pod_show', pod_ident=pod_ident,
|
||||
bay_ident=bay_ident)
|
||||
|
||||
# ReplicationController Operations
|
||||
|
||||
def rc_create(self, rc):
|
||||
|
@ -191,132 +191,6 @@ class Handler(object):
|
||||
|
||||
return services
|
||||
|
||||
# Pod Operations
|
||||
def pod_create(self, context, pod):
|
||||
LOG.debug("pod_create")
|
||||
bay = conductor_utils.retrieve_bay(context, pod.bay_uuid)
|
||||
self.k8s_api = k8s.create_k8s_api(context, bay)
|
||||
manifest = k8s_manifest.parse(pod.manifest)
|
||||
try:
|
||||
resp = self.k8s_api.create_namespaced_pod(body=manifest,
|
||||
namespace='default')
|
||||
except rest.ApiException as err:
|
||||
pod.status = 'failed'
|
||||
raise exception.KubernetesAPIFailed(err=err)
|
||||
|
||||
if resp is None:
|
||||
raise exception.PodCreationFailed(bay_uuid=pod.bay_uuid)
|
||||
|
||||
pod['uuid'] = resp.metadata.uid
|
||||
pod['name'] = resp.metadata.name
|
||||
pod['images'] = [c.image for c in resp.spec.containers]
|
||||
pod['labels'] = ast.literal_eval(resp.metadata.labels)
|
||||
pod['status'] = resp.status.phase
|
||||
pod['host'] = resp.spec.node_name
|
||||
|
||||
return pod
|
||||
|
||||
def pod_update(self, context, pod_ident, bay_ident, manifest):
|
||||
LOG.debug("pod_update %s", pod_ident)
|
||||
bay = conductor_utils.retrieve_bay(context, bay_ident)
|
||||
self.k8s_api = k8s.create_k8s_api(context, bay)
|
||||
if uuidutils.is_uuid_like(pod_ident):
|
||||
pod = objects.Pod.get_by_uuid(context, pod_ident,
|
||||
bay.uuid, self.k8s_api)
|
||||
else:
|
||||
pod = objects.Pod.get_by_name(context, pod_ident,
|
||||
bay.uuid, self.k8s_api)
|
||||
pod_ident = pod.name
|
||||
try:
|
||||
resp = self.k8s_api.replace_namespaced_pod(name=str(pod_ident),
|
||||
body=manifest,
|
||||
namespace='default')
|
||||
except rest.ApiException as err:
|
||||
raise exception.KubernetesAPIFailed(err=err)
|
||||
|
||||
if resp is None:
|
||||
raise exception.PodNotFound(pod=pod.uuid)
|
||||
|
||||
pod['uuid'] = resp.metadata.uid
|
||||
pod['name'] = resp.metadata.name
|
||||
pod['project_id'] = context.project_id
|
||||
pod['user_id'] = context.user_id
|
||||
pod['bay_uuid'] = bay.uuid
|
||||
pod['images'] = [c.image for c in resp.spec.containers]
|
||||
if not resp.metadata.labels:
|
||||
pod['labels'] = {}
|
||||
else:
|
||||
pod['labels'] = ast.literal_eval(resp.metadata.labels)
|
||||
pod['status'] = resp.status.phase
|
||||
pod['host'] = resp.spec.node_name
|
||||
|
||||
return pod
|
||||
|
||||
def pod_delete(self, context, pod_ident, bay_ident):
|
||||
LOG.debug("pod_delete %s", pod_ident)
|
||||
bay = conductor_utils.retrieve_bay(context, bay_ident)
|
||||
self.k8s_api = k8s.create_k8s_api(context, bay)
|
||||
if uuidutils.is_uuid_like(pod_ident):
|
||||
pod = objects.Pod.get_by_uuid(context, pod_ident,
|
||||
bay.uuid, self.k8s_api)
|
||||
pod_name = pod.name
|
||||
else:
|
||||
pod_name = pod_ident
|
||||
if conductor_utils.object_has_stack(context, bay.uuid):
|
||||
try:
|
||||
self.k8s_api.delete_namespaced_pod(name=str(pod_name), body={},
|
||||
namespace='default')
|
||||
except rest.ApiException as err:
|
||||
if err.status == 404:
|
||||
pass
|
||||
else:
|
||||
raise exception.KubernetesAPIFailed(err=err)
|
||||
|
||||
def pod_show(self, context, pod_ident, bay_ident):
|
||||
LOG.debug("pod_show %s", pod_ident)
|
||||
bay = conductor_utils.retrieve_bay(context, bay_ident)
|
||||
self.k8s_api = k8s.create_k8s_api(context, bay)
|
||||
if uuidutils.is_uuid_like(pod_ident):
|
||||
pod = objects.Pod.get_by_uuid(context, pod_ident,
|
||||
bay.uuid, self.k8s_api)
|
||||
else:
|
||||
pod = objects.Pod.get_by_name(context, pod_ident,
|
||||
bay.uuid, self.k8s_api)
|
||||
|
||||
return pod
|
||||
|
||||
def pod_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_pod(namespace='default')
|
||||
except rest.ApiException as err:
|
||||
raise exception.KubernetesAPIFailed(err=err)
|
||||
|
||||
if resp is None:
|
||||
raise exception.PodListNotFound(bay_uuid=bay.uuid)
|
||||
|
||||
pods = []
|
||||
for pod_entry in resp.items:
|
||||
pod = {}
|
||||
pod['uuid'] = pod_entry.metadata.uid
|
||||
pod['name'] = pod_entry.metadata.name
|
||||
pod['project_id'] = context.project_id
|
||||
pod['user_id'] = context.user_id
|
||||
pod['bay_uuid'] = bay.uuid
|
||||
pod['images'] = [c.image for c in pod_entry.spec.containers]
|
||||
if not pod_entry.metadata.labels:
|
||||
pod['labels'] = {}
|
||||
else:
|
||||
pod['labels'] = ast.literal_eval(pod_entry.metadata.labels)
|
||||
pod['status'] = pod_entry.status.phase
|
||||
pod['host'] = pod_entry.spec.node_name
|
||||
|
||||
pod_obj = objects.Pod(context, **pod)
|
||||
pods.append(pod_obj)
|
||||
|
||||
return pods
|
||||
|
||||
# Replication Controller Operations
|
||||
def rc_create(self, context, rc):
|
||||
LOG.debug("rc_create")
|
||||
|
@ -288,86 +288,6 @@ class Connection(object):
|
||||
:raises: ContainerNotFound
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_pod_list(self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
"""Get matching pods.
|
||||
|
||||
Return a list of the specified columns for all pods 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_pod(self, values):
|
||||
"""Create a new pod.
|
||||
|
||||
:param values: A dict containing several items used to identify
|
||||
and track the pod, and several dicts which are passed
|
||||
into the Drivers when managing this pod. For example:
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
'uuid': uuidutils.generate_uuid(),
|
||||
'name': 'example',
|
||||
'type': 'virt'
|
||||
}
|
||||
:returns: A pod.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_pod_by_id(self, context, pod_id):
|
||||
"""Return a pod.
|
||||
|
||||
:param context: The security context
|
||||
:param pod_id: The id of a pod.
|
||||
:returns: A pod.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_pod_by_uuid(self, context, pod_uuid):
|
||||
"""Return a pod.
|
||||
|
||||
:param context: The security context
|
||||
:param pod_uuid: The uuid of a pod.
|
||||
:returns: A pod.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_pod_by_name(self, pod_name):
|
||||
"""Return a pod.
|
||||
|
||||
:param pod_name: The name of a pod.
|
||||
:returns: A pod.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def destroy_pod(self, pod_id):
|
||||
"""Destroy a pod and all associated interfaces.
|
||||
|
||||
:param pod_id: The id or uuid of a pod.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_pod(self, pod_id, values):
|
||||
"""Update properties of a pod.
|
||||
|
||||
:param pod_id: The id or uuid of a pod.
|
||||
:returns: A pod.
|
||||
:raises: PodNotFound
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_service_list(self, context, filters=None, limit=None,
|
||||
marker=None, sort_key=None, sort_dir=None):
|
||||
|
@ -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 pod object
|
||||
|
||||
Revision ID: ef08a5e057bd
|
||||
Revises: e647f5931da8
|
||||
Create Date: 2016-05-24 13:52:39.782156
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'ef08a5e057bd'
|
||||
down_revision = 'e647f5931da8'
|
||||
|
||||
from alembic import op
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.drop_table('pod')
|
@ -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.Pod, session=session)
|
||||
query = self._add_pods_filters(query, {'bay_uuid': bay_uuid})
|
||||
if query.count() != 0:
|
||||
query.delete()
|
||||
|
||||
query = model_query(models.Service, session=session)
|
||||
query = self._add_services_filters(query, {'bay_uuid': bay_uuid})
|
||||
if query.count() != 0:
|
||||
@ -477,101 +472,6 @@ class Connection(api.Connection):
|
||||
ref.update(values)
|
||||
return ref
|
||||
|
||||
def _add_pods_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 'status' in filters:
|
||||
query = query.filter_by(status=filters['status'])
|
||||
|
||||
return query
|
||||
|
||||
def get_pod_list(self, context, filters=None, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None):
|
||||
query = model_query(models.Pod)
|
||||
query = self._add_tenant_filters(context, query)
|
||||
query = self._add_pods_filters(query, filters)
|
||||
return _paginate_query(models.Pod, limit, marker,
|
||||
sort_key, sort_dir, query)
|
||||
|
||||
def create_pod(self, values):
|
||||
# ensure defaults are present for new pods
|
||||
if not values.get('uuid'):
|
||||
values['uuid'] = uuidutils.generate_uuid()
|
||||
|
||||
pod = models.Pod()
|
||||
pod.update(values)
|
||||
try:
|
||||
pod.save()
|
||||
except db_exc.DBDuplicateEntry:
|
||||
raise exception.PodAlreadyExists(uuid=values['uuid'])
|
||||
return pod
|
||||
|
||||
def get_pod_by_id(self, context, pod_id):
|
||||
query = model_query(models.Pod)
|
||||
query = self._add_tenant_filters(context, query)
|
||||
query = query.filter_by(id=pod_id)
|
||||
try:
|
||||
return query.one()
|
||||
except NoResultFound:
|
||||
raise exception.PodNotFound(pod=pod_id)
|
||||
|
||||
def get_pod_by_uuid(self, context, pod_uuid):
|
||||
query = model_query(models.Pod)
|
||||
query = self._add_tenant_filters(context, query)
|
||||
query = query.filter_by(uuid=pod_uuid)
|
||||
try:
|
||||
return query.one()
|
||||
except NoResultFound:
|
||||
raise exception.PodNotFound(pod=pod_uuid)
|
||||
|
||||
def get_pod_by_name(self, pod_name):
|
||||
query = model_query(models.Pod).filter_by(name=pod_name)
|
||||
try:
|
||||
return query.one()
|
||||
except MultipleResultsFound:
|
||||
raise exception.Conflict('Multiple pods exist with same name.'
|
||||
' Please use the pod uuid instead.')
|
||||
except NoResultFound:
|
||||
raise exception.PodNotFound(pod=pod_name)
|
||||
|
||||
def destroy_pod(self, pod_id):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(models.Pod, session=session)
|
||||
query = add_identity_filter(query, pod_id)
|
||||
count = query.delete()
|
||||
if count != 1:
|
||||
raise exception.PodNotFound(pod_id)
|
||||
|
||||
def update_pod(self, pod_id, values):
|
||||
# NOTE(dtantsur): this can lead to very strange errors
|
||||
if 'uuid' in values:
|
||||
msg = _("Cannot overwrite UUID for an existing Pod.")
|
||||
raise exception.InvalidParameterValue(err=msg)
|
||||
|
||||
return self._do_update_pod(pod_id, values)
|
||||
|
||||
def _do_update_pod(self, pod_id, values):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(models.Pod, session=session)
|
||||
query = add_identity_filter(query, pod_id)
|
||||
try:
|
||||
ref = query.with_lockmode('update').one()
|
||||
except NoResultFound:
|
||||
raise exception.PodNotFound(pod=pod_id)
|
||||
|
||||
if 'provision_state' in values:
|
||||
values['provision_updated_at'] = timeutils.utcnow()
|
||||
|
||||
ref.update(values)
|
||||
return ref
|
||||
|
||||
def _add_services_filters(self, query, filters):
|
||||
if filters is None:
|
||||
filters = {}
|
||||
|
@ -194,27 +194,6 @@ class Container(Base):
|
||||
environment = Column(JSONEncodedDict)
|
||||
|
||||
|
||||
class Pod(Base):
|
||||
"""Represents a pod."""
|
||||
|
||||
__tablename__ = 'pod'
|
||||
__table_args__ = (
|
||||
schema.UniqueConstraint('uuid', name='uniq_pod0uuid'),
|
||||
table_args()
|
||||
)
|
||||
id = Column(Integer, primary_key=True)
|
||||
uuid = Column(String(36))
|
||||
name = Column(String(255))
|
||||
desc = Column(String(255))
|
||||
bay_uuid = Column(String(36))
|
||||
images = Column(JSONEncodedList)
|
||||
labels = Column(JSONEncodedDict)
|
||||
status = Column(String(255))
|
||||
project_id = Column(String(255))
|
||||
user_id = Column(String(255))
|
||||
host = Column(String(255))
|
||||
|
||||
|
||||
class Service(Base):
|
||||
"""Represents a software service."""
|
||||
|
||||
|
@ -17,7 +17,6 @@ from magnum.objects import baymodel
|
||||
from magnum.objects import certificate
|
||||
from magnum.objects import container
|
||||
from magnum.objects import magnum_service
|
||||
from magnum.objects import pod
|
||||
from magnum.objects import replicationcontroller as rc
|
||||
from magnum.objects import service
|
||||
from magnum.objects import x509keypair
|
||||
@ -27,7 +26,6 @@ Container = container.Container
|
||||
Bay = bay.Bay
|
||||
BayModel = baymodel.BayModel
|
||||
MagnumService = magnum_service.MagnumService
|
||||
Pod = pod.Pod
|
||||
ReplicationController = rc.ReplicationController
|
||||
Service = service.Service
|
||||
X509KeyPair = x509keypair.X509KeyPair
|
||||
@ -36,7 +34,6 @@ __all__ = (Bay,
|
||||
BayModel,
|
||||
Container,
|
||||
MagnumService,
|
||||
Pod,
|
||||
ReplicationController,
|
||||
Service,
|
||||
X509KeyPair,
|
||||
|
@ -1,122 +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
|
||||
|
||||
|
||||
@base.MagnumObjectRegistry.register
|
||||
class Pod(base.MagnumPersistentObject, base.MagnumObject,
|
||||
base.MagnumObjectDictCompat):
|
||||
# Version 1.0: Initial version
|
||||
# Version 1.1: Remove unused Pod object API 'list_by_bay_uuid'
|
||||
VERSION = '1.1'
|
||||
|
||||
dbapi = dbapi.get_instance()
|
||||
|
||||
fields = {
|
||||
'id': fields.IntegerField(),
|
||||
'uuid': fields.StringField(nullable=True),
|
||||
'name': fields.StringField(nullable=True),
|
||||
'desc': fields.StringField(nullable=True),
|
||||
'project_id': fields.StringField(nullable=True),
|
||||
'user_id': fields.StringField(nullable=True),
|
||||
'bay_uuid': fields.StringField(nullable=True),
|
||||
'images': fields.ListOfStringsField(nullable=True),
|
||||
'labels': fields.DictOfStringsField(nullable=True),
|
||||
'status': fields.StringField(nullable=True),
|
||||
'manifest_url': fields.StringField(nullable=True),
|
||||
'manifest': fields.StringField(nullable=True),
|
||||
'host': fields.StringField(nullable=True),
|
||||
}
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_uuid(cls, context, uuid, bay_uuid, k8s_api):
|
||||
"""Find a pod based on pod uuid and the uuid for a bay.
|
||||
|
||||
:param context: Security context
|
||||
:param uuid: the uuid of a pod.
|
||||
:param bay_uuid: the UUID of the Bay
|
||||
:param k8s_api: k8s API object
|
||||
|
||||
:returns: a :class:`Pod` object.
|
||||
"""
|
||||
try:
|
||||
resp = k8s_api.list_namespaced_pod(namespace='default')
|
||||
except rest.ApiException as err:
|
||||
raise exception.KubernetesAPIFailed(err=err)
|
||||
|
||||
if resp is None:
|
||||
raise exception.PodListNotFound(bay_uuid=bay_uuid)
|
||||
|
||||
pod = {}
|
||||
for pod_entry in resp.items:
|
||||
if pod_entry.metadata.uid == uuid:
|
||||
pod['uuid'] = pod_entry.metadata.uid
|
||||
pod['name'] = pod_entry.metadata.name
|
||||
pod['project_id'] = context.project_id
|
||||
pod['user_id'] = context.user_id
|
||||
pod['bay_uuid'] = bay_uuid
|
||||
pod['images'] = [c.image for c in pod_entry.spec.containers]
|
||||
if not pod_entry.metadata.labels:
|
||||
pod['labels'] = {}
|
||||
else:
|
||||
pod['labels'] = ast.literal_eval(pod_entry.metadata.labels)
|
||||
pod['status'] = pod_entry.status.phase
|
||||
pod['host'] = pod_entry.spec.node_name
|
||||
|
||||
pod_obj = Pod(context, **pod)
|
||||
return pod_obj
|
||||
raise exception.PodNotFound(pod=uuid)
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_name(cls, context, name, bay_uuid, k8s_api):
|
||||
"""Find a pod based on pod name and the uuid for a bay.
|
||||
|
||||
:param context: Security context
|
||||
:param name: the name of a pod.
|
||||
:param bay_uuid: the UUID of the Bay
|
||||
:param k8s_api: k8s API object
|
||||
|
||||
:returns: a :class:`Pod` object.
|
||||
"""
|
||||
try:
|
||||
resp = k8s_api.read_namespaced_pod(name=name,
|
||||
namespace='default')
|
||||
except rest.ApiException as err:
|
||||
raise exception.KubernetesAPIFailed(err=err)
|
||||
|
||||
if resp is None:
|
||||
raise exception.PodNotFound(pod=name)
|
||||
|
||||
pod = {}
|
||||
pod['uuid'] = resp.metadata.uid
|
||||
pod['name'] = resp.metadata.name
|
||||
pod['project_id'] = context.project_id
|
||||
pod['user_id'] = context.user_id
|
||||
pod['bay_uuid'] = bay_uuid
|
||||
pod['images'] = [c.image for c in resp.spec.containers]
|
||||
if not resp.metadata.labels:
|
||||
pod['labels'] = {}
|
||||
else:
|
||||
pod['labels'] = ast.literal_eval(resp.metadata.labels)
|
||||
pod['status'] = resp.status.phase
|
||||
pod['host'] = resp.spec.node_name
|
||||
|
||||
pod_obj = Pod(context, **pod)
|
||||
return pod_obj
|
@ -34,13 +34,6 @@ policy_data = """
|
||||
"baymodel:get_all": "",
|
||||
"baymodel:update": "",
|
||||
|
||||
"pod:create": "",
|
||||
"pod:delete": "",
|
||||
"pod:detail": "",
|
||||
"pod:get": "",
|
||||
"pod:get_all": "",
|
||||
"pod:update": "",
|
||||
|
||||
"rc:create": "",
|
||||
"rc:delete": "",
|
||||
"rc:detail": "",
|
||||
|
@ -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_pods(self):
|
||||
obj_utils.create_test_pod(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_services(self):
|
||||
obj_utils.create_test_service(self.context, bay_uuid=self.bay.uuid)
|
||||
response = self.delete('/bays/%s' % self.bay.uuid,
|
||||
|
@ -27,9 +27,6 @@ class TestK8sConductor(base.TestCase):
|
||||
super(TestK8sConductor, self).setUp()
|
||||
self.kube_handler = k8s_conductor.Handler()
|
||||
|
||||
def mock_pod(self):
|
||||
return objects.Pod({})
|
||||
|
||||
def mock_service(self):
|
||||
return objects.Service({})
|
||||
|
||||
@ -42,140 +39,6 @@ class TestK8sConductor(base.TestCase):
|
||||
def mock_baymodel(self):
|
||||
return objects.BayModel({})
|
||||
|
||||
@patch('magnum.conductor.utils.retrieve_bay')
|
||||
@patch('ast.literal_eval')
|
||||
def test_pod_create_with_success(self, mock_ast, mock_retrieve):
|
||||
expected_pod = mock.MagicMock()
|
||||
expected_pod.uuid = 'test-uuid'
|
||||
expected_pod.name = 'test-name'
|
||||
expected_pod.bay_uuid = 'test-bay-uuid'
|
||||
manifest = {"key": "value"}
|
||||
expected_pod.manifest = '{"key": "value"}'
|
||||
mock_ast.return_value = {}
|
||||
|
||||
with patch('magnum.conductor.k8s_api.create_k8s_api') as \
|
||||
mock_kube_api:
|
||||
self.kube_handler.pod_create(self.context, expected_pod)
|
||||
(mock_kube_api.return_value.create_namespaced_pod
|
||||
.assert_called_once_with(body=manifest, namespace='default'))
|
||||
|
||||
@patch('magnum.conductor.utils.retrieve_bay')
|
||||
def test_pod_create_with_fail(self, mock_retrieve):
|
||||
expected_pod = mock.MagicMock()
|
||||
manifest = {"key": "value"}
|
||||
expected_pod.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_pod.side_effect = err
|
||||
|
||||
self.assertRaises(exception.KubernetesAPIFailed,
|
||||
self.kube_handler.pod_create,
|
||||
self.context, expected_pod)
|
||||
(mock_kube_api.return_value
|
||||
.create_namespaced_pod
|
||||
.assert_called_once_with(body=manifest,
|
||||
namespace='default'))
|
||||
|
||||
@patch('magnum.conductor.utils.retrieve_bay')
|
||||
def test_pod_create_fail_on_existing_pod(self, retrieve_bay):
|
||||
expected_pod = mock.MagicMock()
|
||||
expected_pod.manifest = '{"key": "value"}'
|
||||
|
||||
with patch('magnum.conductor.k8s_api.create_k8s_api') as \
|
||||
mock_kube_api:
|
||||
err = rest.ApiException(status=409)
|
||||
mock_kube_api.return_value.create_namespaced_pod.side_effect = err
|
||||
|
||||
self.assertRaises(exception.KubernetesAPIFailed,
|
||||
self.kube_handler.pod_create,
|
||||
self.context, expected_pod)
|
||||
self.assertEqual('failed', expected_pod.status)
|
||||
|
||||
@patch('magnum.conductor.utils.object_has_stack')
|
||||
@patch('magnum.objects.Pod.get_by_uuid')
|
||||
@patch('magnum.objects.Bay.get_by_name')
|
||||
def test_pod_delete_with_success(self,
|
||||
mock_bay_get_by_name,
|
||||
mock_pod_get_by_uuid,
|
||||
mock_object_has_stack):
|
||||
mock_bay = mock.MagicMock()
|
||||
mock_bay_get_by_name.return_value = mock_bay
|
||||
|
||||
mock_pod = mock.MagicMock()
|
||||
mock_pod.name = 'test-pod'
|
||||
mock_pod.uuid = 'test-uuid'
|
||||
mock_pod.bay_uuid = 'test-bay-uuid'
|
||||
mock_pod_get_by_uuid.return_value = mock_pod
|
||||
|
||||
mock_object_has_stack.return_value = True
|
||||
with patch('magnum.conductor.k8s_api.create_k8s_api') as \
|
||||
mock_kube_api:
|
||||
self.kube_handler.pod_delete(self.context,
|
||||
mock_pod.name,
|
||||
mock_pod.bay_uuid)
|
||||
|
||||
(mock_kube_api.return_value.delete_namespaced_pod
|
||||
.assert_called_once_with(
|
||||
name=mock_pod.name, body={}, namespace='default'))
|
||||
|
||||
@patch('magnum.conductor.utils.object_has_stack')
|
||||
@patch('magnum.objects.Pod.get_by_uuid')
|
||||
@patch('magnum.objects.Bay.get_by_name')
|
||||
def test_pod_delete_with_failure(self, mock_bay_get_by_name,
|
||||
mock_pod_get_by_uuid,
|
||||
mock_object_has_stack):
|
||||
mock_bay = mock.MagicMock()
|
||||
mock_bay_get_by_name.return_value = mock_bay
|
||||
|
||||
mock_pod = mock.MagicMock()
|
||||
mock_pod.name = 'test-pod'
|
||||
mock_pod.uuid = 'test-uuid'
|
||||
mock_pod_get_by_uuid.return_value = mock_pod
|
||||
|
||||
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_pod.side_effect = err
|
||||
|
||||
self.assertRaises(exception.KubernetesAPIFailed,
|
||||
self.kube_handler.pod_delete,
|
||||
self.context, mock_pod.name,
|
||||
mock_pod.bay_uuid)
|
||||
(mock_kube_api.return_value.delete_namespaced_pod
|
||||
.assert_called_once_with(
|
||||
name=mock_pod.name, body={}, namespace='default'))
|
||||
|
||||
@patch('magnum.conductor.utils.object_has_stack')
|
||||
@patch('magnum.objects.Pod.get_by_uuid')
|
||||
@patch('magnum.objects.Bay.get_by_name')
|
||||
def test_pod_delete_succeeds_when_not_found(
|
||||
self, mock_bay_get_by_name,
|
||||
mock_pod_get_by_uuid,
|
||||
mock_object_has_stack):
|
||||
mock_bay = mock.MagicMock()
|
||||
mock_bay_get_by_name.return_value = mock_bay
|
||||
|
||||
mock_pod = mock.MagicMock()
|
||||
mock_pod.name = 'test-pod'
|
||||
mock_pod.uuid = 'test-uuid'
|
||||
mock_pod_get_by_uuid.return_value = mock_pod
|
||||
|
||||
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_pod.side_effect = err
|
||||
|
||||
self.kube_handler.pod_delete(self.context, mock_pod.name,
|
||||
mock_pod.bay_uuid)
|
||||
|
||||
(mock_kube_api.return_value.delete_namespaced_pod
|
||||
.assert_called_once_with(
|
||||
name=mock_pod.name, body={}, namespace='default'))
|
||||
|
||||
@patch('magnum.objects.Bay.get_by_name')
|
||||
@patch('magnum.conductor.k8s_api.create_k8s_api')
|
||||
@patch('ast.literal_eval')
|
||||
@ -567,68 +430,3 @@ class TestK8sConductor(base.TestCase):
|
||||
.assert_called_once_with(body=expected_service.manifest,
|
||||
name=service_name,
|
||||
namespace='default'))
|
||||
|
||||
@patch('magnum.objects.Pod.get_by_name')
|
||||
@patch('magnum.objects.Pod.get_by_uuid')
|
||||
@patch('magnum.objects.Bay.get_by_name')
|
||||
@patch('ast.literal_eval')
|
||||
def test_pod_update_with_success(self, mock_ast,
|
||||
mock_bay_get_by_name,
|
||||
mock_pod_get_by_uuid,
|
||||
mock_pod_get_by_name):
|
||||
mock_bay = mock.MagicMock()
|
||||
mock_bay_get_by_name.return_value = mock_bay
|
||||
|
||||
expected_pod = mock.MagicMock()
|
||||
expected_pod.uuid = 'test-uuid'
|
||||
expected_pod.name = 'test-name'
|
||||
expected_pod.bay_uuid = 'test-bay-uuid'
|
||||
expected_pod.manifest = '{"key": "value"}'
|
||||
mock_ast.return_value = {}
|
||||
|
||||
mock_pod_get_by_uuid.return_value = expected_pod
|
||||
mock_pod_get_by_name.return_value = expected_pod
|
||||
name_pod = expected_pod.name
|
||||
|
||||
with patch('magnum.conductor.k8s_api.create_k8s_api') as \
|
||||
mock_kube_api:
|
||||
self.kube_handler.pod_update(self.context, expected_pod.name,
|
||||
expected_pod.bay_uuid,
|
||||
expected_pod.manifest)
|
||||
(mock_kube_api.return_value.replace_namespaced_pod
|
||||
.assert_called_once_with(
|
||||
body=expected_pod.manifest, name=name_pod,
|
||||
namespace='default'))
|
||||
|
||||
@patch('magnum.objects.Pod.get_by_name')
|
||||
@patch('magnum.objects.Pod.get_by_uuid')
|
||||
@patch('magnum.objects.Bay.get_by_name')
|
||||
def test_pod_update_with_failure(self, mock_bay_get_by_name,
|
||||
mock_pod_get_by_uuid,
|
||||
mock_pod_get_by_name):
|
||||
mock_bay = mock.MagicMock()
|
||||
mock_bay_get_by_name.return_value = mock_bay
|
||||
|
||||
expected_pod = mock.MagicMock()
|
||||
expected_pod.uuid = 'test-uuid'
|
||||
expected_pod.name = 'test-name'
|
||||
expected_pod.bay_uuid = 'test-bay-uuid'
|
||||
mock_pod_get_by_uuid.return_value = expected_pod
|
||||
mock_pod_get_by_name.return_value = expected_pod
|
||||
expected_pod.manifest = '{"key": "value"}'
|
||||
name_pod = expected_pod.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_pod.side_effect = err
|
||||
|
||||
self.assertRaises(exception.KubernetesAPIFailed,
|
||||
self.kube_handler.pod_update,
|
||||
self.context, expected_pod.name,
|
||||
expected_pod.bay_uuid,
|
||||
expected_pod.manifest)
|
||||
(mock_kube_api.return_value.replace_namespaced_pod
|
||||
.assert_called_once_with(
|
||||
body=expected_pod.manifest, name=name_pod,
|
||||
namespace='default'))
|
||||
|
@ -29,7 +29,6 @@ class RPCAPITestCase(base.DbTestCase):
|
||||
super(RPCAPITestCase, self).setUp()
|
||||
self.fake_bay = dbutils.get_test_bay(driver='fake-driver')
|
||||
self.fake_container = dbutils.get_test_container(driver='fake-driver')
|
||||
self.fake_pod = dbutils.get_test_pod(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_x509keypair = dbutils.get_test_x509keypair(
|
||||
@ -128,33 +127,6 @@ class RPCAPITestCase(base.DbTestCase):
|
||||
service_ident=self.fake_service['uuid'],
|
||||
bay_ident=self.fake_service['bay_uuid'])
|
||||
|
||||
def test_pod_create(self):
|
||||
self._test_rpcapi('pod_create',
|
||||
'call',
|
||||
version='1.0',
|
||||
pod=self.fake_pod)
|
||||
|
||||
def test_pod_update(self):
|
||||
self._test_rpcapi('pod_update',
|
||||
'call',
|
||||
version='1.1',
|
||||
pod_ident=self.fake_pod['uuid'],
|
||||
bay_ident=self.fake_pod['bay_uuid'],
|
||||
manifest={})
|
||||
|
||||
def test_pod_delete(self):
|
||||
self._test_rpcapi('pod_delete',
|
||||
'call',
|
||||
version='1.0',
|
||||
pod_ident=self.fake_pod['uuid'],
|
||||
bay_ident=self.fake_pod['bay_uuid'])
|
||||
|
||||
self._test_rpcapi('pod_delete',
|
||||
'call',
|
||||
version='1.1',
|
||||
pod_ident=self.fake_pod['uuid'],
|
||||
bay_ident=self.fake_pod['bay_uuid'])
|
||||
|
||||
def test_rc_create(self):
|
||||
self._test_rpcapi('rc_create',
|
||||
'call',
|
||||
|
@ -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_pod(self,
|
||||
mock_bay_get_by_uuid):
|
||||
pod = objects.Pod({})
|
||||
pod.bay_uuid = '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'
|
||||
self._test_retrieve_bay(pod.bay_uuid, mock_bay_get_by_uuid)
|
||||
|
||||
@patch('magnum.objects.Bay.get_by_uuid')
|
||||
def test_retrieve_bay_from_service(self,
|
||||
mock_bay_get_by_uuid):
|
||||
|
@ -23,40 +23,44 @@ from magnum.tests.unit.db import base
|
||||
class SqlAlchemyCustomTypesTestCase(base.DbTestCase):
|
||||
|
||||
def test_JSONEncodedDict_default_value(self):
|
||||
# Create pod w/o labels
|
||||
pod1_id = uuidutils.generate_uuid()
|
||||
self.dbapi.create_pod({'uuid': pod1_id})
|
||||
pod1 = sa_api.model_query(models.Pod).filter_by(uuid=pod1_id).one()
|
||||
self.assertEqual({}, pod1.labels)
|
||||
# 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 pod with labels
|
||||
pod2_id = uuidutils.generate_uuid()
|
||||
self.dbapi.create_pod({'uuid': pod2_id, 'labels': {'bar': 'foo'}})
|
||||
pod2 = sa_api.model_query(models.Pod).filter_by(uuid=pod2_id).one()
|
||||
self.assertEqual('foo', pod2.labels['bar'])
|
||||
# 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'])
|
||||
|
||||
def test_JSONEncodedDict_type_check(self):
|
||||
self.assertRaises(db_exc.DBError,
|
||||
self.dbapi.create_pod,
|
||||
self.dbapi.create_rc,
|
||||
{'labels':
|
||||
['this is not a dict']})
|
||||
|
||||
def test_JSONEncodedList_default_value(self):
|
||||
# Create pod w/o images
|
||||
pod1_id = uuidutils.generate_uuid()
|
||||
self.dbapi.create_pod({'uuid': pod1_id})
|
||||
pod1 = sa_api.model_query(models.Pod).filter_by(uuid=pod1_id).one()
|
||||
self.assertEqual([], pod1.images)
|
||||
# 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 pod with images
|
||||
pod2_id = uuidutils.generate_uuid()
|
||||
self.dbapi.create_pod({'uuid': pod2_id,
|
||||
'images': ['myimage1', 'myimage2']})
|
||||
pod2 = sa_api.model_query(models.Pod).filter_by(uuid=pod2_id).one()
|
||||
self.assertEqual(['myimage1', 'myimage2'], pod2.images)
|
||||
# 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)
|
||||
|
||||
def test_JSONEncodedList_type_check(self):
|
||||
self.assertRaises(db_exc.DBError,
|
||||
self.dbapi.create_pod,
|
||||
self.dbapi.create_rc,
|
||||
{'images':
|
||||
{'this is not a list': 'test'}})
|
||||
|
@ -192,22 +192,6 @@ class DbBayTestCase(base.DbTestCase):
|
||||
self.dbapi.destroy_bay,
|
||||
'12345678-9999-0000-aaaa-123456789012')
|
||||
|
||||
def test_destroy_bay_that_has_pods(self):
|
||||
bay = utils.create_test_bay()
|
||||
pod = utils.create_test_pod(bay_uuid=bay.uuid)
|
||||
self.assertEqual(bay.uuid, pod.bay_uuid)
|
||||
self.dbapi.destroy_bay(bay.id)
|
||||
self.assertRaises(exception.PodNotFound,
|
||||
self.dbapi.get_pod_by_id, self.context, pod.id)
|
||||
|
||||
def test_destroy_bay_that_has_pods_by_uuid(self):
|
||||
bay = utils.create_test_bay()
|
||||
pod = utils.create_test_pod(bay_uuid=bay.uuid)
|
||||
self.assertEqual(bay.uuid, pod.bay_uuid)
|
||||
self.dbapi.destroy_bay(bay.uuid)
|
||||
self.assertRaises(exception.PodNotFound,
|
||||
self.dbapi.get_pod_by_id, self.context, pod.id)
|
||||
|
||||
def test_destroy_bay_that_has_services(self):
|
||||
bay = utils.create_test_bay()
|
||||
service = utils.create_test_service(bay_uuid=bay.uuid)
|
||||
|
@ -1,183 +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 Pods 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 DbPodTestCase(base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
# This method creates a pod for every test and
|
||||
# replaces a test for creating a pod.
|
||||
super(DbPodTestCase, self).setUp()
|
||||
self.bay = utils.create_test_bay()
|
||||
self.pod = utils.create_test_pod(bay_uuid=self.bay.uuid)
|
||||
|
||||
def test_create_pod_duplicated_uuid(self):
|
||||
self.assertRaises(exception.PodAlreadyExists,
|
||||
utils.create_test_pod,
|
||||
uuid=self.pod.uuid,
|
||||
bay_uuid=self.bay.uuid)
|
||||
|
||||
def test_get_pod_by_id(self):
|
||||
res = self.dbapi.get_pod_by_id(self.context, self.pod.id)
|
||||
self.assertEqual(self.pod.id, res.id)
|
||||
self.assertEqual(self.pod.uuid, res.uuid)
|
||||
|
||||
def test_get_pod_by_uuid(self):
|
||||
res = self.dbapi.get_pod_by_uuid(self.context, self.pod.uuid)
|
||||
self.assertEqual(self.pod.id, res.id)
|
||||
self.assertEqual(self.pod.uuid, res.uuid)
|
||||
|
||||
def test_get_pod_by_name(self):
|
||||
res = self.dbapi.get_pod_by_name(self.pod.name)
|
||||
self.assertEqual(self.pod.id, res.id)
|
||||
self.assertEqual(self.pod.uuid, res.uuid)
|
||||
|
||||
def test_get_pod_by_name_multiple_pods(self):
|
||||
utils.create_test_pod(bay_uuid=self.bay.uuid,
|
||||
uuid=uuidutils.generate_uuid())
|
||||
self.assertRaises(exception.Conflict, self.dbapi.get_pod_by_name,
|
||||
self.pod.name)
|
||||
|
||||
def test_get_pod_by_name_not_found(self):
|
||||
self.assertRaises(exception.PodNotFound,
|
||||
self.dbapi.get_pod_by_name,
|
||||
'not_found')
|
||||
|
||||
def test_get_pod_that_does_not_exist(self):
|
||||
self.assertRaises(exception.PodNotFound,
|
||||
self.dbapi.get_pod_by_id, self.context, 999)
|
||||
self.assertRaises(exception.PodNotFound,
|
||||
self.dbapi.get_pod_by_uuid,
|
||||
self.context,
|
||||
uuidutils.generate_uuid())
|
||||
self.assertRaises(exception.PodNotFound,
|
||||
self.dbapi.get_pod_by_name,
|
||||
'bad-name')
|
||||
|
||||
def test_get_pod_list(self):
|
||||
uuids = [self.pod.uuid]
|
||||
for i in range(1, 6):
|
||||
pod = utils.create_test_pod(uuid=uuidutils.generate_uuid(),
|
||||
bay_uuid=self.bay.uuid)
|
||||
uuids.append(six.text_type(pod.uuid))
|
||||
res = self.dbapi.get_pod_list(self.context)
|
||||
res_uuids = [r.uuid for r in res]
|
||||
self.assertEqual(sorted(uuids), sorted(res_uuids))
|
||||
|
||||
def test_get_pod_list_sorted(self):
|
||||
uuids = [self.pod.uuid]
|
||||
for _ in range(5):
|
||||
pod = utils.create_test_pod(uuid=uuidutils.generate_uuid())
|
||||
uuids.append(six.text_type(pod.uuid))
|
||||
res = self.dbapi.get_pod_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_pod_list,
|
||||
self.context,
|
||||
sort_key='foo')
|
||||
|
||||
def test_get_pod_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)
|
||||
|
||||
pod1 = utils.create_test_pod(
|
||||
name='pod-one',
|
||||
uuid=uuidutils.generate_uuid(),
|
||||
bay_uuid=bay1['uuid'],
|
||||
status='status1')
|
||||
pod2 = utils.create_test_pod(
|
||||
name='pod-two',
|
||||
uuid=uuidutils.generate_uuid(),
|
||||
bay_uuid=bay2['uuid'],
|
||||
status='status2')
|
||||
|
||||
res = self.dbapi.get_pod_list(self.context,
|
||||
filters={'bay_uuid': bay1['uuid']})
|
||||
self.assertEqual([pod1.id], [r.id for r in res])
|
||||
|
||||
res = self.dbapi.get_pod_list(self.context,
|
||||
filters={'bay_uuid': bay2['uuid']})
|
||||
self.assertEqual([pod2.id], [r.id for r in res])
|
||||
|
||||
res = self.dbapi.get_pod_list(self.context,
|
||||
filters={'name': 'pod-one'})
|
||||
self.assertEqual([pod1.id], [r.id for r in res])
|
||||
|
||||
res = self.dbapi.get_pod_list(self.context,
|
||||
filters={'name': 'bad-pod'})
|
||||
self.assertEqual([], [r.id for r in res])
|
||||
|
||||
res = self.dbapi.get_pod_list(self.context,
|
||||
filters={'status': 'status1'})
|
||||
self.assertEqual([pod1.id], [r.id for r in res])
|
||||
|
||||
res = self.dbapi.get_pod_list(self.context,
|
||||
filters={'status': 'status2'})
|
||||
self.assertEqual([pod2.id], [r.id for r in res])
|
||||
|
||||
def test_get_pod_list_bay_not_exist(self):
|
||||
res = self.dbapi.get_pod_list(self.context,
|
||||
{'bay_uuid': self.bay.uuid})
|
||||
self.assertEqual(1, len(res))
|
||||
res = self.dbapi.get_pod_list(self.context, filters={
|
||||
'bay_uuid': uuidutils.generate_uuid()})
|
||||
self.assertEqual(0, len(res))
|
||||
|
||||
def test_destroy_pod(self):
|
||||
self.dbapi.destroy_pod(self.pod.id)
|
||||
self.assertRaises(exception.PodNotFound,
|
||||
self.dbapi.get_pod_by_id, self.context, self.pod.id)
|
||||
|
||||
def test_destroy_pod_by_uuid(self):
|
||||
self.assertIsNotNone(self.dbapi.get_pod_by_uuid(self.context,
|
||||
self.pod.uuid))
|
||||
self.dbapi.destroy_pod(self.pod.uuid)
|
||||
self.assertRaises(exception.PodNotFound,
|
||||
self.dbapi.get_pod_by_uuid,
|
||||
self.context, self.pod.uuid)
|
||||
|
||||
def test_destroy_pod_that_does_not_exist(self):
|
||||
self.assertRaises(exception.PodNotFound,
|
||||
self.dbapi.destroy_pod,
|
||||
uuidutils.generate_uuid())
|
||||
|
||||
def test_update_pod(self):
|
||||
old_name = self.pod.name
|
||||
new_name = 'new-pod'
|
||||
self.assertNotEqual(old_name, new_name)
|
||||
res = self.dbapi.update_pod(self.pod.id, {'name': new_name})
|
||||
self.assertEqual(new_name, res.name)
|
||||
|
||||
def test_update_pod_not_found(self):
|
||||
pod_uuid = uuidutils.generate_uuid()
|
||||
self.assertRaises(exception.PodNotFound, self.dbapi.update_pod,
|
||||
pod_uuid, {'status': 'Running'})
|
||||
|
||||
def test_update_pod_uuid(self):
|
||||
self.assertRaises(exception.InvalidParameterValue,
|
||||
self.dbapi.update_pod, self.pod.id,
|
||||
{'uuid': ''})
|
@ -109,39 +109,6 @@ def create_test_bay(**kw):
|
||||
return dbapi.create_bay(bay)
|
||||
|
||||
|
||||
def get_test_pod(**kw):
|
||||
return {
|
||||
'id': kw.get('id', 42),
|
||||
'uuid': kw.get('uuid', '10a47dd1-4874-4298-91cf-eff046dbdb8d'),
|
||||
'name': kw.get('name', 'pod1'),
|
||||
'project_id': kw.get('project_id', 'fake_project'),
|
||||
'user_id': kw.get('user_id', 'fake_user'),
|
||||
'desc': kw.get('desc', 'test pod'),
|
||||
'bay_uuid': kw.get('bay_uuid', '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'),
|
||||
'images': kw.get('images', ['MyImage']),
|
||||
'labels': kw.get('labels', {'name': 'foo'}),
|
||||
'status': kw.get('status', 'Running'),
|
||||
'host': kw.get('host', '10.0.0.3'),
|
||||
'created_at': kw.get('created_at'),
|
||||
'updated_at': kw.get('updated_at'),
|
||||
}
|
||||
|
||||
|
||||
def create_test_pod(**kw):
|
||||
"""Create test pod entry in DB and return Pod DB object.
|
||||
|
||||
Function to be used to create test Pod objects in the database.
|
||||
:param kw: kwargs with overriding values for pod's attributes.
|
||||
:returns: Test Pod DB object.
|
||||
"""
|
||||
pod = get_test_pod(**kw)
|
||||
# Let DB generate ID if it isn't specified explicitly
|
||||
if 'id' not in kw:
|
||||
del pod['id']
|
||||
dbapi = db_api.get_instance()
|
||||
return dbapi.create_pod(pod)
|
||||
|
||||
|
||||
def get_test_service(**kw):
|
||||
return {
|
||||
'id': kw.get('id', 42),
|
||||
|
@ -428,7 +428,6 @@ object_data = {
|
||||
'Certificate': '1.0-2aff667971b85c1edf8d15684fd7d5e2',
|
||||
'Container': '1.3-e2d9d2e8a8844d421148cd9fde6c6bd6',
|
||||
'MyObj': '1.0-b43567e512438205e32f4e95ca616697',
|
||||
'Pod': '1.1-39f221ad1dad0eb7f7bee3569d42fa7e',
|
||||
'ReplicationController': '1.0-a471c2429c212ed91833cfcf0f934eab',
|
||||
'Service': '1.0-f4a1c5a4618708824a553568c1ada0ea',
|
||||
'X509KeyPair': '1.1-4aecc268e23e32b8a762d43ba1a4b159',
|
||||
|
@ -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 TestPodObject(base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPodObject, self).setUp()
|
||||
self.fake_pod = utils.get_test_pod()
|
||||
|
||||
@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_pod['uuid']
|
||||
bay_uuid = self.fake_pod['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': {
|
||||
'node_name': 'fake-node',
|
||||
'containers': [
|
||||
{
|
||||
'image': 'fake-image'
|
||||
}
|
||||
]
|
||||
},
|
||||
'status': {
|
||||
'phase': 'CREATED'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
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.node_name = 'fake-host'
|
||||
fake_obj.items[0].status = mock.MagicMock()
|
||||
fake_obj.items[0].status.phase = 'fake-status'
|
||||
k8s_api_mock.list_namespaced_pod.return_value = fake_obj
|
||||
objects.Pod.get_by_uuid(self.context,
|
||||
uuid, bay_uuid,
|
||||
k8s_api_mock)
|
||||
(k8s_api_mock.list_namespaced_pod.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_pod['name']
|
||||
bay_uuid = self.fake_pod['bay_uuid']
|
||||
|
||||
mock_ast.return_value = {}
|
||||
k8s_api_mock = mock.MagicMock()
|
||||
mock_kube_api.return_value = k8s_api_mock
|
||||
fake_pod = mock.MagicMock()
|
||||
fake_pod.metadata.uid = 'fake-uuid'
|
||||
fake_pod.metadata.name = 'fake-name'
|
||||
fake_pod.spec.containers[0].image = ['fake-image']
|
||||
fake_pod.metadata.labels = {}
|
||||
fake_pod.status.phase = 'fake-status'
|
||||
fake_pod.spec.node_name = 'fake-host'
|
||||
k8s_api_mock.read_namespaced_pod.return_value = fake_pod
|
||||
objects.Pod.get_by_name(self.context,
|
||||
name, bay_uuid,
|
||||
k8s_api_mock)
|
||||
(k8s_api_mock.read_namespaced_pod.assert_called_once_with(
|
||||
name=name,
|
||||
namespace='default'))
|
@ -79,33 +79,6 @@ def create_test_bay(context, **kw):
|
||||
return bay
|
||||
|
||||
|
||||
def get_test_pod(context, **kw):
|
||||
"""Return a Pod 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_pod = db_utils.get_test_pod(**kw)
|
||||
# Let DB generate ID if it isn't specified explicitly
|
||||
if 'id' not in kw:
|
||||
del db_pod['id']
|
||||
pod = objects.Pod(context)
|
||||
for key in db_pod:
|
||||
setattr(pod, key, db_pod[key])
|
||||
return pod
|
||||
|
||||
|
||||
def create_test_pod(context, **kw):
|
||||
"""Create and return a test pod object.
|
||||
|
||||
Create a pod in the DB and return a Pod object with appropriate
|
||||
attributes.
|
||||
"""
|
||||
pod = get_test_pod(context, **kw)
|
||||
pod.manifest = '{"foo": "bar"}'
|
||||
return pod
|
||||
|
||||
|
||||
def get_test_service(context, **kw):
|
||||
"""Return a Service object with appropriate attributes.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user