Updates controllers to use nova flavors client where appropriate (create/delete flavor

or ResourceClass with flavor). Adds nova_flavor_uuid to Flavor model for tracking
the nova created flavors
This commit is contained in:
marios 2013-07-22 16:25:58 +03:00
parent 9696e1a80b
commit 323a29967e
4 changed files with 45 additions and 44 deletions

View File

@ -32,7 +32,7 @@ from tuskar.heat.client import HeatClient as heat_client
from tuskar.common import exception from tuskar.common import exception
from tuskar.openstack.common import log from tuskar.openstack.common import log
from tuskar.compute.nova import NovaClient
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
CONF = cfg.CONF CONF = cfg.CONF
@ -232,13 +232,10 @@ class ResourceClass(Base):
flavors = [] flavors = []
if resource_class.flavors: if resource_class.flavors:
for flav in resource_class.flavors: for flav in resource_class.flavors:
flavor = Flavor.add_capacities(resource_class.id,
flav)
flavors.append(flavor)
return ResourceClass(links=links, flavor = Flavor.add_capacities(resource_class.id, flav)
racks=racks, flavors.append(flavor)
flavors=flavors, return ResourceClass(links=links, racks=racks, flavors=flavors,
**(resource_class.as_dict())) **(resource_class.as_dict()))
@ -270,7 +267,7 @@ class RacksController(rest.RestController):
@wsme.validate(Rack) @wsme.validate(Rack)
@wsme_pecan.wsexpose(Rack, wtypes.text, body=Rack, status_code=200) @wsme_pecan.wsexpose(Rack, wtypes.text, body=Rack, status_code=200)
def put(self, rack_id, rack): def put(self, rack_id, rack):
"""Update the Rack.""" """Update the Rack"""
try: try:
result = pecan.request.dbapi.update_rack(rack_id, rack) result = pecan.request.dbapi.update_rack(rack_id, rack)
@ -336,6 +333,8 @@ class RacksController(rest.RestController):
class FlavorsController(rest.RestController): class FlavorsController(rest.RestController):
"""REST controller for Flavor.""" """REST controller for Flavor."""
nova=NovaClient()
#POST /api/resource_classes/1/flavors #POST /api/resource_classes/1/flavors
@wsme.validate(Flavor) @wsme.validate(Flavor)
@wsme_pecan.wsexpose(Flavor, wtypes.text, body=Flavor, status_code=201) @wsme_pecan.wsexpose(Flavor, wtypes.text, body=Flavor, status_code=201)
@ -343,13 +342,17 @@ class FlavorsController(rest.RestController):
"""Create a new Flavor for a ResourceClass.""" """Create a new Flavor for a ResourceClass."""
try: try:
flavor = pecan.request.dbapi.create_resource_class_flavor( flavor = pecan.request.dbapi.create_resource_class_flavor(
resource_class_id, flavor) resource_class_id,flavor)
nova_flavor_uuid = self.nova.create_flavor(flavor,
pecan.request.dbapi.get_resource_class(resource_class_id).name)
pecan.request.dbapi.update_flavor_nova_uuid(flavor.id, nova_flavor_uuid)
except Exception as e: except Exception as e:
LOG.exception(e) LOG.exception(e)
raise wsme.exc.ClientSideError(_("Invalid data")) raise wsme.exc.ClientSideError(_("Invalid data"))
pecan.response.status_code = 201 pecan.response.status_code = 201
return Flavor.add_capacities(resource_class_id, flavor) return Flavor.add_capacities(resource_class_id, flavor)
#Do we need this, i.e. GET /api/resource_classes/1/flavors #Do we need this, i.e. GET /api/resource_classes/1/flavors
#i.e. return just the flavors for a given resource_class? #i.e. return just the flavors for a given resource_class?
@wsme_pecan.wsexpose([Flavor], wtypes.text) @wsme_pecan.wsexpose([Flavor], wtypes.text)
@ -358,7 +361,7 @@ class FlavorsController(rest.RestController):
flavors = [] flavors = []
for flavor in pecan.request.dbapi.get_flavors(resource_class_id): for flavor in pecan.request.dbapi.get_flavors(resource_class_id):
flavors.append(Flavor.add_capacities(resource_class_id, flavor)) flavors.append(Flavor.add_capacities(resource_class_id, flavor))
return flavors return flavors
#return [Flavor.from_db_model(flavor) for flavor in result] #return [Flavor.from_db_model(flavor) for flavor in result]
@wsme_pecan.wsexpose(Flavor, wtypes.text, wtypes.text) @wsme_pecan.wsexpose(Flavor, wtypes.text, wtypes.text)
@ -373,7 +376,7 @@ class FlavorsController(rest.RestController):
"""Update an existing ResourceClass Flavor""" """Update an existing ResourceClass Flavor"""
try: try:
flavor = pecan.request.dbapi.update_resource_class_flavor( flavor = pecan.request.dbapi.update_resource_class_flavor(
resource_class_id, flavor_id, flavor) resource_class_id, flavor_id, flavor)
except Exception as e: except Exception as e:
LOG.exception(e) LOG.exception(e)
raise wsme.exc.ClientSideError(_("Invalid data")) raise wsme.exc.ClientSideError(_("Invalid data"))
@ -383,7 +386,8 @@ class FlavorsController(rest.RestController):
def delete(self, resource_class_id, flavor_id): def delete(self, resource_class_id, flavor_id):
"""Delete a Flavor.""" """Delete a Flavor."""
#pecan.response.status_code = 204 #pecan.response.status_code = 204
pecan.request.dbapi.delete_flavor(flavor_id) nova_flavor_uuid = pecan.request.dbapi.delete_flavor(flavor_id)
self.nova.delete_flavor(nova_flavor_uuid)
class ResourceClassesController(rest.RestController): class ResourceClassesController(rest.RestController):
@ -391,18 +395,16 @@ class ResourceClassesController(rest.RestController):
flavors = FlavorsController() flavors = FlavorsController()
"""
_custom_actions = {
'flavors': ['GET', 'POST', 'DELETE', 'PUT']
}
"""
@wsme.validate(ResourceClass) @wsme.validate(ResourceClass)
@wsme_pecan.wsexpose(ResourceClass, body=ResourceClass, status_code=201) @wsme_pecan.wsexpose(ResourceClass, body=ResourceClass, status_code=201)
def post(self, resource_class): def post(self, resource_class):
"""Create a new Resource Class.""" """Create a new Resource Class."""
try: try:
result = pecan.request.dbapi.create_resource_class(resource_class) result = pecan.request.dbapi.create_resource_class(resource_class)
#create any flavors included in this resource_class creation
for flav in result.flavors:
nova_flavor_uuid = self.flavors.nova.create_flavor(flav, result.name)
pecan.request.dbapi.update_flavor_nova_uuid(flav.id, nova_flavor_uuid)
except Exception as e: except Exception as e:
LOG.exception(e) LOG.exception(e)
raise wsme.exc.ClientSideError(_("Invalid data")) raise wsme.exc.ClientSideError(_("Invalid data"))
@ -440,7 +442,7 @@ class ResourceClassesController(rest.RestController):
result = [] result = []
for rc in pecan.request.dbapi.get_resource_classes(None): for rc in pecan.request.dbapi.get_resource_classes(None):
result.append(ResourceClass.convert(rc, pecan.request.host_url)) result.append(ResourceClass.convert(rc, pecan.request.host_url))
return result return result
@wsme_pecan.wsexpose(ResourceClass, unicode) @wsme_pecan.wsexpose(ResourceClass, unicode)
def get_one(self, resource_class_id): def get_one(self, resource_class_id):
@ -455,25 +457,13 @@ class ResourceClassesController(rest.RestController):
# #
# TODO(mfojtik): Update the HEAT template at this point # TODO(mfojtik): Update the HEAT template at this point
# #
#DELETE any resource class flavors from nova too
for flav in pecan.request.dbapi.get_flavors(resource_class_id):
nova_flavor_uuid = pecan.request.dbapi.delete_flavor(flav.id)
self.flavors.nova.delete_flavor(nova_flavor_uuid)
pecan.request.dbapi.delete_resource_class(resource_class_id) pecan.request.dbapi.delete_resource_class(resource_class_id)
"""
@wsme_pecan.wsexpose(None, wtypes.text, wtypes.text, status_code=204)
def flavors(self, foo_id, resource_class_id):
#Retrieve Flavors for a given Resource Class""
import pdb;pdb.set_trace()
method = pecan.request.method
if method=="GET":
return "GET"
elif method=="POST":
return "POST"
elif method=="DELETE":
return "DELETE"
elif method=="PUT":
return "PUT"
else:
return "ERROR"
"""
class DataCenterController(rest.RestController): class DataCenterController(rest.RestController):

