ea03c1f55c
Change-Id: I90624cb58eca1104ede8446cef0c80342153a6aa
215 lines
7.0 KiB
Python
215 lines
7.0 KiB
Python
# Copyright (c) 2014 OpenStack Foundation.
|
|
# 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.
|
|
|
|
|
|
class CongressRulesManager(object):
|
|
"""Converts murano model to list of congress rules:
|
|
- murano:objects+(env_id, obj_id, type_name)
|
|
- murano:properties+(obj_id, prop_name, prop_value)
|
|
- murano:relationships+(source, target, name)
|
|
- murano:parent_types+(obj_id, parent_name)
|
|
- murano:states+(env_id, state)
|
|
"""
|
|
|
|
_rules = []
|
|
_env_id = ''
|
|
_class_loader = None
|
|
|
|
def convert(self, model, class_loader=None, tenant_id=None):
|
|
self._rules = []
|
|
self._class_loader = class_loader
|
|
|
|
if model is None:
|
|
return self._rules
|
|
|
|
self._env_id = model['?']['id']
|
|
# Environment owner is tenant.
|
|
self._owner_id = tenant_id
|
|
|
|
# Arbitrary property for tenant_id.
|
|
if tenant_id is not None:
|
|
r = PropertyRule(self._env_id, 'tenant_id', tenant_id)
|
|
self._rules.append(r)
|
|
|
|
state_rule = StateRule(self._env_id, 'pending')
|
|
self._rules.append(state_rule)
|
|
|
|
self._walk(model, self._process_item)
|
|
|
|
# Convert MuranoProperty containing reference to another object
|
|
# to MuranoRelationship.
|
|
object_ids = [rule.obj_id for rule in self._rules
|
|
if isinstance(rule, ObjectRule)]
|
|
|
|
self._rules = [self._create_relationship(rule, object_ids)
|
|
for rule in self._rules]
|
|
|
|
return self._rules
|
|
|
|
def _walk(self, obj, func):
|
|
|
|
if obj is None:
|
|
return
|
|
|
|
obj = self._to_dict(obj)
|
|
func(obj)
|
|
if isinstance(obj, list):
|
|
for v in obj:
|
|
self._walk(v, func)
|
|
elif isinstance(obj, dict):
|
|
for key, value in obj.iteritems():
|
|
self._walk(value, func)
|
|
|
|
def _process_item(self, obj):
|
|
if isinstance(obj, dict) and '?' in obj:
|
|
obj2 = self._create_object_rule(obj)
|
|
# Owner of components in environment is environment itself.
|
|
self._owner_id = self._env_id
|
|
|
|
self._rules.append(obj2)
|
|
self._rules.extend(self._create_propety_rules(obj2.obj_id, obj))
|
|
|
|
cls = obj['?']['type']
|
|
types = self._get_parent_types(cls, self._class_loader)
|
|
self._rules.extend(self._create_parent_type_rules(obj['?']['id'],
|
|
types))
|
|
|
|
@staticmethod
|
|
def _to_dict(obj):
|
|
# If we have MuranoObject class we need to convert to dictionary.
|
|
if 'to_dictionary' in dir(obj):
|
|
return obj.to_dictionary()
|
|
else:
|
|
return obj
|
|
|
|
def _create_object_rule(self, app):
|
|
return ObjectRule(app['?']['id'], self._owner_id, app['?']['type'])
|
|
|
|
def _create_propety_rules(self, obj_id, obj, prefix=""):
|
|
rules = []
|
|
|
|
# Skip when inside properties of other object.
|
|
if '?' in obj and prefix != "":
|
|
rules.append(RelationshipRule(obj_id, obj['?']['id'],
|
|
prefix.split('.')[0]))
|
|
return rules
|
|
|
|
for key, value in obj.iteritems():
|
|
if key == '?':
|
|
continue
|
|
|
|
if value is not None:
|
|
value = self._to_dict(value)
|
|
if isinstance(value, dict):
|
|
rules.extend(self._create_propety_rules(
|
|
obj_id, value, prefix + key + "."))
|
|
elif isinstance(value, list):
|
|
for v in value:
|
|
v = self._to_dict(v)
|
|
if not isinstance(v, dict):
|
|
rule = PropertyRule(obj_id, prefix + key, v)
|
|
rules.append(rule)
|
|
else:
|
|
rule = PropertyRule(obj_id, prefix + key, value)
|
|
rules.append(rule)
|
|
|
|
return rules
|
|
|
|
@staticmethod
|
|
def _is_relationship(rule, app_ids):
|
|
if not isinstance(rule, PropertyRule):
|
|
return False
|
|
|
|
return rule.prop_value in app_ids
|
|
|
|
def _create_relationship(self, rule, app_ids):
|
|
if self._is_relationship(rule, app_ids):
|
|
return RelationshipRule(rule.obj_id, rule.prop_value,
|
|
rule.prop_name)
|
|
else:
|
|
return rule
|
|
|
|
def _get_parent_types(self, type_name, class_loader):
|
|
types = set()
|
|
types.add(type_name)
|
|
if class_loader is not None:
|
|
cls = class_loader.get_class(type_name)
|
|
if cls is not None:
|
|
for parent in cls.parents:
|
|
types.add(parent.name)
|
|
types = types.union(
|
|
self._get_parent_types(parent.name, class_loader))
|
|
return types
|
|
|
|
@staticmethod
|
|
def _create_parent_type_rules(app_id, types):
|
|
rules = []
|
|
for type_name in types:
|
|
rules.append(ParentTypeRule(app_id, type_name))
|
|
return rules
|
|
|
|
|
|
class ObjectRule(object):
|
|
def __init__(self, obj_id, owner_id, type_name):
|
|
self.obj_id = obj_id
|
|
self.owner_id = owner_id
|
|
self.type_name = type_name
|
|
|
|
def __str__(self):
|
|
return 'murano:objects+("{0}", "{1}", "{2}")'.format(self.obj_id,
|
|
self.owner_id,
|
|
self.type_name)
|
|
|
|
|
|
class PropertyRule(object):
|
|
def __init__(self, obj_id, prop_name, prop_value):
|
|
self.obj_id = obj_id
|
|
self.prop_name = prop_name
|
|
self.prop_value = prop_value
|
|
|
|
def __str__(self):
|
|
return 'murano:properties+("{0}", "{1}", "{2}")'.format(
|
|
self.obj_id, self.prop_name, self.prop_value)
|
|
|
|
|
|
class RelationshipRule(object):
|
|
def __init__(self, source_id, target_id, rel_name):
|
|
self.source_id = source_id
|
|
self.target_id = target_id
|
|
self.rel_name = rel_name
|
|
|
|
def __str__(self):
|
|
return 'murano:relationships+("{0}", "{1}", "{2}")'.format(
|
|
self.source_id, self.target_id, self.rel_name)
|
|
|
|
|
|
class ParentTypeRule(object):
|
|
def __init__(self, obj_id, type_name):
|
|
self.obj_id = obj_id
|
|
self.type_name = type_name
|
|
|
|
def __str__(self):
|
|
return 'murano:parent_types+("{0}", "{1}")'.format(self.obj_id,
|
|
self.type_name)
|
|
|
|
|
|
class StateRule(object):
|
|
def __init__(self, obj_id, state):
|
|
self.obj_id = obj_id
|
|
self.state = state
|
|
|
|
def __str__(self):
|
|
return 'murano:states+("{0}", "{1}")'.format(self.obj_id, self.state)
|