Merge pull request #62 from xarses/fix-resources-assignment-rebased
Fix resources assignment
This commit is contained in:
commit
394a24a821
@ -1,4 +1,4 @@
|
|||||||
clients-data-file: /vagrant/clients.json
|
clients-data-file: /vagrant/tmp/connections.yaml
|
||||||
|
|
||||||
tmp: /vagrant/tmp
|
tmp: /vagrant/tmp
|
||||||
|
|
||||||
@ -7,9 +7,8 @@ examples-dir: /vagrant/examples
|
|||||||
extensions-dir: /vagrant/solar/solar/extensions
|
extensions-dir: /vagrant/solar/solar/extensions
|
||||||
|
|
||||||
file-system-db:
|
file-system-db:
|
||||||
resources-path: ./schema/resources
|
|
||||||
storage-path: /vagrant/tmp/storage
|
storage-path: /vagrant/tmp/storage
|
||||||
|
|
||||||
template-dir: /vagrant/templates
|
template-dir: /vagrant/templates
|
||||||
resources-files-mask: /vagrant/x/resources/*/*.yaml
|
resources-files-mask: /vagrant/resources/*/*.yaml
|
||||||
resource-instances-path: /vagrant/tmp/resource-instances
|
node_resource_template: /vagrant/resources/ro_node/
|
||||||
|
28
example.py
28
example.py
@ -6,6 +6,10 @@ import time
|
|||||||
from solar.core import resource
|
from solar.core import resource
|
||||||
from solar.core import signals
|
from solar.core import signals
|
||||||
|
|
||||||
|
from solar.interfaces.db import get_db
|
||||||
|
|
||||||
|
db = get_db()
|
||||||
|
db.clear()
|
||||||
|
|
||||||
signals.Connections.clear()
|
signals.Connections.clear()
|
||||||
|
|
||||||
@ -13,23 +17,23 @@ if os.path.exists('rs'):
|
|||||||
shutil.rmtree('rs')
|
shutil.rmtree('rs')
|
||||||
os.mkdir('rs')
|
os.mkdir('rs')
|
||||||
|
|
||||||
node1 = resource.create('node1', 'resources/ro_node/', 'rs/', {'ip':'10.0.0.3', 'ssh_key' : '/vagrant/.vagrant/machines/solar-dev2/virtualbox/private_key', 'ssh_user':'vagrant'})
|
node1 = resource.create('node1', 'resources/ro_node/', {'ip':'10.0.0.3', 'ssh_key' : '/vagrant/.vagrant/machines/solar-dev2/virtualbox/private_key', 'ssh_user':'vagrant'})
|
||||||
node2 = resource.create('node2', 'resources/ro_node/', 'rs/', {'ip':'10.0.0.4', 'ssh_key' : '/vagrant/.vagrant/machines/solar-dev3/virtualbox/private_key', 'ssh_user':'vagrant'})
|
node2 = resource.create('node2', 'resources/ro_node/', {'ip':'10.0.0.4', 'ssh_key' : '/vagrant/.vagrant/machines/solar-dev3/virtualbox/private_key', 'ssh_user':'vagrant'})
|
||||||
|
|
||||||
mariadb_service1 = resource.create('mariadb_service1', 'resources/mariadb_service', 'rs/', {'image':'mariadb', 'root_password' : 'mariadb', 'port' : '3306', 'ip': '', 'ssh_user': '', 'ssh_key': ''})
|
mariadb_service1 = resource.create('mariadb_service1', 'resources/mariadb_service', {'image':'mariadb', 'root_password' : 'mariadb', 'port' : '3306', 'ip': '', 'ssh_user': '', 'ssh_key': ''})
|
||||||
keystone_db = resource.create('keystone_db', 'resources/mariadb_db/', 'rs/', {'db_name':'keystone_db', 'login_password':'', 'login_user':'root', 'login_port': '', 'ip':'', 'ssh_user':'', 'ssh_key':''})
|
keystone_db = resource.create('keystone_db', 'resources/mariadb_db/', {'db_name':'keystone_db', 'login_password':'', 'login_user':'root', 'login_port': '', 'ip':'', 'ssh_user':'', 'ssh_key':''})
|
||||||
keystone_db_user = resource.create('keystone_db_user', 'resources/mariadb_user/', 'rs/', {'new_user_name' : 'keystone', 'new_user_password' : 'keystone', 'db_name':'', 'login_password':'', 'login_user':'root', 'login_port': '', 'ip':'', 'ssh_user':'', 'ssh_key':''})
|
keystone_db_user = resource.create('keystone_db_user', 'resources/mariadb_user/', {'new_user_name' : 'keystone', 'new_user_password' : 'keystone', 'db_name':'', 'login_password':'', 'login_user':'root', 'login_port': '', 'ip':'', 'ssh_user':'', 'ssh_key':''})
|
||||||
|
|
||||||
keystone_config1 = resource.create('keystone_config1', 'resources/keystone_config/', 'rs/', {'config_dir' : '/etc/solar/keystone', 'ip':'', 'ssh_user':'', 'ssh_key':'', 'admin_token':'admin', 'db_password':'', 'db_name':'', 'db_user':'', 'db_host':''})
|
keystone_config1 = resource.create('keystone_config1', 'resources/keystone_config/', {'config_dir' : '/etc/solar/keystone', 'ip':'', 'ssh_user':'', 'ssh_key':'', 'admin_token':'admin', 'db_password':'', 'db_name':'', 'db_user':'', 'db_host':''})
|
||||||
keystone_service1 = resource.create('keystone_service1', 'resources/keystone_service/', 'rs/', {'port':'5001', 'admin_port':'35357', 'image': '', 'ip':'', 'ssh_key':'', 'ssh_user':'', 'config_dir':''})
|
keystone_service1 = resource.create('keystone_service1', 'resources/keystone_service/', {'port':'5001', 'admin_port':'35357', 'image': '', 'ip':'', 'ssh_key':'', 'ssh_user':'', 'config_dir':''})
|
||||||
|
|
||||||
keystone_config2 = resource.create('keystone_config2', 'resources/keystone_config/', 'rs/', {'config_dir' : '/etc/solar/keystone', 'ip':'', 'ssh_user':'', 'ssh_key':'', 'admin_token':'admin', 'db_password':'', 'db_name':'', 'db_user':'', 'db_host':''})
|
keystone_config2 = resource.create('keystone_config2', 'resources/keystone_config/', {'config_dir' : '/etc/solar/keystone', 'ip':'', 'ssh_user':'', 'ssh_key':'', 'admin_token':'admin', 'db_password':'', 'db_name':'', 'db_user':'', 'db_host':''})
|
||||||
keystone_service2 = resource.create('keystone_service2', 'resources/keystone_service/', 'rs/', {'port':'5002', 'admin_port':'35357', 'image': '', 'ip':'', 'ssh_key':'', 'ssh_user':'', 'config_dir':''})
|
keystone_service2 = resource.create('keystone_service2', 'resources/keystone_service/', {'port':'5002', 'admin_port':'35357', 'image': '', 'ip':'', 'ssh_key':'', 'ssh_user':'', 'config_dir':''})
|
||||||
|
|
||||||
|
|
||||||
haproxy_keystone_config = resource.create('haproxy_keystone1_config', 'resources/haproxy_keystone_config/', 'rs/', {'name':'keystone_config', 'listen_port':'5000', 'servers':[], 'ports':[]})
|
haproxy_keystone_config = resource.create('haproxy_keystone1_config', 'resources/haproxy_keystone_config/', {'name':'keystone_config', 'listen_port':'5000', 'servers':[], 'ports':[]})
|
||||||
haproxy_config = resource.create('haproxy_config', 'resources/haproxy', 'rs/', {'ip':'', 'ssh_key':'', 'ssh_user':'', 'configs_names':[], 'configs_ports':[], 'listen_ports':[], 'configs':[], 'config_dir': ''})
|
haproxy_config = resource.create('haproxy_config', 'resources/haproxy', {'ip':'', 'ssh_key':'', 'ssh_user':'', 'configs_names':[], 'configs_ports':[], 'listen_ports':[], 'configs':[], 'config_dir': ''})
|
||||||
haproxy_service = resource.create('haproxy_service', 'resources/docker_container/', 'rs/', {'image' : 'tutum/haproxy', 'ports': [], 'host_binds': [], 'volume_binds':[], 'ip':'', 'ssh_key':'', 'ssh_user':''})
|
haproxy_service = resource.create('haproxy_service', 'resources/docker_container/', {'image' : 'tutum/haproxy', 'ports': [], 'host_binds': [], 'volume_binds':[], 'ip':'', 'ssh_key':'', 'ssh_user':''})
|
||||||
|
|
||||||
|
|
||||||
####
|
####
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
- id: node_1
|
- id: node_1
|
||||||
ip: 10.0.0.2
|
ip: 10.0.0.2
|
||||||
ssh_user: vagrant
|
ssh_user: vagrant
|
||||||
ssh_private_key_path: /vagrant/tmp/keys/ssh_private
|
ssh_key: /vagrant/tmp/keys/ssh_private
|
||||||
|
|
||||||
- id: node_2
|
- id: node_2
|
||||||
ip: 10.0.0.3
|
ip: 10.0.0.3
|
||||||
ssh_user: vagrant
|
ssh_user: vagrant
|
||||||
ssh_private_key_path: /vagrant/tmp/keys/ssh_private
|
ssh_key: /vagrant/tmp/keys/ssh_private
|
||||||
|
@ -1 +1 @@
|
|||||||
clients-data-file: /tmp/clients.json
|
clients-data-file: /tmp/connections.yaml
|
||||||
|
@ -4,3 +4,4 @@ networkx==1.9.1
|
|||||||
PyYAML==3.11
|
PyYAML==3.11
|
||||||
jsonschema==2.4.0
|
jsonschema==2.4.0
|
||||||
requests==2.7.0
|
requests==2.7.0
|
||||||
|
mock
|
||||||
|
@ -4,6 +4,7 @@ set -e
|
|||||||
|
|
||||||
|
|
||||||
VENV=x-venv
|
VENV=x-venv
|
||||||
|
WORKSPACE=${WORKSPACE:-"/vagrant"}
|
||||||
CONFIG_FILE=$WORKSPACE/jenkins-config.yaml
|
CONFIG_FILE=$WORKSPACE/jenkins-config.yaml
|
||||||
|
|
||||||
# Setup a proper path, I call my virtualenv dir "$VENV" and
|
# Setup a proper path, I call my virtualenv dir "$VENV" and
|
||||||
|
@ -107,12 +107,7 @@ class Cmd(object):
|
|||||||
lambda r: Expression(args.resources, r.get('tags', [])).evaluate(),
|
lambda r: Expression(args.resources, r.get('tags', [])).evaluate(),
|
||||||
self._get_resources_list())
|
self._get_resources_list())
|
||||||
|
|
||||||
resource_instances_path = utils.read_config()['resource-instances-path']
|
assign_resources_to_nodes(resources, nodes)
|
||||||
utils.create_dir(resource_instances_path)
|
|
||||||
assign_resources_to_nodes(
|
|
||||||
resources,
|
|
||||||
nodes,
|
|
||||||
resource_instances_path)
|
|
||||||
|
|
||||||
def _get_resources_list(self):
|
def _get_resources_list(self):
|
||||||
result = []
|
result = []
|
||||||
@ -128,3 +123,7 @@ class Cmd(object):
|
|||||||
def main():
|
def main():
|
||||||
api = Cmd()
|
api = Cmd()
|
||||||
api.parse(sys.argv[1:])
|
api.parse(sys.argv[1:])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
|
||||||
|
|
||||||
RESOURCE_DB = {}
|
|
||||||
|
|
||||||
|
|
||||||
def resource_add(key, value):
|
|
||||||
if key in RESOURCE_DB:
|
|
||||||
raise Exception('Key `{0}` already exists'.format(key))
|
|
||||||
RESOURCE_DB[key] = value
|
|
||||||
|
|
||||||
|
|
||||||
def get_resource(key):
|
|
||||||
return RESOURCE_DB.get(key, None)
|
|
||||||
|
|
||||||
|
|
||||||
def clear():
|
|
||||||
global RESOURCE_DB
|
|
||||||
|
|
||||||
RESOURCE_DB = {}
|
|
@ -1,4 +1,4 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
@ -25,7 +25,7 @@ class BaseHandler(object):
|
|||||||
|
|
||||||
def _compile_action_file(self, resource, action):
|
def _compile_action_file(self, resource, action):
|
||||||
action_file = resource.metadata['actions'][action]
|
action_file = resource.metadata['actions'][action]
|
||||||
action_file = os.path.join(resource.base_dir, 'actions', action_file)
|
action_file = os.path.join(resource.metadata['actions_path'], action_file)
|
||||||
dir_path = self.dirs[resource.name]
|
dir_path = self.dirs[resource.name]
|
||||||
dest_file = tempfile.mkstemp(text=True, prefix=action, dir=dir_path)[1]
|
dest_file = tempfile.mkstemp(text=True, prefix=action, dir=dir_path)[1]
|
||||||
args = self._make_args(resource)
|
args = self._make_args(resource)
|
||||||
@ -43,7 +43,7 @@ class BaseHandler(object):
|
|||||||
|
|
||||||
def _make_args(self, resource):
|
def _make_args(self, resource):
|
||||||
args = {'name': resource.name}
|
args = {'name': resource.name}
|
||||||
args['resource_dir'] = resource.base_dir
|
args['resource_dir'] = resource.metadata['actions_path']
|
||||||
args.update(resource.args)
|
args.update(resource.args)
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
@ -8,23 +8,27 @@ from copy import deepcopy
|
|||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
import solar
|
||||||
|
|
||||||
from solar.core import actions
|
from solar.core import actions
|
||||||
from solar.core import db
|
|
||||||
from solar.core import observer
|
from solar.core import observer
|
||||||
from solar.core import signals
|
from solar.core import signals
|
||||||
from solar import utils
|
from solar import utils
|
||||||
from solar.core import validation
|
from solar.core import validation
|
||||||
|
|
||||||
from solar.core.connections import ResourcesConnectionGraph
|
from solar.core.connections import ResourcesConnectionGraph
|
||||||
|
from solar.interfaces.db import get_db
|
||||||
|
|
||||||
|
db = get_db()
|
||||||
|
|
||||||
|
|
||||||
class Resource(object):
|
class Resource(object):
|
||||||
def __init__(self, name, metadata, args, base_dir, tags=None):
|
def __init__(self, name, metadata, args, tags=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.base_dir = base_dir
|
|
||||||
self.metadata = metadata
|
self.metadata = metadata
|
||||||
self.actions = metadata['actions'].keys() if metadata['actions'] else None
|
self.actions = metadata['actions'].keys() if metadata['actions'] else None
|
||||||
self.args = {}
|
self.args = {}
|
||||||
|
|
||||||
for arg_name, arg_value in args.items():
|
for arg_name, arg_value in args.items():
|
||||||
if not self.metadata['input'].get(arg_name):
|
if not self.metadata['input'].get(arg_name):
|
||||||
continue
|
continue
|
||||||
@ -42,11 +46,10 @@ class Resource(object):
|
|||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return ("Resource(name='{0}', metadata={1}, args={2}, "
|
return ("Resource(name='{0}', metadata={1}, args={2}, "
|
||||||
"base_dir='{3}', tags={4})").format(self.name,
|
"tags={3})").format(self.name,
|
||||||
json.dumps(self.metadata),
|
json.dumps(self.metadata),
|
||||||
json.dumps(self.args_show()),
|
json.dumps(self.args_show()),
|
||||||
self.base_dir,
|
self.tags)
|
||||||
self.tags)
|
|
||||||
|
|
||||||
def args_show(self):
|
def args_show(self):
|
||||||
def formatter(v):
|
def formatter(v):
|
||||||
@ -111,20 +114,13 @@ class Resource(object):
|
|||||||
for k, v in self.args_dict().items():
|
for k, v in self.args_dict().items():
|
||||||
metadata['input'][k]['value'] = v
|
metadata['input'][k]['value'] = v
|
||||||
|
|
||||||
meta_file = os.path.join(self.base_dir, 'meta.yaml')
|
db.add_resource(self.name, metadata)
|
||||||
with open(meta_file, 'w') as f:
|
|
||||||
f.write(yaml.dump(metadata, default_flow_style=False))
|
|
||||||
|
|
||||||
|
|
||||||
def create(name, base_path, dest_path, args, connections={}):
|
def create(name, base_path, args, tags=[], connections={}):
|
||||||
if not os.path.exists(base_path):
|
if not os.path.exists(base_path):
|
||||||
raise Exception('Base resource does not exist: {0}'.format(base_path))
|
raise Exception('Base resource does not exist: {0}'.format(base_path))
|
||||||
if not os.path.exists(dest_path):
|
|
||||||
raise Exception('Dest dir does not exist: {0}'.format(dest_path))
|
|
||||||
if not os.path.isdir(dest_path):
|
|
||||||
raise Exception('Dest path is not a directory: {0}'.format(dest_path))
|
|
||||||
|
|
||||||
dest_path = os.path.abspath(os.path.join(dest_path, name))
|
|
||||||
base_meta_file = os.path.join(base_path, 'meta.yaml')
|
base_meta_file = os.path.join(base_path, 'meta.yaml')
|
||||||
actions_path = os.path.join(base_path, 'actions')
|
actions_path = os.path.join(base_path, 'actions')
|
||||||
|
|
||||||
@ -132,42 +128,32 @@ def create(name, base_path, dest_path, args, connections={}):
|
|||||||
meta['id'] = name
|
meta['id'] = name
|
||||||
meta['version'] = '1.0.0'
|
meta['version'] = '1.0.0'
|
||||||
meta['actions'] = {}
|
meta['actions'] = {}
|
||||||
|
meta['actions_path'] = actions_path
|
||||||
|
|
||||||
if os.path.exists(actions_path):
|
if os.path.exists(actions_path):
|
||||||
for f in os.listdir(actions_path):
|
for f in os.listdir(actions_path):
|
||||||
meta['actions'][os.path.splitext(f)[0]] = f
|
meta['actions'][os.path.splitext(f)[0]] = f
|
||||||
|
|
||||||
resource = Resource(name, meta, args, dest_path, tags=args.get('tags', []))
|
resource = Resource(name, meta, args, tags=tags)
|
||||||
signals.assign_connections(resource, connections)
|
signals.assign_connections(resource, connections)
|
||||||
|
|
||||||
# save
|
|
||||||
shutil.copytree(base_path, dest_path)
|
|
||||||
resource.save()
|
resource.save()
|
||||||
db.resource_add(name, resource)
|
|
||||||
|
|
||||||
return resource
|
return resource
|
||||||
|
|
||||||
|
|
||||||
def load(dest_path):
|
def wrap_resource(raw_resource):
|
||||||
meta_file = os.path.join(dest_path, 'meta.yaml')
|
name = raw_resource['id']
|
||||||
meta = utils.load_file(meta_file)
|
args = raw_resource['input']
|
||||||
name = meta['id']
|
tags = raw_resource.get('tags', [])
|
||||||
args = meta['input']
|
|
||||||
tags = meta.get('tags', [])
|
|
||||||
|
|
||||||
resource = Resource(name, meta, args, dest_path, tags=tags)
|
return Resource(name, raw_resource, args, tags=tags)
|
||||||
|
|
||||||
db.resource_add(name, resource)
|
|
||||||
|
|
||||||
return resource
|
|
||||||
|
|
||||||
|
|
||||||
def load_all(dest_path):
|
def load_all():
|
||||||
ret = {}
|
ret = {}
|
||||||
|
|
||||||
for name in os.listdir(dest_path):
|
for raw_resource in db.get_list('resource'):
|
||||||
resource_path = os.path.join(dest_path, name)
|
resource = wrap_resource(raw_resource)
|
||||||
resource = load(resource_path)
|
|
||||||
ret[resource.name] = resource
|
ret[resource.name] = resource
|
||||||
|
|
||||||
signals.Connections.reconnect_all()
|
signals.Connections.reconnect_all()
|
||||||
@ -175,26 +161,28 @@ def load_all(dest_path):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def assign_resources_to_nodes(resources, nodes, dst_dir):
|
def assign_resources_to_nodes(resources, nodes):
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
for resource in resources:
|
for resource in resources:
|
||||||
merged = deepcopy(resource)
|
res = deepcopy(resource)
|
||||||
# Node specific setting should override resource's
|
res['tags'] = list(set(node.get('tags', [])) |
|
||||||
merged.update(deepcopy(node))
|
set(resource.get('tags', [])))
|
||||||
merged['tags'] = list(set(node.get('tags', [])) |
|
resource_uuid = solar.utils.generate_uuid()
|
||||||
set(resource.get('tags', [])))
|
# We should not generate here any uuid's, because
|
||||||
|
# a single node should be represented with a single
|
||||||
|
# resource
|
||||||
|
node_uuid = node['id']
|
||||||
|
|
||||||
create(
|
node_resource_template = solar.utils.read_config()['node_resource_template']
|
||||||
format('{0}-{1}'.format(node['id'], resource['id'])),
|
created_resource = create(resource_uuid, resource['dir_path'], res['input'], tags=res['tags'])
|
||||||
resource['dir_path'],
|
created_node = create(node_uuid, node_resource_template, node, tags=node.get('tags', []))
|
||||||
dst_dir,
|
|
||||||
merged)
|
signals.connect(created_node, created_resource)
|
||||||
|
|
||||||
|
|
||||||
def connect_resources(profile):
|
def connect_resources(profile):
|
||||||
connections = profile.get('connections', [])
|
connections = profile.get('connections', [])
|
||||||
resources = load_all('/vagrant/tmp/resource-instances/')
|
graph = ResourcesConnectionGraph(connections, load_all().values())
|
||||||
graph = ResourcesConnectionGraph(connections, resources.values())
|
|
||||||
|
|
||||||
for connection in graph.iter_connections():
|
for connection in graph.iter_connections():
|
||||||
signals.connect(connection['from'], connection['to'], connection['mapping'])
|
signals.connect(connection['from'], connection['to'], connection['mapping'])
|
||||||
|
@ -4,9 +4,11 @@ import itertools
|
|||||||
import networkx as nx
|
import networkx as nx
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import db
|
|
||||||
|
|
||||||
from solar import utils
|
from solar import utils
|
||||||
|
from solar.interfaces.db import get_db
|
||||||
|
|
||||||
|
db = get_db()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CLIENTS_CONFIG_KEY = 'clients-data-file'
|
CLIENTS_CONFIG_KEY = 'clients-data-file'
|
||||||
@ -46,10 +48,10 @@ class Connections(object):
|
|||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
for emitter_name, dest_dict in CLIENTS.items():
|
for emitter_name, dest_dict in CLIENTS.items():
|
||||||
emitter = db.get_resource(emitter_name)
|
emitter = db.get_obj_resource(emitter_name)
|
||||||
for emitter_input, destinations in dest_dict.items():
|
for emitter_input, destinations in dest_dict.items():
|
||||||
for receiver_name, receiver_input in destinations:
|
for receiver_name, receiver_input in destinations:
|
||||||
receiver = db.get_resource(receiver_name)
|
receiver = db.get_obj_resource(receiver_name)
|
||||||
emitter.args[emitter_input].subscribe(
|
emitter.args[emitter_input].subscribe(
|
||||||
receiver.args[receiver_input])
|
receiver.args[receiver_input])
|
||||||
|
|
||||||
@ -107,7 +109,7 @@ def connect(emitter, receiver, mapping=None):
|
|||||||
|
|
||||||
def disconnect(emitter, receiver):
|
def disconnect(emitter, receiver):
|
||||||
for src, destinations in CLIENTS[emitter.name].items():
|
for src, destinations in CLIENTS[emitter.name].items():
|
||||||
disconnect_by_src(emitter, src, receiver)
|
disconnect_by_src(emitter.name, src, receiver)
|
||||||
|
|
||||||
for destination in destinations:
|
for destination in destinations:
|
||||||
receiver_input = destination[1]
|
receiver_input = destination[1]
|
||||||
@ -125,13 +127,13 @@ def disconnect_receiver_by_input(receiver, input):
|
|||||||
"""
|
"""
|
||||||
for emitter_name, inputs in CLIENTS.items():
|
for emitter_name, inputs in CLIENTS.items():
|
||||||
emitter = db.get_resource(emitter_name)
|
emitter = db.get_resource(emitter_name)
|
||||||
disconnect_by_src(emitter, input, receiver)
|
disconnect_by_src(emitter['id'], input, receiver)
|
||||||
|
|
||||||
|
|
||||||
def disconnect_by_src(emitter, src, receiver):
|
def disconnect_by_src(emitter_name, src, receiver):
|
||||||
if src in CLIENTS[emitter.name]:
|
if src in CLIENTS[emitter_name]:
|
||||||
CLIENTS[emitter.name][src] = [
|
CLIENTS[emitter_name][src] = [
|
||||||
destination for destination in CLIENTS[emitter.name][src]
|
destination for destination in CLIENTS[emitter_name][src]
|
||||||
if destination[0] != receiver.name
|
if destination[0] != receiver.name
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -143,7 +145,7 @@ def notify(source, key, value):
|
|||||||
print 'Notify', source.name, key, value, CLIENTS[source.name]
|
print 'Notify', source.name, key, value, CLIENTS[source.name]
|
||||||
if key in CLIENTS[source.name]:
|
if key in CLIENTS[source.name]:
|
||||||
for client, r_key in CLIENTS[source.name][key]:
|
for client, r_key in CLIENTS[source.name][key]:
|
||||||
resource = db.get_resource(client)
|
resource = db.get_obj_resource(client)
|
||||||
print 'Resource found', client
|
print 'Resource found', client
|
||||||
if resource:
|
if resource:
|
||||||
resource.update({r_key: value}, emitter=source)
|
resource.update({r_key: value}, emitter=source)
|
||||||
|
@ -11,39 +11,26 @@ from solar import utils
|
|||||||
from solar import errors
|
from solar import errors
|
||||||
|
|
||||||
|
|
||||||
def get_files(path, pattern):
|
|
||||||
for root, dirs, files in os.walk(path):
|
|
||||||
for file_name in files:
|
|
||||||
if fnmatch(file_name, pattern):
|
|
||||||
yield os.path.join(root, file_name)
|
|
||||||
|
|
||||||
|
|
||||||
class FileSystemDB(DirDBM):
|
class FileSystemDB(DirDBM):
|
||||||
RESOURCES_PATH = utils.read_config()['file-system-db']['resources-path']
|
|
||||||
STORAGE_PATH = utils.read_config()['file-system-db']['storage-path']
|
STORAGE_PATH = utils.read_config()['file-system-db']['storage-path']
|
||||||
|
RESOURCE_COLLECTION_NAME = 'resource'
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
utils.create_dir(self.STORAGE_PATH)
|
utils.create_dir(self.STORAGE_PATH)
|
||||||
super(FileSystemDB, self).__init__(self.STORAGE_PATH)
|
super(FileSystemDB, self).__init__(self.STORAGE_PATH)
|
||||||
self.entities = {}
|
self.entities = {}
|
||||||
|
|
||||||
def create_resource(self, resource, tags):
|
def get_resource(self, uid):
|
||||||
self.from_files(self.RESOURCES_PATH)
|
return self[self._make_key(self.RESOURCE_COLLECTION_NAME, uid)]
|
||||||
|
|
||||||
resource_uid = '{0}_{1}'.format(resource, '_'.join(tags))
|
def get_obj_resource(self, uid):
|
||||||
data = deepcopy(self.get(resource))
|
from solar.core.resource import wrap_resource
|
||||||
data['tags'] = tags
|
raw_resource = self[self._make_key(self.RESOURCE_COLLECTION_NAME, uid)]
|
||||||
self[resource_uid] = data
|
|
||||||
|
|
||||||
def get_copy(self, key):
|
return wrap_resource(raw_resource)
|
||||||
return deepcopy(self[key])
|
|
||||||
|
|
||||||
def add(self, obj):
|
def add_resource(self, uid, resource):
|
||||||
if 'id' in obj:
|
self[self._make_key(self.RESOURCE_COLLECTION_NAME, uid)] = resource
|
||||||
self.entities[obj['id']] = obj
|
|
||||||
|
|
||||||
def store_from_file(self, file_path):
|
|
||||||
self.store(file_path)
|
|
||||||
|
|
||||||
def store(self, collection, obj):
|
def store(self, collection, obj):
|
||||||
if 'id' in obj:
|
if 'id' in obj:
|
||||||
@ -72,20 +59,6 @@ class FileSystemDB(DirDBM):
|
|||||||
def _make_key(self, collection, _id):
|
def _make_key(self, collection, _id):
|
||||||
return '{0}-{1}'.format(collection, _id)
|
return '{0}-{1}'.format(collection, _id)
|
||||||
|
|
||||||
def add_resource(self, resource):
|
|
||||||
if 'id' in resource:
|
|
||||||
self.entities[resource['id']] = resource
|
|
||||||
|
|
||||||
def get(self, resource_id):
|
|
||||||
return self.entities[resource_id]
|
|
||||||
|
|
||||||
def from_files(self, path):
|
|
||||||
for file_path in get_files(path, '*.yml'):
|
|
||||||
with open(file_path) as f:
|
|
||||||
entity = f
|
|
||||||
|
|
||||||
self.add_resource(entity)
|
|
||||||
|
|
||||||
def _readFile(self, path):
|
def _readFile(self, path):
|
||||||
return yaml.load(super(FileSystemDB, self)._readFile(path))
|
return yaml.load(super(FileSystemDB, self)._readFile(path))
|
||||||
|
|
||||||
|
@ -4,9 +4,11 @@ import tempfile
|
|||||||
import unittest
|
import unittest
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from solar.core import db
|
|
||||||
from solar.core import resource as xr
|
from solar.core import resource as xr
|
||||||
from solar.core import signals as xs
|
from solar.core import signals as xs
|
||||||
|
from solar.interfaces.db import get_db
|
||||||
|
|
||||||
|
db = get_db()
|
||||||
|
|
||||||
|
|
||||||
class BaseResourceTest(unittest.TestCase):
|
class BaseResourceTest(unittest.TestCase):
|
||||||
@ -29,8 +31,4 @@ class BaseResourceTest(unittest.TestCase):
|
|||||||
return path
|
return path
|
||||||
|
|
||||||
def create_resource(self, name, src, args):
|
def create_resource(self, name, src, args):
|
||||||
dst = os.path.join(self.storage_dir, 'rs', name)
|
return xr.create(name, src, args)
|
||||||
os.makedirs(dst)
|
|
||||||
|
|
||||||
return xr.create(name, src, dst, args)
|
|
||||||
|
|
||||||
|
118
x-README.md
118
x-README.md
@ -1,118 +0,0 @@
|
|||||||
# x
|
|
||||||
|
|
||||||
## HAProxy deployment
|
|
||||||
|
|
||||||
```
|
|
||||||
cd /vagrant
|
|
||||||
python cli.py deploy haproxy_deployment/haproxy-deployment.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
or from Python shell:
|
|
||||||
|
|
||||||
```
|
|
||||||
from x import deployment
|
|
||||||
|
|
||||||
deployment.deploy('/vagrant/haproxy_deployment/haproxy-deployment.yaml')
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage:
|
|
||||||
|
|
||||||
Creating resources:
|
|
||||||
|
|
||||||
```
|
|
||||||
from x import resource
|
|
||||||
|
|
||||||
node1 = resource.create('node1', 'x/resources/ro_node/', 'rs/', {'ip':'10.0.0.3', 'ssh_key' : '/vagrant/tmp/keys/ssh_private', 'ssh_user':'vagrant'})
|
|
||||||
|
|
||||||
node2 = resource.create('node2', 'x/resources/ro_node/', 'rs/', {'ip':'10.0.0.4', 'ssh_key' : '/vagrant/tmp/keys/ssh_private', 'ssh_user':'vagrant'})
|
|
||||||
|
|
||||||
keystone_db_data = resource.create('mariadb_keystone_data', 'x/resources/data_container/', 'rs/', {'image' : 'mariadb', 'export_volumes' : ['/var/lib/mysql'], 'ip': '', 'ssh_user': '', 'ssh_key': ''}, connections={'ip' : 'node2.ip', 'ssh_key':'node2.ssh_key', 'ssh_user':'node2.ssh_user'})
|
|
||||||
|
|
||||||
nova_db_data = resource.create('mariadb_nova_data', 'x/resources/data_container/', 'rs/', {'image' : 'mariadb', 'export_volumes' : ['/var/lib/mysql'], 'ip': '', 'ssh_user': '', 'ssh_key': ''}, connections={'ip' : 'node1.ip', 'ssh_key':'node1.ssh_key', 'ssh_user':'node1.ssh_user'})
|
|
||||||
```
|
|
||||||
|
|
||||||
to make connection after resource is created use `signal.connect`
|
|
||||||
|
|
||||||
To test notifications:
|
|
||||||
|
|
||||||
```
|
|
||||||
keystone_db_data.args # displays node2 IP
|
|
||||||
|
|
||||||
node2.update({'ip': '10.0.0.5'})
|
|
||||||
|
|
||||||
keystone_db_data.args # updated IP
|
|
||||||
```
|
|
||||||
|
|
||||||
If you close the Python shell you can load the resources like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
from x import resource
|
|
||||||
|
|
||||||
node1 = resource.load('rs/node1')
|
|
||||||
|
|
||||||
node2 = resource.load('rs/node2')
|
|
||||||
|
|
||||||
keystone_db_data = resource.load('rs/mariadn_keystone_data')
|
|
||||||
|
|
||||||
nova_db_data = resource.load('rs/mariadb_nova_data')
|
|
||||||
```
|
|
||||||
|
|
||||||
Connections are loaded automatically.
|
|
||||||
|
|
||||||
|
|
||||||
You can also load all resources at once:
|
|
||||||
|
|
||||||
```
|
|
||||||
from x import resource
|
|
||||||
|
|
||||||
all_resources = resource.load_all('rs')
|
|
||||||
```
|
|
||||||
|
|
||||||
## CLI
|
|
||||||
|
|
||||||
You can do the above from the command-line client:
|
|
||||||
|
|
||||||
```
|
|
||||||
cd /vagrant
|
|
||||||
|
|
||||||
python cli.py resource create node1 x/resources/ro_node/ rs/ '{"ip":"10.0.0.3", "ssh_key" : "/vagrant/tmp/keys/ssh_private", "ssh_user":"vagrant"}'
|
|
||||||
|
|
||||||
python cli.py resource create node2 x/resources/ro_node/ rs/ '{"ip":"10.0.0.4", "ssh_key" : "/vagrant/tmp/keys/ssh_private", "ssh_user":"vagrant"}'
|
|
||||||
|
|
||||||
python cli.py resource create mariadb_keystone_data x/resources/data_container/ rs/ '{"image": "mariadb", "export_volumes" : ["/var/lib/mysql"], "ip": "", "ssh_user": "", "ssh_key": ""}'
|
|
||||||
|
|
||||||
python cli.py resource create mariadb_nova_data x/resources/data_container/ rs/ '{"image" : "mariadb", "export_volumes" : ["/var/lib/mysql"], "ip": "", "ssh_user": "", "ssh_key": ""}'
|
|
||||||
|
|
||||||
# View resources
|
|
||||||
python cli.py resource show rs/mariadb_keystone_data
|
|
||||||
|
|
||||||
# Show all resources at location rs/
|
|
||||||
python cli.py resource show rs/ --all
|
|
||||||
|
|
||||||
# Show resources with specific tag
|
|
||||||
python cli.py resources show rs/ --tag test
|
|
||||||
|
|
||||||
# Connect resources
|
|
||||||
python cli.py connect rs/node2 rs/mariadb_keystone_data
|
|
||||||
|
|
||||||
python cli.py connect rs/node1 rs/mariadb_nova_data
|
|
||||||
|
|
||||||
# Test update
|
|
||||||
python cli.py update rs/node2 '{"ip": "1.1.1.1"}'
|
|
||||||
python cli.py resource show rs/mariadb_keystone_data # --> IP is 1.1.1.1
|
|
||||||
|
|
||||||
# View connections
|
|
||||||
python cli.py connections show
|
|
||||||
|
|
||||||
# Outputs graph to 'graph.png' file, please note that arrows don't have "normal" pointers, but just the line is thicker
|
|
||||||
# please see http://networkx.lanl.gov/_modules/networkx/drawing/nx_pylab.html
|
|
||||||
python cli.py connections graph
|
|
||||||
|
|
||||||
# Disconnect
|
|
||||||
python cli.py disconnect rs/mariadb_nova_data rs/node1
|
|
||||||
|
|
||||||
# Tag a resource:
|
|
||||||
python cli.py resource tag rs/node1 test-tag
|
|
||||||
# Remove tag
|
|
||||||
python cli.py resource tag rs/node1 test-tag --delete
|
|
||||||
```
|
|
Loading…
x
Reference in New Issue
Block a user