View File

View File

@ -226,8 +226,20 @@ class Connection(api.Connection):
session.close() session.close()
return flavor return flavor
def update_resource_class_flavor(self, resource_class_id, def update_flavor_nova_uuid(self, flavor_id, nova_uuid):
flavor_id, new_flavor): session = get_session()
session.begin()
try:
flavor = self.get_flavor(flavor_id)
flavor.nova_flavor_uuid = nova_uuid
session.add(flavor)
session.commit()
return True
except Exception:
session.rollback()
raise
def update_resource_class_flavor(self, resource_class_id, flavor_id, new_flavor):
session = get_session() session = get_session()
session.begin() session.begin()
try: try:
@ -458,7 +470,7 @@ class Connection(api.Connection):
with session.begin(): with session.begin():
if self.delete_capacities(flavor, session): if self.delete_capacities(flavor, session):
session.delete(flavor) session.delete(flavor)
return True return flavor.nova_flavor_uuid
def delete_capacities(self, resource, session): def delete_capacities(self, resource, session):
try: try:

View File

@ -156,12 +156,11 @@ class Flavor(Base):
resource_class_id = Column(Integer, ForeignKey('resource_classes.id', resource_class_id = Column(Integer, ForeignKey('resource_classes.id',
onupdate="cascade")) onupdate="cascade"))
max_vms = Column(Integer) max_vms = Column(Integer)
nova_flavor_uuid = Column(String(length=128))
capacities = relationship("Capacity", capacities = relationship("Capacity",
secondary= secondary=Base.metadata.tables['flavor_capacities'],
Base.metadata.tables['flavor_capacities'], cascade="all, delete",
cascade="all, delete", lazy='joined')
lazy='joined')
class ResourceClass(Base): class ResourceClass(Base):
"""Represents a Resource Class.""" """Represents a Resource Class."""