Sudarshan Acharya 924a11fae7 Async instance create operation
202 response is sent before the calls to nova/volume are completed.
So need to rely on our database for some info in the response, and
hence the SimpleInstance.

If anything fails during the async creation process, ServiceStatus
is updated to ERROR.

Likewise, if the get/list calls fails from server/volume, we can
use the SimpleInstance.
2012-06-08 04:20:45 -05:00

195 lines
6.7 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 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 logging
from reddwarf.common import config
from reddwarf.common import utils
LOG = logging.getLogger(__name__)
def get_ip_address(addresses):
if addresses is not None and \
addresses.get('private') is not None and \
len(addresses['private']) > 0:
return [addr.get('addr') for addr in addresses['private']]
if addresses is not None and\
addresses.get('usernet') is not None and\
len(addresses['usernet']) > 0:
return [addr.get('addr') for addr in addresses['usernet']]
def get_volumes(volumes):
LOG.debug("volumes - %s" % volumes)
if volumes is not None and len(volumes) > 0:
return {'size': volumes[0].get('size')}
class InstanceView(object):
def __init__(self, instance, req=None, add_addresses=False,
add_volumes=False):
self.instance = instance
self.add_addresses = add_addresses
self.add_volumes = add_volumes
self.req = req
def data(self):
ip = get_ip_address(self.instance.addresses)
volumes = get_volumes(self.instance.volumes)
instance_dict = {
"id": self.instance.id,
"name": self.instance.name,
"status": self.instance.status,
"links": self._build_links()
}
dns_support = config.Config.get("reddwarf_dns_support", 'False')
if utils.bool_from_string(dns_support):
instance_dict['hostname'] = self.instance.hostname
if self.add_addresses and ip is not None and len(ip) > 0:
instance_dict['ip'] = ip
if self.add_volumes and volumes is not None:
instance_dict['volume'] = volumes
LOG.debug(instance_dict)
return {"instance": instance_dict}
def _build_links(self):
# TODO(ed-): Make generic, move to common?
result = []
scheme = 'https' # Forcing https
links = [link for link in self.instance.links]
links = [link['href'] for link in links if link['rel'] == 'self']
href_link = links[0]
splitpath = href_link.split('/')
endpoint = ''
if self.req:
endpoint = self.req.host
splitpath = self.req.path.split('/')
detailed = ''
if splitpath[-1] == 'detail':
detailed = '/detail'
splitpath.pop(-1)
instance_id = self.instance.id
if str(splitpath[-1]) == str(instance_id):
splitpath.pop(-1)
href_template = "%(scheme)s://%(endpoint)s%(path)s/%(instance_id)s"
for link in self.instance.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 InstanceDetailView(InstanceView):
def __init__(self, instance, req=None, add_addresses=False,
add_volumes=False):
super(InstanceDetailView, self).__init__(instance,
req=req,
add_addresses=add_addresses,
add_volumes=add_volumes)
def data(self):
result = super(InstanceDetailView, self).data()
result['instance']['created'] = self.instance.created
result['instance']['flavor'] = self._build_flavor()
result['instance']['updated'] = self.instance.updated
return result
def _build_flavor(self):
try:
return self.instance.flavor
except:
return {
'id': self.instance.db_info.flavor_id,
'links': self._build_flavor_links(),
}
def _build_flavor_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.instance.db_info.flavor_id
if str(splitpath[-1]) == str(flavorid):
splitpath.pop(-1)
href_template = "%(scheme)s://%(endpoint)s%(path)s/%(flavorid)s"
for link in self.instance.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)
for link in result:
link['href'] = link['href'].replace('instances', 'flavors')
return result
class InstancesView(object):
def __init__(self, instances, req=None, add_addresses=False,
add_volumes=False):
self.instances = instances
self.add_addresses = add_addresses
self.add_volumes = add_volumes
self.req = req
def data(self):
data = []
# These are model instances
for instance in self.instances:
data.append(self.data_for_instance(instance))
return {'instances': data}
def data_for_instance(self, instance):
view = InstanceView(instance, req=self.req,
add_addresses=self.add_addresses)
return view.data()['instance']
class InstancesDetailView(InstancesView):
def data_for_instance(self, instance):
return InstanceDetailView(instance, req=self.req,
add_addresses=self.add_addresses,
add_volumes=self.add_volumes).data()['instance']