199 lines
7.6 KiB
Python
199 lines
7.6 KiB
Python
# Copyright (c) 2015 Huawei Tech. Co., Ltd.
|
|
# 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 pecan
|
|
from pecan import expose
|
|
from pecan import rest
|
|
|
|
import oslo_db.exception as db_exc
|
|
|
|
import tricircle.common.context as t_context
|
|
from tricircle.common import utils
|
|
from tricircle.db import core
|
|
from tricircle.db import models
|
|
|
|
|
|
class FlavorManageController(rest.RestController):
|
|
# NOTE(zhiyuan) according to nova API reference, flavor creating and
|
|
# deleting should use '/flavors/os-flavor-manage' path, but '/flavors/'
|
|
# also supports this two operations to keep compatible with nova client
|
|
|
|
def __init__(self, project_id):
|
|
self.project_id = project_id
|
|
|
|
@expose(generic=True, template='json')
|
|
def post(self, **kw):
|
|
context = t_context.extract_context_from_environ()
|
|
if not context.is_admin:
|
|
pecan.abort(400, 'Admin role required to create flavors')
|
|
return
|
|
|
|
required_fields = ['name', 'ram', 'vcpus', 'disk']
|
|
if 'flavor' not in kw:
|
|
pass
|
|
if not utils.validate_required_fields_set(kw['flavor'],
|
|
required_fields):
|
|
pass
|
|
|
|
flavor_dict = {
|
|
'name': kw['flavor']['name'],
|
|
'flavorid': kw['flavor'].get('id'),
|
|
'memory_mb': kw['flavor']['ram'],
|
|
'vcpus': kw['flavor']['vcpus'],
|
|
'root_gb': kw['flavor']['disk'],
|
|
'ephemeral_gb': kw['flavor'].get('OS-FLV-EXT-DATA:ephemeral', 0),
|
|
'swap': kw['flavor'].get('swap', 0),
|
|
'rxtx_factor': kw['flavor'].get('rxtx_factor', 1.0),
|
|
'is_public': kw['flavor'].get('os-flavor-access:is_public', True),
|
|
}
|
|
|
|
try:
|
|
with context.session.begin():
|
|
flavor = core.create_resource(
|
|
context, models.InstanceTypes, flavor_dict)
|
|
except db_exc.DBDuplicateEntry:
|
|
pecan.abort(409, 'Flavor already exists')
|
|
return
|
|
except Exception:
|
|
pecan.abort(500, 'Fail to create flavor')
|
|
return
|
|
|
|
return {'flavor': flavor}
|
|
|
|
@expose(generic=True, template='json')
|
|
def delete(self, _id):
|
|
context = t_context.extract_context_from_environ()
|
|
with context.session.begin():
|
|
flavors = core.query_resource(context, models.InstanceTypes,
|
|
[{'key': 'flavorid',
|
|
'comparator': 'eq',
|
|
'value': _id}], [])
|
|
if not flavors:
|
|
pecan.abort(404, 'Flavor not found')
|
|
return
|
|
core.delete_resource(context,
|
|
models.InstanceTypes, flavors[0]['id'])
|
|
pecan.response.status = 202
|
|
return
|
|
|
|
|
|
class FlavorController(rest.RestController):
|
|
|
|
def __init__(self, project_id):
|
|
self.project_id = project_id
|
|
|
|
@pecan.expose()
|
|
def _lookup(self, action, *remainder):
|
|
if action == 'os-flavor-manage':
|
|
return FlavorManageController(self.project_id), remainder
|
|
|
|
@expose(generic=True, template='json')
|
|
def post(self, **kw):
|
|
context = t_context.extract_context_from_environ()
|
|
if not context.is_admin:
|
|
pecan.abort(400, 'Admin role required to create flavors')
|
|
return
|
|
|
|
required_fields = ['name', 'ram', 'vcpus', 'disk']
|
|
if 'flavor' not in kw:
|
|
pecan.abort(400, 'Request body not found')
|
|
return
|
|
if not utils.validate_required_fields_set(kw['flavor'],
|
|
required_fields):
|
|
pecan.abort(400, 'Required field not set')
|
|
return
|
|
|
|
flavor_dict = {
|
|
'name': kw['flavor']['name'],
|
|
'flavorid': kw['flavor'].get('id'),
|
|
'memory_mb': kw['flavor']['ram'],
|
|
'vcpus': kw['flavor']['vcpus'],
|
|
'root_gb': kw['flavor']['disk'],
|
|
'ephemeral_gb': kw['flavor'].get('OS-FLV-EXT-DATA:ephemeral', 0),
|
|
'swap': kw['flavor'].get('swap', 0),
|
|
'rxtx_factor': kw['flavor'].get('rxtx_factor', 1.0),
|
|
'is_public': kw['flavor'].get('os-flavor-access:is_public', True),
|
|
}
|
|
|
|
try:
|
|
with context.session.begin():
|
|
flavor = core.create_resource(
|
|
context, models.InstanceTypes, flavor_dict)
|
|
except db_exc.DBDuplicateEntry:
|
|
pecan.abort(409, 'Flavor already exists')
|
|
return
|
|
except Exception:
|
|
pecan.abort(500, 'Fail to create flavor')
|
|
return
|
|
|
|
flavor['id'] = flavor['flavorid']
|
|
del flavor['flavorid']
|
|
return {'flavor': flavor}
|
|
|
|
@expose(generic=True, template='json')
|
|
def get_one(self, _id):
|
|
# NOTE(zhiyuan) this function handles two kinds of requests
|
|
# GET /flavors/flavor_id
|
|
# GET /flavors/detail
|
|
context = t_context.extract_context_from_environ()
|
|
if _id == 'detail':
|
|
with context.session.begin():
|
|
flavors = core.query_resource(context, models.InstanceTypes,
|
|
[], [])
|
|
for flavor in flavors:
|
|
flavor['id'] = flavor['flavorid']
|
|
del flavor['flavorid']
|
|
return {'flavors': flavors}
|
|
else:
|
|
with context.session.begin():
|
|
flavors = core.query_resource(context, models.InstanceTypes,
|
|
[{'key': 'flavorid',
|
|
'comparator': 'eq',
|
|
'value': _id}], [])
|
|
if not flavors:
|
|
pecan.abort(404, 'Flavor not found')
|
|
return
|
|
flavor = flavors[0]
|
|
flavor['id'] = flavor['flavorid']
|
|
del flavor['flavorid']
|
|
return {'flavor': flavor}
|
|
|
|
@expose(generic=True, template='json')
|
|
def get_all(self):
|
|
context = t_context.extract_context_from_environ()
|
|
with context.session.begin():
|
|
flavors = core.query_resource(context, models.InstanceTypes,
|
|
[], [])
|
|
return {'flavors': [dict(
|
|
[('id', flavor['flavorid']),
|
|
('name', flavor['name'])]) for flavor in flavors]}
|
|
|
|
@expose(generic=True, template='json')
|
|
def delete(self, _id):
|
|
# TODO(zhiyuan) handle foreign key constraint
|
|
context = t_context.extract_context_from_environ()
|
|
with context.session.begin():
|
|
flavors = core.query_resource(context, models.InstanceTypes,
|
|
[{'key': 'flavorid',
|
|
'comparator': 'eq',
|
|
'value': _id}], [])
|
|
if not flavors:
|
|
pecan.abort(404, 'Flavor not found')
|
|
return
|
|
core.delete_resource(context,
|
|
models.InstanceTypes, flavors[0]['id'])
|
|
pecan.response.status = 202
|
|
return
|