Support to list software configs
APIImpact List software configs GET /v1/{tenant_id}/software_configs Request params(optional) limit,marker Json response example {'software_configs':[ {'creation_time': '2015-06-25T07:15:56', 'group': 'Heat::Ungrouped', 'id': 'de879d1c-c9a5-4635-ba29-08a5690fec27', 'name': 'foo'}] } Change-Id: Iad691672874b64b393b85d2eb9a55b22facbd263 Closes-Bug: #1464248
This commit is contained in:
parent
3fd6b53079
commit
7975d8b46a
@ -59,6 +59,8 @@
|
||||
"stacks:list_snapshots": "rule:deny_stack_user",
|
||||
"stacks:restore_snapshot": "rule:deny_stack_user",
|
||||
|
||||
"software_configs:global_index": "rule:deny_everybody",
|
||||
"software_configs:index": "rule:deny_stack_user",
|
||||
"software_configs:create": "rule:deny_stack_user",
|
||||
"software_configs:show": "rule:deny_stack_user",
|
||||
"software_configs:delete": "rule:deny_stack_user",
|
||||
|
@ -334,6 +334,12 @@ class API(wsgi.Router):
|
||||
connect(controller=software_config_resource,
|
||||
path_prefix='/{tenant_id}/software_configs',
|
||||
routes=[
|
||||
{
|
||||
'name': 'software_config_index',
|
||||
'url': '',
|
||||
'action': 'index',
|
||||
'method': 'GET'
|
||||
},
|
||||
{
|
||||
'name': 'software_config_create',
|
||||
'url': '',
|
||||
|
@ -11,11 +11,14 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import six
|
||||
from webob import exc
|
||||
|
||||
from heat.api.openstack.v1 import util
|
||||
from heat.common import param_utils
|
||||
from heat.common import serializers
|
||||
from heat.common import wsgi
|
||||
from heat.rpc import api as rpc_api
|
||||
from heat.rpc import client as rpc_client
|
||||
|
||||
|
||||
@ -34,6 +37,44 @@ class SoftwareConfigController(object):
|
||||
def default(self, req, **args):
|
||||
raise exc.HTTPNotFound()
|
||||
|
||||
def _extract_bool_param(self, name, value):
|
||||
try:
|
||||
return param_utils.extract_bool(name, value)
|
||||
except ValueError as e:
|
||||
raise exc.HTTPBadRequest(six.text_type(e))
|
||||
|
||||
def _index(self, req, tenant_safe=True):
|
||||
whitelist = {
|
||||
'limit': 'single',
|
||||
'marker': 'single'
|
||||
}
|
||||
params = util.get_allowed_params(req.params, whitelist)
|
||||
scs = self.rpc_client.list_software_configs(req.context,
|
||||
tenant_safe=tenant_safe,
|
||||
**params)
|
||||
return {'software_configs': scs}
|
||||
|
||||
@util.policy_enforce
|
||||
def global_index(self, req):
|
||||
return self._index(req, tenant_safe=False)
|
||||
|
||||
@util.policy_enforce
|
||||
def index(self, req):
|
||||
"""
|
||||
Lists summary information for all software configs
|
||||
"""
|
||||
global_tenant = False
|
||||
name = rpc_api.PARAM_GLOBAL_TENANT
|
||||
if name in req.params:
|
||||
global_tenant = self._extract_bool_param(
|
||||
name,
|
||||
req.params.get(name))
|
||||
|
||||
if global_tenant:
|
||||
return self.global_index(req, req.context.tenant_id)
|
||||
|
||||
return self._index(req)
|
||||
|
||||
@util.policy_enforce
|
||||
def show(self, req, config_id):
|
||||
"""
|
||||
|
@ -306,6 +306,14 @@ def software_config_get(context, config_id):
|
||||
return IMPL.software_config_get(context, config_id)
|
||||
|
||||
|
||||
def software_config_get_all(context, limit=None, marker=None,
|
||||
tenant_safe=True):
|
||||
return IMPL.software_config_get_all(context,
|
||||
limit=limit,
|
||||
marker=marker,
|
||||
tenant_safe=tenant_safe)
|
||||
|
||||
|
||||
def software_config_delete(context, config_id):
|
||||
return IMPL.software_config_delete(context, config_id)
|
||||
|
||||
|
@ -870,6 +870,15 @@ def software_config_get(context, config_id):
|
||||
return result
|
||||
|
||||
|
||||
def software_config_get_all(context, limit=None, marker=None,
|
||||
tenant_safe=True):
|
||||
query = model_query(context, models.SoftwareConfig)
|
||||
if tenant_safe:
|
||||
query = query.filter_by(tenant=context.tenant_id)
|
||||
return _paginate_query(context, query, models.SoftwareConfig,
|
||||
limit=limit, marker=marker).all()
|
||||
|
||||
|
||||
def software_config_delete(context, config_id):
|
||||
config = software_config_get(context, config_id)
|
||||
session = orm_session.Session.object_session(config)
|
||||
|
@ -403,19 +403,20 @@ def format_validate_parameter(param):
|
||||
return res
|
||||
|
||||
|
||||
def format_software_config(sc):
|
||||
def format_software_config(sc, detail=True):
|
||||
if sc is None:
|
||||
return
|
||||
result = {
|
||||
rpc_api.SOFTWARE_CONFIG_ID: sc.id,
|
||||
rpc_api.SOFTWARE_CONFIG_NAME: sc.name,
|
||||
rpc_api.SOFTWARE_CONFIG_GROUP: sc.group,
|
||||
rpc_api.SOFTWARE_CONFIG_CONFIG: sc.config['config'],
|
||||
rpc_api.SOFTWARE_CONFIG_INPUTS: sc.config['inputs'],
|
||||
rpc_api.SOFTWARE_CONFIG_OUTPUTS: sc.config['outputs'],
|
||||
rpc_api.SOFTWARE_CONFIG_OPTIONS: sc.config['options'],
|
||||
rpc_api.SOFTWARE_CONFIG_CREATION_TIME: sc.created_at.isoformat(),
|
||||
rpc_api.SOFTWARE_CONFIG_CREATION_TIME: sc.created_at.isoformat()
|
||||
}
|
||||
if detail:
|
||||
result[rpc_api.SOFTWARE_CONFIG_CONFIG] = sc.config['config']
|
||||
result[rpc_api.SOFTWARE_CONFIG_INPUTS] = sc.config['inputs']
|
||||
result[rpc_api.SOFTWARE_CONFIG_OUTPUTS] = sc.config['outputs']
|
||||
result[rpc_api.SOFTWARE_CONFIG_OPTIONS] = sc.config['options']
|
||||
return result
|
||||
|
||||
|
||||
|
@ -266,7 +266,7 @@ class EngineService(service.Service):
|
||||
by the RPC caller.
|
||||
"""
|
||||
|
||||
RPC_API_VERSION = '1.9'
|
||||
RPC_API_VERSION = '1.10'
|
||||
|
||||
def __init__(self, host, topic, manager=None):
|
||||
super(EngineService, self).__init__()
|
||||
@ -1477,6 +1477,15 @@ class EngineService(service.Service):
|
||||
def show_software_config(self, cnxt, config_id):
|
||||
return self.software_config.show_software_config(cnxt, config_id)
|
||||
|
||||
@context.request_context
|
||||
def list_software_configs(self, cnxt, limit=None, marker=None,
|
||||
tenant_safe=True):
|
||||
return self.software_config.list_software_configs(
|
||||
cnxt,
|
||||
limit=limit,
|
||||
marker=marker,
|
||||
tenant_safe=tenant_safe)
|
||||
|
||||
@context.request_context
|
||||
def create_software_config(self, cnxt, group, name, config,
|
||||
inputs, outputs, options):
|
||||
|
@ -36,6 +36,16 @@ class SoftwareConfigService(service.Service):
|
||||
sc = software_config_object.SoftwareConfig.get_by_id(cnxt, config_id)
|
||||
return api.format_software_config(sc)
|
||||
|
||||
def list_software_configs(self, cnxt, limit=None, marker=None,
|
||||
tenant_safe=True):
|
||||
scs = software_config_object.SoftwareConfig.get_all(
|
||||
cnxt,
|
||||
limit=limit,
|
||||
marker=marker,
|
||||
tenant_safe=tenant_safe)
|
||||
result = [api.format_software_config(sc, detail=False) for sc in scs]
|
||||
return result
|
||||
|
||||
def create_software_config(self, cnxt, group, name, config,
|
||||
inputs, outputs, options):
|
||||
|
||||
|
@ -56,6 +56,11 @@ class SoftwareConfig(base.VersionedObject,
|
||||
return cls._from_db_object(
|
||||
context, cls(), db_api.software_config_get(context, config_id))
|
||||
|
||||
@classmethod
|
||||
def get_all(cls, context, **kwargs):
|
||||
scs = db_api.software_config_get_all(context, **kwargs)
|
||||
return [cls._from_db_object(context, cls(), sc) for sc in scs]
|
||||
|
||||
@classmethod
|
||||
def delete(cls, context, config_id):
|
||||
db_api.software_config_delete(context, config_id)
|
||||
|
@ -30,6 +30,7 @@ class EngineClient(object):
|
||||
1.1 - Add support_status argument to list_resource_types()
|
||||
1.4 - Add support for service list
|
||||
1.9 - Add template_type option to generate_template()
|
||||
1.10 - Add support for software config list
|
||||
'''
|
||||
|
||||
BASE_RPC_API_VERSION = '1.0'
|
||||
@ -511,6 +512,15 @@ class EngineClient(object):
|
||||
return self.call(cnxt, self.make_msg('show_software_config',
|
||||
config_id=config_id))
|
||||
|
||||
def list_software_configs(self, cnxt, limit=None, marker=None,
|
||||
tenant_safe=True):
|
||||
return self.call(cnxt,
|
||||
self.make_msg('list_software_configs',
|
||||
limit=limit,
|
||||
marker=marker,
|
||||
tenant_safe=tenant_safe),
|
||||
version='1.10')
|
||||
|
||||
def create_software_config(self, cnxt, group, name, config,
|
||||
inputs=None, outputs=None, options=None):
|
||||
inputs = inputs or []
|
||||
|
@ -1030,6 +1030,17 @@ class SqlAlchemyTest(common.HeatTestCase):
|
||||
self.ctx,
|
||||
config_id)
|
||||
|
||||
def test_software_config_get_all(self):
|
||||
self.assertEqual([], db_api.software_config_get_all(self.ctx))
|
||||
tenant_id = self.ctx.tenant_id
|
||||
software_config = db_api.software_config_create(
|
||||
self.ctx, {'name': 'config_mysql',
|
||||
'tenant': tenant_id})
|
||||
self.assertIsNotNone(software_config)
|
||||
software_configs = db_api.software_config_get_all(self.ctx)
|
||||
self.assertEqual(1, len(software_configs))
|
||||
self.assertEqual(software_config, software_configs[0])
|
||||
|
||||
def test_software_config_delete(self):
|
||||
tenant_id = self.ctx.tenant_id
|
||||
config = db_api.software_config_create(
|
||||
@ -1109,16 +1120,16 @@ class SqlAlchemyTest(common.HeatTestCase):
|
||||
values = self._deployment_values()
|
||||
deployment = db_api.software_deployment_create(self.ctx, values)
|
||||
self.assertIsNotNone(deployment)
|
||||
all = db_api.software_deployment_get_all(self.ctx)
|
||||
self.assertEqual(1, len(all))
|
||||
self.assertEqual(deployment, all[0])
|
||||
all = db_api.software_deployment_get_all(
|
||||
deployments = db_api.software_deployment_get_all(self.ctx)
|
||||
self.assertEqual(1, len(deployments))
|
||||
self.assertEqual(deployment, deployments[0])
|
||||
deployments = db_api.software_deployment_get_all(
|
||||
self.ctx, server_id=values['server_id'])
|
||||
self.assertEqual(1, len(all))
|
||||
self.assertEqual(deployment, all[0])
|
||||
all = db_api.software_deployment_get_all(
|
||||
self.assertEqual(1, len(deployments))
|
||||
self.assertEqual(deployment, deployments[0])
|
||||
deployments = db_api.software_deployment_get_all(
|
||||
self.ctx, server_id=str(uuid.uuid4()))
|
||||
self.assertEqual([], all)
|
||||
self.assertEqual([], deployments)
|
||||
|
||||
def test_software_deployment_update(self):
|
||||
deployment_id = str(uuid.uuid4())
|
||||
|
@ -39,7 +39,7 @@ class ServiceEngineTest(common.HeatTestCase):
|
||||
|
||||
def test_make_sure_rpc_version(self):
|
||||
self.assertEqual(
|
||||
'1.9',
|
||||
'1.10',
|
||||
service.EngineService.RPC_API_VERSION,
|
||||
('RPC version is changed, please update this test to new version '
|
||||
'and make sure additional test cases are added for RPC APIs '
|
||||
|
@ -48,6 +48,16 @@ class SoftwareConfigServiceTest(common.HeatTestCase):
|
||||
return self.engine.create_software_config(
|
||||
self.ctx, group, name, config, inputs, outputs, options)
|
||||
|
||||
def test_list_software_configs(self):
|
||||
config = self._create_software_config()
|
||||
config_id = config['id']
|
||||
self.assertIsNotNone(config)
|
||||
|
||||
configs = self.engine.list_software_configs(self.ctx)
|
||||
self.assertIsNotNone(configs)
|
||||
config_ids = [x['id'] for x in configs]
|
||||
self.assertIn(config_id, config_ids)
|
||||
|
||||
def test_show_software_config(self):
|
||||
config_id = str(uuid.uuid4())
|
||||
|
||||
|
@ -3737,6 +3737,15 @@ class RoutesTest(common.HeatTestCase):
|
||||
})
|
||||
|
||||
def test_software_configs(self):
|
||||
self.assertRoute(
|
||||
self.m,
|
||||
'/aaaa/software_configs',
|
||||
'GET',
|
||||
'index',
|
||||
'SoftwareConfigController',
|
||||
{
|
||||
'tenant_id': 'aaaa'
|
||||
})
|
||||
self.assertRoute(
|
||||
self.m,
|
||||
'/aaaa/software_configs',
|
||||
@ -4146,6 +4155,18 @@ class SoftwareConfigControllerTest(ControllerTest, common.HeatTestCase):
|
||||
self.assertRaises(
|
||||
webob.exc.HTTPNotFound, self.controller.default, None)
|
||||
|
||||
@mock.patch.object(policy.Enforcer, 'enforce')
|
||||
def test_index(self, mock_enforce):
|
||||
self._mock_enforce_setup(mock_enforce, 'index')
|
||||
req = self._get('/software_configs')
|
||||
with mock.patch.object(
|
||||
self.controller.rpc_client,
|
||||
'list_software_configs',
|
||||
return_value=[]):
|
||||
resp = self.controller.index(req, tenant_id=self.tenant)
|
||||
self.assertEqual(
|
||||
{'software_configs': []}, resp)
|
||||
|
||||
@mock.patch.object(policy.Enforcer, 'enforce')
|
||||
def test_show(self, mock_enforce):
|
||||
self._mock_enforce_setup(mock_enforce, 'show')
|
||||
|
@ -268,6 +268,11 @@ class EngineRpcAPITestCase(common.HeatTestCase):
|
||||
self._test_engine_api('set_watch_state', 'call',
|
||||
watch_name='watch1', state="xyz")
|
||||
|
||||
def test_list_software_configs(self):
|
||||
self._test_engine_api('list_software_configs', 'call',
|
||||
limit=mock.ANY, marker=mock.ANY,
|
||||
tenant_safe=mock.ANY)
|
||||
|
||||
def test_show_software_config(self):
|
||||
self._test_engine_api('show_software_config', 'call',
|
||||
config_id='cda89008-6ea6-4057-b83d-ccde8f0b48c9')
|
||||
|
Loading…
Reference in New Issue
Block a user