commit
7cb40c224b
17
reddwarf/flavor/__init__.py
Normal file
17
reddwarf/flavor/__init__.py
Normal file
@ -0,0 +1,17 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2012 OpenStack LLC.
|
||||
# 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.
|
||||
|
80
reddwarf/flavor/models.py
Normal file
80
reddwarf/flavor/models.py
Normal file
@ -0,0 +1,80 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010-2012 OpenStack LLC.
|
||||
# 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.
|
||||
|
||||
"""Model classes that form the core of instance flavor functionality."""
|
||||
|
||||
from reddwarf import db
|
||||
|
||||
from novaclient import exceptions as nova_exceptions
|
||||
from reddwarf.common import exception as rd_exceptions
|
||||
from reddwarf.common import utils
|
||||
from reddwarf.common.models import NovaRemoteModelBase
|
||||
from reddwarf.common.remote import create_nova_client
|
||||
|
||||
|
||||
class Flavor(object):
|
||||
|
||||
_data_fields = ['id', 'links', 'name', 'ram', 'vcpus']
|
||||
|
||||
def __init__(self, flavor=None, context=None, flavor_id=None):
|
||||
if flavor:
|
||||
self.flavor = flavor
|
||||
return
|
||||
if flavor_id and context:
|
||||
try:
|
||||
client = create_nova_client(context)
|
||||
self.flavor = client.flavors.get(flavor_id)
|
||||
except nova_exceptions.NotFound, e:
|
||||
raise rd_exceptions.NotFound(uuid=flavor_id)
|
||||
except nova_exceptions.ClientException, e:
|
||||
raise rd_exceptions.ReddwarfError(str(e))
|
||||
return
|
||||
msg = ("Flavor is not defined, and"
|
||||
" context and flavor_id were not specified.")
|
||||
raise InvalidModelError(msg)
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
return self.flavor.id
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.flavor.name
|
||||
|
||||
@property
|
||||
def ram(self):
|
||||
return self.flavor.ram
|
||||
|
||||
@property
|
||||
def vcpus(self):
|
||||
return self.flavor.vcpus
|
||||
|
||||
@property
|
||||
def links(self):
|
||||
return self.flavor.links
|
||||
|
||||
|
||||
class Flavors(NovaRemoteModelBase):
|
||||
|
||||
def __init__(self, context):
|
||||
nova_flavors = create_nova_client(context).flavors.list()
|
||||
self.flavors = [Flavor(flavor=item) for item in nova_flavors]
|
||||
|
||||
def __iter__(self):
|
||||
for item in self.flavors:
|
||||
yield item
|
||||
|
91
reddwarf/flavor/service.py
Normal file
91
reddwarf/flavor/service.py
Normal file
@ -0,0 +1,91 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010-2012 OpenStack LLC.
|
||||
# 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 routes
|
||||
import webob.exc
|
||||
|
||||
from reddwarf.common import exception
|
||||
from reddwarf.common import wsgi
|
||||
from reddwarf.flavor import models
|
||||
from reddwarf.flavor import views
|
||||
|
||||
|
||||
class BaseController(wsgi.Controller):
|
||||
"""Base controller class."""
|
||||
|
||||
exclude_attr = []
|
||||
exception_map = {
|
||||
webob.exc.HTTPUnprocessableEntity: [
|
||||
],
|
||||
webob.exc.HTTPBadRequest: [
|
||||
exception.BadRequest,
|
||||
],
|
||||
webob.exc.HTTPNotFound: [
|
||||
exception.NotFound,
|
||||
],
|
||||
webob.exc.HTTPConflict: [
|
||||
],
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def _extract_required_params(self, params, model_name):
|
||||
params = params or {}
|
||||
model_params = params.get(model_name, {})
|
||||
return utils.stringify_keys(utils.exclude(model_params,
|
||||
*self.exclude_attr))
|
||||
|
||||
|
||||
class FlavorController(BaseController):
|
||||
"""Controller for flavor functionality"""
|
||||
|
||||
def show(self, req, tenant_id, id):
|
||||
"""Return a single flavor."""
|
||||
context = req.environ[wsgi.CONTEXT_KEY]
|
||||
flavor = models.Flavor(context=context, flavor_id=id)
|
||||
# Pass in the request to build accurate links.
|
||||
return wsgi.Result(views.FlavorDetailView(flavor, req).data(), 200)
|
||||
|
||||
def detail(self, req, tenant_id):
|
||||
"""Return a list of flavors, with additional data about each flavor."""
|
||||
context = req.environ[wsgi.CONTEXT_KEY]
|
||||
flavors = models.Flavors(context=context)
|
||||
return wsgi.Result(views.FlavorsDetailView(flavors, req).data(), 200)
|
||||
|
||||
def index(self, req, tenant_id):
|
||||
"""Return all flavors."""
|
||||
context = req.environ[wsgi.CONTEXT_KEY]
|
||||
flavors = models.Flavors(context=context)
|
||||
return wsgi.Result(views.FlavorsView(flavors, req).data(), 200)
|
||||
|
||||
class API(wsgi.Router):
|
||||
"""API"""
|
||||
def __init__(self):
|
||||
mapper = routes.Mapper()
|
||||
super(API, self).__init__(mapper)
|
||||
self._flavor_router(mapper)
|
||||
|
||||
def _flavor_router(self, mapper):
|
||||
flavor_resource = FlavorController().create_resource()
|
||||
path = "/{tenant_id}/flavors"
|
||||
mapper.resource("flavor", path, controller=flavor_resource,
|
||||
collection={'detail': 'GET', '': 'GET'})
|
||||
|
||||
|
||||
def app_factory(global_conf, **local_conf):
|
||||
return API()
|
89
reddwarf/flavor/views.py
Normal file
89
reddwarf/flavor/views.py
Normal file
@ -0,0 +1,89 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010-2012 OpenStack LLC.
|
||||
# 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.
|
||||
|
||||
class FlavorView(object):
|
||||
|
||||
def __init__(self, flavor, req=None):
|
||||
self.flavor = flavor
|
||||
self.req = req
|
||||
|
||||
def data(self):
|
||||
return {"flavor": {
|
||||
'id': self.flavor.id,
|
||||
'links': self._build_links(),
|
||||
'name': self.flavor.name,
|
||||
}}
|
||||
|
||||
def _build_links(self):
|
||||
result = []
|
||||
#scheme = self.req.scheme
|
||||
scheme = 'https' # Forcing https
|
||||
endpoint = self.req.host
|
||||
splitpath = self.req.path.split('/')
|
||||
detailed = ''
|
||||
if splitpath[-1] == 'detail':
|
||||
detailed = '/detail'
|
||||
splitpath.pop(-1)
|
||||
flavorid = self.flavor.id
|
||||
if splitpath[-1] == flavorid:
|
||||
splitpath.pop(-1)
|
||||
href_template = "%(scheme)s://%(endpoint)s%(path)s/%(flavorid)s"
|
||||
for link in self.flavor.links:
|
||||
rlink = link
|
||||
href = rlink['href']
|
||||
if rlink['rel'] == 'self':
|
||||
path = '/'.join(splitpath)
|
||||
href = href_template % locals()
|
||||
elif rlink['rel'] == 'bookmark':
|
||||
splitpath.pop(2) # Remove the version.
|
||||
splitpath.pop(1) # Remove the tenant id.
|
||||
path = '/'.join(splitpath)
|
||||
href = href_template % locals()
|
||||
|
||||
rlink['href'] = href
|
||||
result.append(rlink)
|
||||
return result
|
||||
|
||||
|
||||
class FlavorDetailView(FlavorView):
|
||||
|
||||
def data(self):
|
||||
result = super(FlavorDetailView, self).data()
|
||||
details = {
|
||||
'ram': self.flavor.ram,
|
||||
'vcpus': self.flavor.vcpus,
|
||||
}
|
||||
result["flavor"].update(details)
|
||||
return result
|
||||
|
||||
|
||||
class FlavorsView(object):
|
||||
view = FlavorView
|
||||
|
||||
def __init__(self, flavors, req=None):
|
||||
self.flavors = flavors
|
||||
self.req = req
|
||||
|
||||
def data(self, detailed=False):
|
||||
data = []
|
||||
for flavor in self.flavors:
|
||||
data.append(self.view(flavor, req=self.req).data()['flavor'])
|
||||
return {"flavors": data}
|
||||
|
||||
|
||||
class FlavorsDetailView(FlavorsView):
|
||||
view = FlavorDetailView
|
@ -26,6 +26,11 @@ from reddwarf.common import wsgi
|
||||
from reddwarf.instance import models, views
|
||||
from reddwarf.common import exception as rd_exceptions
|
||||
|
||||
#TODO(ed-): Import these properly after this is restructured
|
||||
from reddwarf.flavor import models as flavormodels
|
||||
from reddwarf.flavor import views as flavorviews
|
||||
from reddwarf.flavor import service as flavorservice
|
||||
|
||||
CONFIG = config.Config
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -262,6 +267,7 @@ class API(wsgi.Router):
|
||||
mapper = routes.Mapper()
|
||||
super(API, self).__init__(mapper)
|
||||
self._instance_router(mapper)
|
||||
self._flavor_router(mapper) #TODO(ed-): Remove after restructure
|
||||
|
||||
def _instance_router(self, mapper):
|
||||
instance_resource = InstanceController().create_resource()
|
||||
@ -269,6 +275,13 @@ class API(wsgi.Router):
|
||||
mapper.resource("instance", path, controller=instance_resource,
|
||||
collection={'detail': 'GET'})
|
||||
|
||||
#TODO(ed-): remove this when all mention of flavorservice et cetera are moved away
|
||||
def _flavor_router(self, mapper):
|
||||
flavor_resource = flavorservice.FlavorController().create_resource()
|
||||
path = "/{tenant_id}/flavors"
|
||||
mapper.resource("flavor", path, controller=flavor_resource,
|
||||
collection={'detail': 'GET'})
|
||||
|
||||
|
||||
def app_factory(global_conf, **local_conf):
|
||||
return API()
|
||||
|
Loading…
x
Reference in New Issue
Block a user