Use yaml based instead of template based format for objects filtering
This commit is contained in:
parent
509529dcef
commit
3397de81cb
@ -16,7 +16,7 @@ input:
|
|||||||
- service_name: keystone-admin
|
- service_name: keystone-admin
|
||||||
bind: '*:8080'
|
bind: '*:8080'
|
||||||
backends:
|
backends:
|
||||||
'with_items': '{{ with_tags("service/keystone") }}'
|
'with_tags': ['service/keystone']
|
||||||
'item':
|
'item':
|
||||||
'remote_name': '{{ item.name }}'
|
'remote_name': '{{ item.name }}'
|
||||||
'remote_addr': '{{ item.node.ip }}:{{ item.admin_port }}'
|
'remote_addr': '{{ item.node.ip }}:{{ item.admin_port }}'
|
||||||
@ -24,7 +24,7 @@ input:
|
|||||||
- service_name: keystone-pub
|
- service_name: keystone-pub
|
||||||
bind: '*:8081'
|
bind: '*:8081'
|
||||||
backends:
|
backends:
|
||||||
with_items: '{{ with_tags("service/keystone") }}'
|
with_tags: ["service/keystone"]
|
||||||
item:
|
item:
|
||||||
remote_name: '{{ item.name }}'
|
remote_name: '{{ item.name }}'
|
||||||
remote_addr: '{{ item.node.ip }}:{{ item.public_port }}'
|
remote_addr: '{{ item.node.ip }}:{{ item.public_port }}'
|
||||||
|
@ -9,8 +9,12 @@ actions:
|
|||||||
remove: simple/keystone/remove.yml
|
remove: simple/keystone/remove.yml
|
||||||
|
|
||||||
input:
|
input:
|
||||||
db_root_password: '{{ first_with_tags("entrypoint/mariadb").root_password }}'
|
db_root_password:
|
||||||
db_host: '{{ first_with_tags("entrypoint/mariadb").node.ip }}'
|
first_with_tags: ["entrypoint/mariadb"]
|
||||||
|
item: '{{ item.root_password }}'
|
||||||
|
db_host:
|
||||||
|
first_with_tags: ["entrypoint/mariadb"]
|
||||||
|
item: '{{ item.node.ip }}'
|
||||||
admin_port: 35357
|
admin_port: 35357
|
||||||
public_port: 5000
|
public_port: 5000
|
||||||
name: keystone-test
|
name: keystone-test
|
||||||
|
@ -117,7 +117,7 @@ class Cmd(object):
|
|||||||
'name': 'keystone-test',
|
'name': 'keystone-test',
|
||||||
'admin_port': '35357',
|
'admin_port': '35357',
|
||||||
'public_port': '5000',
|
'public_port': '5000',
|
||||||
'db_addr': '{{ first_with_tags("entrypoint/mariadb").node.ip }}'}},
|
'db_addr': {'first_with_tags': ["entrypoint/mariadb"], 'item': '{{ item.node.ip }}'}}},
|
||||||
|
|
||||||
{'id': 'haproxy',
|
{'id': 'haproxy',
|
||||||
'tags': ['service/haproxy'],
|
'tags': ['service/haproxy'],
|
||||||
@ -126,14 +126,14 @@ class Cmd(object):
|
|||||||
{'service_name': 'keystone-admin',
|
{'service_name': 'keystone-admin',
|
||||||
'bind': '*:8080',
|
'bind': '*:8080',
|
||||||
'backends': {
|
'backends': {
|
||||||
'with_items': '{{ with_tags("service/keystone") }}',
|
'with_tags': ["service/keystone"],
|
||||||
'item': {'name': '{{ item.name }}', 'addr': '{{ item.node.ip }}:{{ item.admin_port }}'}}},
|
'item': {'name': '{{ item.name }}', 'addr': '{{ item.node.ip }}:{{ item.admin_port }}'}}},
|
||||||
|
|
||||||
{'service_name': 'keystone-pub',
|
{'service_name': 'keystone-pub',
|
||||||
'bind': '*:8081',
|
'bind': '*:8081',
|
||||||
'backends': {
|
'backends': {
|
||||||
'with_items': '{{ with_tags("service/keystone") }}',
|
'with_tags': ["service/keystone"],
|
||||||
'item': {'name': '{{ item.name }}', 'addr': '{{ item.node.ip }}:{{ item.public_port }}'}}}]}},
|
'item': {'name': '{{ item.name }}', 'addr': '{{ item.node.ip }}:{{ item.public_port }}'}}}]}}
|
||||||
]
|
]
|
||||||
|
|
||||||
nodes = [
|
nodes = [
|
||||||
|
@ -12,13 +12,6 @@ import mock
|
|||||||
from jinja2 import Template
|
from jinja2 import Template
|
||||||
|
|
||||||
|
|
||||||
class SetEncoder(json.JSONEncoder):
|
|
||||||
def default(self, obj):
|
|
||||||
if isinstance(obj, set):
|
|
||||||
return list(obj)
|
|
||||||
return json.JSONEncoder.default(self, obj)
|
|
||||||
|
|
||||||
|
|
||||||
class Node(object):
|
class Node(object):
|
||||||
|
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
@ -53,34 +46,18 @@ class Resource(object):
|
|||||||
called_with_tags = []
|
called_with_tags = []
|
||||||
|
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
|
if value.get('first_with_tags'):
|
||||||
|
called_with_tags.extend(value.get('first_with_tags'))
|
||||||
|
elif value.get('with_tags'):
|
||||||
|
called_with_tags.extend(value.get('with_tags'))
|
||||||
|
|
||||||
for k, v in value.items():
|
for k, v in value.items():
|
||||||
self.depends_on(value=v, tags=tags)
|
self.depends_on(value=v, tags=tags)
|
||||||
elif isinstance(value, list):
|
elif isinstance(value, list):
|
||||||
for e in value:
|
for e in value:
|
||||||
self.depends_on(value=e, tags=tags)
|
self.depends_on(value=e, tags=tags)
|
||||||
elif isinstance(value, str):
|
elif isinstance(value, str):
|
||||||
env = Template(value)
|
return value
|
||||||
tags_call_mock = mock.MagicMock()
|
|
||||||
|
|
||||||
env.globals['with_tags'] = tags_call_mock
|
|
||||||
env.globals['first_with_tags'] = tags_call_mock
|
|
||||||
|
|
||||||
try:
|
|
||||||
env.render()
|
|
||||||
except jinja2.exceptions.UndefinedError:
|
|
||||||
# On dependency resolving stage we should
|
|
||||||
# not handle rendering errors, we need
|
|
||||||
# only information about graph, this
|
|
||||||
# information can be provided by tags
|
|
||||||
# filtering calls
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Get arguments, which are tags, and flatten the list
|
|
||||||
used_tags = sum(map(
|
|
||||||
lambda call: list(call[0]),
|
|
||||||
tags_call_mock.call_args_list), [])
|
|
||||||
|
|
||||||
called_with_tags.extend(used_tags)
|
|
||||||
|
|
||||||
tags.extend(called_with_tags)
|
tags.extend(called_with_tags)
|
||||||
|
|
||||||
@ -151,22 +128,48 @@ class DataGraph(nx.DiGraph):
|
|||||||
|
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
# Handle iterators
|
# Handle iterators
|
||||||
if value.get('with_items'):
|
if value.get('first_with_tags') or value.get('with_tags'):
|
||||||
|
|
||||||
if len(value.keys()) != 2:
|
if len(value.keys()) != 2:
|
||||||
raise Exception("Iterator should have two elements '{0}'".format(value))
|
raise Exception("Iterator should have two elements '{0}'".format(value))
|
||||||
|
|
||||||
result_list = []
|
def with_tags(*args):
|
||||||
iter_key = (set(value.keys()) - set(['with_items'])).pop()
|
resources_with_tags = filter(
|
||||||
|
lambda n: n[1]['tags'] & set(list(*args)),
|
||||||
|
previous_render.items())
|
||||||
|
|
||||||
rendered_with_items = []
|
return map(lambda n: n[1], resources_with_tags)
|
||||||
if isinstance(value['with_items'], list):
|
|
||||||
rendered_with_items = value['with_items']
|
method_name = 'with_tags'
|
||||||
elif isinstance(value['with_items'], str):
|
if value.get('first_with_tags'):
|
||||||
rendered_with_items = json.loads(self.render(value['with_items'], context, previous_render))
|
method_name = 'first_with_tags'
|
||||||
|
|
||||||
|
iter_key = (set(value.keys()) - set([method_name])).pop()
|
||||||
|
|
||||||
|
items = []
|
||||||
|
if isinstance(value[method_name], list):
|
||||||
|
items = with_tags(value[method_name])
|
||||||
|
elif isinstance(value[method_name], str):
|
||||||
|
items = with_tags([value[method_name]])
|
||||||
else:
|
else:
|
||||||
raise Exception('Cannot iterate over dict "{0}"'.format(value))
|
raise Exception('Cannot iterate over dict "{0}"'.format(value))
|
||||||
|
|
||||||
for item in rendered_with_items:
|
# first_with_tags returns a single object, hence we should
|
||||||
|
# render a single object
|
||||||
|
if value.get('first_with_tags'):
|
||||||
|
if len(items) > 1:
|
||||||
|
raise Exception('Returns too many objects, check that '
|
||||||
|
'tags assigned properly "{0}"'.format(value))
|
||||||
|
|
||||||
|
iter_ctx = copy.deepcopy(context)
|
||||||
|
iter_ctx[iter_key] = items[0]
|
||||||
|
return self.render(value[iter_key], iter_ctx, previous_render)
|
||||||
|
|
||||||
|
# If it's with_tags construction, than it returns a list
|
||||||
|
# we should render each element and return a list of rendered
|
||||||
|
# elements
|
||||||
|
result_list = []
|
||||||
|
for item in items:
|
||||||
iter_ctx = copy.deepcopy(context)
|
iter_ctx = copy.deepcopy(context)
|
||||||
iter_ctx[iter_key] = item
|
iter_ctx[iter_key] = item
|
||||||
result_list.append(self.render(value[iter_key], iter_ctx, previous_render))
|
result_list.append(self.render(value[iter_key], iter_ctx, previous_render))
|
||||||
@ -184,25 +187,6 @@ class DataGraph(nx.DiGraph):
|
|||||||
return map(lambda v: self.render(v, context, previous_render), value)
|
return map(lambda v: self.render(v, context, previous_render), value)
|
||||||
elif isinstance(value, str):
|
elif isinstance(value, str):
|
||||||
env = Template(value)
|
env = Template(value)
|
||||||
|
|
||||||
def first_with_tags(*args):
|
|
||||||
for uid, resource in previous_render.items():
|
|
||||||
if resource['tags'] & set(args):
|
|
||||||
return resource
|
|
||||||
|
|
||||||
# TODO Should we fail here?
|
|
||||||
return mock.MagicMock()
|
|
||||||
|
|
||||||
def with_tags(*args):
|
|
||||||
resources_with_tags = filter(
|
|
||||||
lambda n: n[1]['tags'] & set(args),
|
|
||||||
previous_render.items())
|
|
||||||
|
|
||||||
return json.dumps(map(lambda n: n[1], resources_with_tags), cls=SetEncoder)
|
|
||||||
|
|
||||||
env.globals['with_tags'] = with_tags
|
|
||||||
env.globals['first_with_tags'] = first_with_tags
|
|
||||||
|
|
||||||
return env.render(**context)
|
return env.render(**context)
|
||||||
else:
|
else:
|
||||||
# If non of above return value, e.g. if there is
|
# If non of above return value, e.g. if there is
|
||||||
|
Loading…
Reference in New Issue
Block a user