Add connect action
This commit is contained in:
parent
1470125937
commit
8033017c23
@ -29,6 +29,7 @@ from solar import extensions
|
||||
from solar import utils
|
||||
from solar.core import data
|
||||
from solar.core.resource import assign_resources_to_nodes
|
||||
from solar.core.resource import connect_resources
|
||||
from solar.core.tags_set_parser import Expression
|
||||
from solar.interfaces.db import get_db
|
||||
|
||||
@ -88,6 +89,13 @@ class Cmd(object):
|
||||
parser.add_argument('-n', '--nodes')
|
||||
parser.add_argument('-r', '--resources')
|
||||
|
||||
# Perform resources connection
|
||||
parser = self.subparser.add_parser('connect')
|
||||
parser.set_defaults(func=getattr(self, 'connect'))
|
||||
parser.add_argument(
|
||||
'-p',
|
||||
'--profile')
|
||||
|
||||
def profile(self, args):
|
||||
if args.create:
|
||||
params = {'tags': args.tags, 'id': args.id}
|
||||
@ -108,6 +116,10 @@ class Cmd(object):
|
||||
def discover(self, args):
|
||||
Discovery({'id': 'discovery'}).discover()
|
||||
|
||||
def connect(self, args):
|
||||
profile = self.db.get_record('profiles', args.profile)
|
||||
connect_resources(profile)
|
||||
|
||||
def assign(self, args):
|
||||
nodes = filter(
|
||||
lambda n: Expression(args.nodes, n.get('tags', [])).evaluate(),
|
||||
|
68
solar/solar/core/connections.py
Normal file
68
solar/solar/core/connections.py
Normal file
@ -0,0 +1,68 @@
|
||||
|
||||
import copy
|
||||
import json
|
||||
|
||||
from itertools import imap, ifilter
|
||||
|
||||
import networkx as nx
|
||||
import jinja2
|
||||
import mock
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
|
||||
def depends_on(init_value, value=None, tags=None):
|
||||
if tags is None:
|
||||
tags = []
|
||||
|
||||
if value is None:
|
||||
value = init_value
|
||||
|
||||
called_with_tags = []
|
||||
|
||||
if isinstance(value, dict):
|
||||
if value.get('first_resource'):
|
||||
called_with_tags.extend(value.get('first_resource'))
|
||||
elif value.get('filter_resources'):
|
||||
called_with_tags.extend(value.get('filter_resources'))
|
||||
|
||||
for k, v in value.items():
|
||||
depends_on(init_value, value=v, tags=tags)
|
||||
elif isinstance(value, list):
|
||||
for e in value:
|
||||
depends_on(init_value, value=e, tags=tags)
|
||||
elif isinstance(value, str):
|
||||
return value
|
||||
|
||||
tags.extend(called_with_tags)
|
||||
|
||||
return tags
|
||||
|
||||
|
||||
class ResourcesConnectionGraph(object):
|
||||
|
||||
def __init__(self, connections, resources, *args, **kwargs):
|
||||
super(ResourcesConnectionGraph, self).__init__(*args, **kwargs)
|
||||
self.connections = connections
|
||||
self.resources = resources
|
||||
|
||||
def iter_connections(self):
|
||||
for connection in self.connections:
|
||||
connections_from = self.resources_with_tags(depends_on(connection))
|
||||
connections_to = self.resources_with_tags(connection['for_resources'])
|
||||
mapping = self.make_mapping(connection)
|
||||
|
||||
for connection_from in connections_from:
|
||||
for connection_to in connections_to:
|
||||
if connection_from == connection_to:
|
||||
continue
|
||||
|
||||
yield {'from': connection_from, 'to': connection_to, 'mapping': mapping}
|
||||
|
||||
def resources_with_tags(self, tags):
|
||||
"""Filter all resources which have tags
|
||||
"""
|
||||
return filter(lambda r: set(r.tags) & set(tags), self.resources)
|
||||
|
||||
def make_mapping(self, connection):
|
||||
return connection['mapping']
|
@ -5,6 +5,7 @@ class Profile(object):
|
||||
self._profile = profile
|
||||
self.tags = set(profile['tags'])
|
||||
self.extensions = profile.get('extensions', [])
|
||||
self.connections = profile.get('connections', [])
|
||||
|
||||
def get(self, key):
|
||||
return self._profile.get(key, None)
|
||||
|
@ -15,6 +15,8 @@ from solar.core import signals
|
||||
from solar.core import utils
|
||||
from solar.core import validation
|
||||
|
||||
from solar.core.connections import ResourcesConnectionGraph
|
||||
|
||||
|
||||
class Resource(object):
|
||||
def __init__(self, name, metadata, args, base_dir, tags=None):
|
||||
@ -24,6 +26,9 @@ class Resource(object):
|
||||
self.actions = metadata['actions'].keys() if metadata['actions'] else None
|
||||
self.args = {}
|
||||
for arg_name, arg_value in args.items():
|
||||
if not self.metadata['input'].get(arg_name):
|
||||
continue
|
||||
|
||||
metadata_arg = self.metadata['input'][arg_name]
|
||||
type_ = validation.schema_input_type(metadata_arg.get('schema', 'str'))
|
||||
|
||||
@ -108,7 +113,6 @@ class Resource(object):
|
||||
|
||||
meta_file = os.path.join(self.base_dir, 'meta.yaml')
|
||||
with open(meta_file, 'w') as f:
|
||||
f.write(yaml.dump(metadata))
|
||||
f.write(yaml.dump(metadata, default_flow_style=False))
|
||||
|
||||
|
||||
@ -128,13 +132,12 @@ def create(name, base_path, dest_path, args, connections={}):
|
||||
meta['id'] = name
|
||||
meta['version'] = '1.0.0'
|
||||
meta['actions'] = {}
|
||||
meta['tags'] = []
|
||||
|
||||
if os.path.exists(actions_path):
|
||||
for f in os.listdir(actions_path):
|
||||
meta['actions'][os.path.splitext(f)[0]] = f
|
||||
|
||||
resource = Resource(name, meta, args, dest_path)
|
||||
resource = Resource(name, meta, args, dest_path, tags=args['tags'])
|
||||
signals.assign_connections(resource, connections)
|
||||
|
||||
# save
|
||||
@ -178,7 +181,6 @@ def assign_resources_to_nodes(resources, nodes, dst_dir):
|
||||
merged = deepcopy(resource)
|
||||
# Node specific setting should override resource's
|
||||
merged.update(deepcopy(node))
|
||||
# Tags for specific resource is set of tags from node and from resource
|
||||
merged['tags'] = list(set(node.get('tags', [])) |
|
||||
set(resource.get('tags', [])))
|
||||
|
||||
@ -187,3 +189,12 @@ def assign_resources_to_nodes(resources, nodes, dst_dir):
|
||||
resource['dir_path'],
|
||||
dst_dir,
|
||||
merged)
|
||||
|
||||
|
||||
def connect_resources(profile):
|
||||
connections = profile.get('connections', [])
|
||||
resources = load_all('/vagrant/tmp/resource-instances/')
|
||||
graph = ResourcesConnectionGraph(connections, resources.values())
|
||||
|
||||
for connection in graph.iter_connections():
|
||||
signals.connect(connection['from'], connection['to'], connection['mapping'])
|
||||
|
@ -40,4 +40,3 @@ def save_to_config_file(key, data):
|
||||
with open(fpath, 'w') as f:
|
||||
encoder = ext_encoder(fpath)
|
||||
encoder.dump(data, f)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user