Merge "Remove Image and ZunService class from controllers"
This commit is contained in:
commit
44da21a8f4
@ -12,15 +12,13 @@
|
||||
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import strutils
|
||||
from oslo_utils import timeutils
|
||||
import pecan
|
||||
from pecan import rest
|
||||
|
||||
from zun.api.controllers import base
|
||||
from zun.api.controllers import link
|
||||
from zun.api.controllers import types
|
||||
from zun.api.controllers.v1 import collection
|
||||
from zun.api.controllers.v1.schemas import images as schema
|
||||
from zun.api.controllers.v1.views import images_view as view
|
||||
from zun.api import utils as api_utils
|
||||
from zun.common import exception
|
||||
from zun.common.i18n import _LE
|
||||
@ -32,84 +30,11 @@ from zun import objects
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Image(base.APIBase):
|
||||
"""API representation of an image.
|
||||
|
||||
This class enforces type checking and value constraints, and converts
|
||||
between the internal object model and the API representation of
|
||||
an image.
|
||||
"""
|
||||
|
||||
fields = {
|
||||
'uuid': {
|
||||
'validate': types.Uuid.validate,
|
||||
},
|
||||
'image_id': {
|
||||
'validate': types.NameType.validate,
|
||||
'validate_args': {
|
||||
'pattern': types.image_name_pattern
|
||||
},
|
||||
},
|
||||
'repo': {
|
||||
'validate': types.NameType.validate,
|
||||
'validate_args': {
|
||||
'pattern': types.image_name_pattern
|
||||
},
|
||||
'mandatory': True
|
||||
},
|
||||
'tag': {
|
||||
'validate': types.NameType.validate,
|
||||
'validate_args': {
|
||||
'pattern': types.image_name_pattern
|
||||
},
|
||||
},
|
||||
'size': {
|
||||
'validate': types.ImageSize.validate,
|
||||
},
|
||||
}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(Image, self).__init__(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def _convert_with_links(image, url, expand=True):
|
||||
if not expand:
|
||||
image.unset_fields_except([
|
||||
'uuid', 'image_id', 'repo', 'tag', 'size'])
|
||||
|
||||
image.links = [link.Link.make_link(
|
||||
'self', url,
|
||||
'images', image.uuid),
|
||||
link.Link.make_link(
|
||||
'bookmark', url,
|
||||
'images', image.uuid,
|
||||
bookmark=True)]
|
||||
return image
|
||||
|
||||
@classmethod
|
||||
def convert_with_links(cls, rpc_image, expand=True):
|
||||
image = Image(**rpc_image)
|
||||
return cls._convert_with_links(image, pecan.request.host_url,
|
||||
expand)
|
||||
|
||||
@classmethod
|
||||
def sample(cls, expand=True):
|
||||
sample = cls(uuid='27e3153e-d5bf-4b7e-b517-fb518e17f35c',
|
||||
repo='ubuntu',
|
||||
tag='latest',
|
||||
size='700m',
|
||||
created_at=timeutils.utcnow(),
|
||||
updated_at=timeutils.utcnow())
|
||||
return cls._convert_with_links(sample, 'http://localhost:9517', expand)
|
||||
|
||||
|
||||
class ImageCollection(collection.Collection):
|
||||
"""API representation of a collection of images."""
|
||||
|
||||
fields = {
|
||||
'images': {
|
||||
'validate': types.List(types.Custom(Image)).validate,
|
||||
},
|
||||
'images'
|
||||
}
|
||||
|
||||
"""A list containing images objects"""
|
||||
@ -121,20 +46,10 @@ class ImageCollection(collection.Collection):
|
||||
def convert_with_links(rpc_images, limit, url=None,
|
||||
expand=False, **kwargs):
|
||||
collection = ImageCollection()
|
||||
# TODO(sbiswas7): This is the ugly part of the deal.
|
||||
# We need to convert this p thing below as dict for now
|
||||
# Removal of dict-compat lead to this change.
|
||||
collection.images = [Image.convert_with_links(p.as_dict(), expand)
|
||||
for p in rpc_images]
|
||||
collection.images = [view.format_image(url, p) for p in rpc_images]
|
||||
collection.next = collection.get_next(limit, url=url, **kwargs)
|
||||
return collection
|
||||
|
||||
@classmethod
|
||||
def sample(cls):
|
||||
sample = cls()
|
||||
sample.images = [Image.sample(expand=False)]
|
||||
return sample
|
||||
|
||||
|
||||
class ImagesController(rest.RestController):
|
||||
'''Controller for Images'''
|
||||
@ -206,9 +121,7 @@ class ImagesController(rest.RestController):
|
||||
# Set the HTTP Location Header
|
||||
pecan.response.location = link.build_url('images', new_image.uuid)
|
||||
pecan.response.status = 202
|
||||
# TODO(sbiswas7): Schema validation is a better approach than
|
||||
# back n forth conversion into dicts and objects.
|
||||
return Image.convert_with_links(new_image.as_dict())
|
||||
return view.format_image(pecan.request.host_url, new_image)
|
||||
|
||||
@pecan.expose('json')
|
||||
@exception.wrap_pecan_controller_exception
|
||||
|
43
zun/api/controllers/v1/views/images_view.py
Normal file
43
zun/api/controllers/v1/views/images_view.py
Normal file
@ -0,0 +1,43 @@
|
||||
#
|
||||
# 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 itertools
|
||||
|
||||
from zun.api.controllers import link
|
||||
|
||||
|
||||
_basic_keys = (
|
||||
'uuid',
|
||||
'repo',
|
||||
'tag'
|
||||
'size'
|
||||
)
|
||||
|
||||
|
||||
def format_image(url, image):
|
||||
def transform(key, value):
|
||||
if key not in _basic_keys:
|
||||
return
|
||||
if key == 'uuid':
|
||||
yield ('uuid', value)
|
||||
yield ('links', [link.Link.make_link(
|
||||
'self', url, 'images', value),
|
||||
link.Link.make_link(
|
||||
'bookmark', url,
|
||||
'images', value,
|
||||
bookmark=True)])
|
||||
else:
|
||||
yield (key, value)
|
||||
|
||||
return dict(itertools.chain.from_iterable(
|
||||
transform(k, v) for k, v in image.as_dict().items()))
|
@ -13,8 +13,6 @@
|
||||
import pecan
|
||||
from pecan import rest
|
||||
|
||||
from zun.api.controllers import base
|
||||
from zun.api.controllers import types
|
||||
from zun.api.controllers.v1 import collection
|
||||
from zun.api import servicegroup as svcgrp_api
|
||||
from zun.common import exception
|
||||
@ -22,74 +20,10 @@ from zun.common import policy
|
||||
from zun import objects
|
||||
|
||||
|
||||
class ZunService(base.APIBase):
|
||||
|
||||
fields = {
|
||||
'host': {
|
||||
'validate': types.String.validate,
|
||||
'validate_args': {
|
||||
'min_length': 1,
|
||||
'max_length': 255,
|
||||
},
|
||||
},
|
||||
'binary': {
|
||||
'validate': types.String.validate,
|
||||
'validate_args': {
|
||||
'min_length': 1,
|
||||
'max_length': 255,
|
||||
},
|
||||
},
|
||||
'state': {
|
||||
'validate': types.String.validate,
|
||||
'validate_args': {
|
||||
'min_length': 1,
|
||||
'max_length': 255,
|
||||
},
|
||||
},
|
||||
'id': {
|
||||
'validate': types.Integer.validate,
|
||||
'validate_args': {
|
||||
'minimum': 1,
|
||||
},
|
||||
},
|
||||
'report_count': {
|
||||
'validate': types.Integer.validate,
|
||||
'validate_args': {
|
||||
'minimum': 0,
|
||||
},
|
||||
},
|
||||
'disabled': {
|
||||
'validate': types.Bool.validate,
|
||||
'validate_args': {
|
||||
'default': False,
|
||||
},
|
||||
},
|
||||
'disabled_reason': {
|
||||
'validate': types.String.validate,
|
||||
'validate_args': {
|
||||
'min_length': 0,
|
||||
'max_length': 255,
|
||||
},
|
||||
},
|
||||
'created_at': {
|
||||
'validate': types.DateTime.validate,
|
||||
},
|
||||
'updated_at': {
|
||||
'validate': types.DateTime.validate,
|
||||
},
|
||||
}
|
||||
|
||||
def __init__(self, state, **kwargs):
|
||||
super(ZunService, self).__init__(**kwargs)
|
||||
setattr(self, 'state', state)
|
||||
|
||||
|
||||
class ZunServiceCollection(collection.Collection):
|
||||
|
||||
fields = {
|
||||
'services': {
|
||||
'validate': types.List(types.Custom(ZunService)).validate,
|
||||
},
|
||||
'services'
|
||||
}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
@ -102,9 +36,10 @@ class ZunServiceCollection(collection.Collection):
|
||||
collection = ZunServiceCollection()
|
||||
collection.services = []
|
||||
for p in rpc_hsvcs:
|
||||
hsvc = p.as_dict()
|
||||
alive = servicegroup_api.service_is_up(p)
|
||||
state = 'up' if alive else 'down'
|
||||
hsvc = ZunService(state, **p.as_dict())
|
||||
hsvc['state'] = state
|
||||
collection.services.append(hsvc)
|
||||
next = collection.get_next(limit=None, url=None, **kwargs)
|
||||
if next is not None:
|
||||
|
@ -12,28 +12,13 @@
|
||||
|
||||
import mock
|
||||
|
||||
from zun.api.controllers.v1 import zun_services as zservice
|
||||
from zun.api import servicegroup
|
||||
from zun import objects
|
||||
from zun.tests import base
|
||||
from zun.tests.unit.api import base as api_base
|
||||
from zun.tests.unit.api import utils as api_utils
|
||||
|
||||
|
||||
class TestZunServiceObject(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestZunServiceObject, self).setUp()
|
||||
self.rpc_dict = api_utils.zservice_get_data()
|
||||
|
||||
def test_msvc_obj_fields_filtering(self):
|
||||
"""Test that it does filtering fields """
|
||||
self.rpc_dict['fake-key'] = 'fake-value'
|
||||
msvco = zservice.ZunService("up", **self.rpc_dict)
|
||||
self.assertNotIn('fake-key', msvco.fields)
|
||||
|
||||
|
||||
class db_rec(object):
|
||||
class DbRec(object):
|
||||
|
||||
def __init__(self, d):
|
||||
self.rec_as_dict = d
|
||||
@ -53,7 +38,7 @@ class TestZunServiceController(api_base.FunctionalTest):
|
||||
for i in range(count):
|
||||
elem = api_utils.zservice_get_data()
|
||||
elem['id'] = i + 1
|
||||
rec = db_rec(elem)
|
||||
rec = DbRec(elem)
|
||||
reclist.append(rec)
|
||||
return reclist
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user