Cherry-pick following change-ids from release-0.2.

Ie214f0fc9467171b2feb17b2356e834237786bb7
Iaba3df12b2ff0f415ee149e7173529ef2ad31b15

Change-Id: I969361b7a13f57db72ad08f68d98b2730fd0840b
This commit is contained in:
Serg Melikyan 2013-08-15 11:25:39 +04:00 committed by Timur Sufiev
parent 9b20e9a725
commit bc87e2f8a7
10 changed files with 80 additions and 70 deletions

View File

@ -21,5 +21,5 @@ ENV_SCHEMA = {
"id": {"type": "string"},
"name": {"type": "string"}
},
"required": ["id"]
"required": ["id", "name"]
}

View File

@ -55,7 +55,7 @@ class Controller(object):
@utils.verify_session
@normalize_path
def post(self, request, environment_id, path, body):
log.debug(_('Services:Post <EnvId: {0}, , Path: {2}, '
log.debug(_('Services:Post <EnvId: {0}, Path: {2}, '
'Body: {1}>'.format(environment_id, body, path)))
post_data = CoreServices.post_data
@ -69,7 +69,7 @@ class Controller(object):
@utils.verify_session
@normalize_path
def put(self, request, environment_id, path, body):
log.debug(_('Services:Put <EnvId: {0}, , Path: {2}, '
log.debug(_('Services:Put <EnvId: {0}, Path: {2}, '
'Body: {1}>'.format(environment_id, body, path)))
put_data = CoreServices.put_data

View File

@ -12,12 +12,12 @@
# License for the specific language governing permissions and limitations
# under the License.
import eventlet
from jsonschema import validate
from muranoapi.common.uuidutils import generate_uuid
import types
from collections import deque
from functools import wraps
import eventlet
from jsonschema import validate
import types
from muranoapi.openstack.common import log as logging
@ -101,6 +101,18 @@ class TraverseHelper(object):
node = TraverseHelper.get(path, source)
node.append(value)
@staticmethod
def extend(path, value, source):
"""
Extend list by appending elements from the iterable.
:param path: string with path to desired value
:param value: value
:param source: List
"""
node = TraverseHelper.get(path, source)
node.extend(value)
@staticmethod
def remove(path, source):
"""
@ -125,17 +137,6 @@ class TraverseHelper(object):
raise ValueError('Source object or path is malformed')
def auto_id(value):
if isinstance(value, types.DictionaryType):
value['id'] = generate_uuid()
for k, v in value.iteritems():
value[k] = auto_id(v)
if isinstance(value, types.ListType):
for item in value:
auto_id(item)
return value
def build_entity_map(value):
def build_entity_map_recursive(value, id_map):
if isinstance(value, types.DictionaryType):

View File

@ -12,9 +12,10 @@
# License for the specific language governing permissions and limitations
# under the License.
from muranoapi.common.utils import TraverseHelper, auto_id
from muranoapi.common.utils import TraverseHelper
from muranoapi.db.services.environments import EnvironmentServices
from muranoapi.openstack.common import timeutils
import types
class CoreServices(object):
@ -66,16 +67,12 @@ class CoreServices(object):
if not 'services' in env_description:
env_description['services'] = []
data = auto_id(data)
if path == '/services':
data['created'] = str(timeutils.utcnow())
data['updated'] = str(timeutils.utcnow())
if isinstance(data, types.ListType):
TraverseHelper.extend(path, data, env_description)
else:
TraverseHelper.insert(path, data, env_description)
for idx, unit in enumerate(data['units']):
unit['name'] = data['name'] + '_instance_' + str(idx)
TraverseHelper.insert(path, data, env_description)
save_description(session_id, env_description)
return data

View File

@ -16,9 +16,11 @@ from collections import namedtuple
from jsonschema import validate
from muranoapi.api.v1.schemas import ENV_SCHEMA
from muranoapi.common import config
from muranoapi.common.uuidutils import generate_uuid
from muranoapi.db.models import Session, Environment
from muranoapi.db.services.sessions import SessionServices, SessionState
from muranoapi.db.session import get_session
from muranoapi.openstack.common import timeutils
from muranocommon.messaging import MqClient, Message
@ -175,6 +177,37 @@ class EnvironmentServices(object):
unit = get_session()
session = unit.query(Session).get(session_id)
EnvironmentServices.normalize(environment)
validate(environment, ENV_SCHEMA)
session.description = environment
session.save(unit)
@staticmethod
def normalize(environment):
if 'id' not in environment:
environment['id'] = generate_uuid()
if 'services' not in environment:
return
for service in environment['services']:
if 'id' not in service:
service['id'] = generate_uuid()
if 'created' not in service:
service['created'] = str(timeutils.utcnow())
if 'updated' not in service:
service['updated'] = str(timeutils.utcnow())
if 'units' not in service:
continue
for idx, unit in enumerate(service['units']):
if 'id' not in unit:
unit['id'] = generate_uuid()
if 'name' not in unit:
unit['name'] = '{srv_name}_instance_{number}'.format(
srv_name=service['name'], number=idx
)

View File

@ -16,6 +16,7 @@ from collections import namedtuple
from muranoapi.common import config
from muranoapi.db.models import Session, Environment, Deployment, Status
from muranoapi.db.session import get_session
from muranocommon.helpers.token_sanitizer import TokenSanitizer
from muranocommon.messaging import MqClient, Message
@ -26,6 +27,11 @@ SessionState = namedtuple('SessionState', ['open', 'deploying', 'deployed'])(
)
def secure_description(description):
sanitizer = TokenSanitizer()
return sanitizer.sanitize(description)
class SessionServices(object):
@staticmethod
def get_sessions(environment_id, state=None):
@ -125,9 +131,7 @@ class SessionServices(object):
session.state = SessionState.deploying
deployment = Deployment()
deployment.environment_id = environment['id']
deployment.description = dict(session.description)
if 'token' in deployment.description:
del deployment.description['token']
deployment.description = secure_description(dict(session.description))
status = Status()
status.text = "Deployment scheduled"
status.level = "info"

View File

@ -88,6 +88,18 @@ class TraverseHelperTests(unittest.TestCase):
value = TraverseHelper.get('/obj/attr', source)
self.assertListEqual(value, [1, 2, 3, 4])
def test_extending_list_with_list(self):
source = {'attr': [1, 2, 3]}
TraverseHelper.extend('/attr', [4, 5], source)
value = TraverseHelper.get('/attr', source)
self.assertListEqual(value, [1, 2, 3, 4, 5])
def test_nested_extending_list_with_list(self):
source = {'obj': {'attr': [1, 2, 3]}}
TraverseHelper.extend('/obj/attr', [4, 5], source)
value = TraverseHelper.get('/obj/attr', source)
self.assertListEqual(value, [1, 2, 3, 4, 5])
def test_attribute_remove_from_dict(self):
source = {'attr1': False, 'attr2': True}
TraverseHelper.remove('/attr1', source)

View File

@ -1,38 +0,0 @@
# Copyright (c) 2013 Mirantis, Inc.
#
# 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 unittest2 as unittest
from muranoapi.common.utils import auto_id
class AutoIdTests(unittest.TestCase):
def test_simple_dict(self):
source = {"attr": True}
value = auto_id(source)
self.assertIn('id', value)
def test_nested_lists(self):
source = {"attr": True, "obj": {"attr": False}}
value = auto_id(source)
self.assertIn('id', value)
def test_list_with_ints(self):
source = [0, 1, 2, 3]
value = auto_id(source)
self.assertListEqual(value, source)
def test_list_with_dicts(self):
source = [{"attr": True}, {"attr": False}]
value = auto_id(source)
for item in value:
self.assertIn('id', item)

View File

@ -31,4 +31,4 @@ passlib
jsonschema==2.0.0
python-keystoneclient>=0.2.0
oslo.config
http://github.com/sergmelikyan/murano-common/releases/download/0.2.1/muranocommon-0.2.1.tar.gz#egg=muranocommon-0.2.1
http://tarballs.openstack.org/murano-common/murano-common-release-0.2.tar.gz#egg=muranocommon-dev

View File

@ -15,6 +15,7 @@
[metadata]
name = muranoapi
version = 0.2
summary = Murano API
description-file =
README.rst
@ -65,4 +66,4 @@ input_file = muranoapi/locale/muranoapi.pot
[extract_messages]
keywords = _ gettext ngettext l_ lazy_gettext
mapping_file = babel.cfg
output_file = muranoapi/locale/muranoapi.pot
output_file = muranoapi/locale/muranoapi.pot