diff --git a/README.md b/README.md index 15176b25..4cbddf53 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ -Usage: +## 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'}) @@ -48,3 +50,31 @@ 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"], "host": "", "ssh_user": "", "ssh_key": ""}' + +python cli.py resource create mariadb_nova_data x/resources/data_container/ rs/ '{"image" : "mariadb", "export_volumes" : ["/var/lib/mysql"], "host": "", "ssh_user": "", "ssh_key": ""}' + +# View resources +python cli.py resource show rs/mariadb_keystone_data + +# Connect resources +python cli.py connect rs/mariadb_keystone_data rs/node2 --mapping '{"host" : "node2.ip", "ssh_key":"node2.ssh_key", "ssh_user":"node2.ssh_user"}' + +python cli.py connect rs/mariadb_nova_data rs/node1 --mapping '{"host" : "node1.ip", "ssh_key":"node1.ssh_key", "ssh_user":"node1.ssh_user"}' + +# View connections +python cli.py connections show +python cli.py connections graph +``` diff --git a/cli.py b/cli.py new file mode 100644 index 00000000..ce803853 --- /dev/null +++ b/cli.py @@ -0,0 +1,85 @@ +import click +import json +import networkx as nx + +from x import resource as xr +from x import signals as xs + + +@click.group() +def cli(): + pass + + +def init_cli_resource(): + @click.group() + def resource(): + pass + + cli.add_command(resource) + + @click.command() + @click.argument('name') + @click.argument('base_path') + @click.argument('dest_path') + @click.argument('args') + def create(args, dest_path, base_path, name): + print 'create', name, base_path, dest_path, args + args = json.loads(args) + xr.create(name, base_path, dest_path, args) + + resource.add_command(create) + + @click.command() + @click.argument('path') + def show(path): + print xr.load(path) + + resource.add_command(show) + + +def init_cli_connect(): + @click.command() + @click.argument('emitter') + @click.argument('receiver') + @click.option('--mapping', default=None) + def connect(mapping, receiver, emitter): + print 'Connect', emitter, receiver + emitter = xr.load(emitter) + receiver = xr.load(receiver) + print emitter + print receiver + if mapping is not None: + mapping = json.loads(mapping) + xs.connect(emitter, receiver, mapping=mapping) + + cli.add_command(connect) + + +def init_cli_connections(): + @click.group() + def connections(): + pass + + cli.add_command(connections) + + @click.command() + def show(): + print json.dumps(xs.CLIENTS, indent=2) + + connections.add_command(show) + + # TODO: this requires graphing libraries + #@click.command() + #def graph(): + # nx.draw_graphviz(xs.connection_graph()) + + #connections.add_command(graph) + + +if __name__ == '__main__': + init_cli_resource() + init_cli_connect() + init_cli_connections() + + cli() diff --git a/requirements.txt b/requirements.txt index 0330efe9..ca7d2def 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ click==4.0 +jinja2==2.7.3 networkx==1.9.1 +PyYAML==3.11 diff --git a/x/resource.py b/x/resource.py index 391804f2..a58d7712 100644 --- a/x/resource.py +++ b/x/resource.py @@ -1,4 +1,5 @@ # -*- coding: UTF-8 -*- +import json import os import shutil @@ -24,8 +25,8 @@ class Resource(object): def __repr__(self): return "Resource('name={0}', metadata={1}, args={2}, base_dir='{3}')".format(self.name, - self.metadata, - self.args, + json.dumps(self.metadata), + json.dumps(self.args), self.base_dir) def update(self, args): diff --git a/x/signals.py b/x/signals.py index a9542fd4..85d1bb26 100644 --- a/x/signals.py +++ b/x/signals.py @@ -12,7 +12,7 @@ CLIENTS_CONFIG_KEY = 'clients-data-file' CLIENTS = utils.read_config_file(CLIENTS_CONFIG_KEY) -def guess_mappings(emitter, receiver): +def guess_mapping(emitter, receiver): """Guess connection mapping between emitter and receiver. Suppose emitter and receiver have inputs: @@ -49,11 +49,11 @@ def guess_mappings(emitter, receiver): return ret -def connect(emitter, receiver, mappings=None): - if mappings is None: - mappings = guess_mappings(emitter, receiver) +def connect(emitter, receiver, mapping=None): + if mapping is None: + mapping = guess_mapping(emitter, receiver) - for src, dst in mappings: + for src, dst in mapping.items(): CLIENTS.setdefault(emitter.name, {}) CLIENTS[emitter.name].setdefault(src, []) CLIENTS[emitter.name][src].append((receiver.name, dst))