diff --git a/examples/resources/docker.yml b/examples/resources/docker.yml new file mode 100644 index 00000000..3b704056 --- /dev/null +++ b/examples/resources/docker.yml @@ -0,0 +1,10 @@ +id: docker +type: resource +handler: ansible +version: v1 +actions: + run: simple/docker/run.yml + remove: simple/docker/remove.yml +input: + base_image: ubuntu +tags: [n/1] diff --git a/examples/simple/docker/remove.yml b/examples/resources/simple/docker/remove.yml similarity index 100% rename from examples/simple/docker/remove.yml rename to examples/resources/simple/docker/remove.yml diff --git a/examples/simple/docker/run.yml b/examples/resources/simple/docker/run.yml similarity index 100% rename from examples/simple/docker/run.yml rename to examples/resources/simple/docker/run.yml diff --git a/examples/simple/group_vars/all b/examples/resources/simple/group_vars/all similarity index 100% rename from examples/simple/group_vars/all rename to examples/resources/simple/group_vars/all diff --git a/examples/simple/host_vars/first b/examples/resources/simple/host_vars/first similarity index 100% rename from examples/simple/host_vars/first rename to examples/resources/simple/host_vars/first diff --git a/examples/simple/hosts b/examples/resources/simple/hosts similarity index 100% rename from examples/simple/hosts rename to examples/resources/simple/hosts diff --git a/examples/simple/mariadb/remove.yml b/examples/resources/simple/mariadb/remove.yml similarity index 100% rename from examples/simple/mariadb/remove.yml rename to examples/resources/simple/mariadb/remove.yml diff --git a/examples/simple/mariadb/run.yml b/examples/resources/simple/mariadb/run.yml similarity index 100% rename from examples/simple/mariadb/run.yml rename to examples/resources/simple/mariadb/run.yml diff --git a/examples/simple/rabbitmq/remove.yml b/examples/resources/simple/rabbitmq/remove.yml similarity index 100% rename from examples/simple/rabbitmq/remove.yml rename to examples/resources/simple/rabbitmq/remove.yml diff --git a/examples/simple/rabbitmq/run.yml b/examples/resources/simple/rabbitmq/run.yml similarity index 100% rename from examples/simple/rabbitmq/run.yml rename to examples/resources/simple/rabbitmq/run.yml diff --git a/examples/simple/remove.yml b/examples/resources/simple/remove.yml similarity index 100% rename from examples/simple/remove.yml rename to examples/resources/simple/remove.yml diff --git a/examples/simple/run.yml b/examples/resources/simple/run.yml similarity index 100% rename from examples/simple/run.yml rename to examples/resources/simple/run.yml diff --git a/examples/simple/user/remove.yml b/examples/resources/simple/user/remove.yml similarity index 100% rename from examples/simple/user/remove.yml rename to examples/resources/simple/user/remove.yml diff --git a/examples/simple/user/run.yml b/examples/resources/simple/user/run.yml similarity index 100% rename from examples/simple/user/run.yml rename to examples/resources/simple/user/run.yml diff --git a/schema/resources/docker_compose.yml b/schema/resources/docker_compose.yml deleted file mode 100644 index 044bb6c6..00000000 --- a/schema/resources/docker_compose.yml +++ /dev/null @@ -1,23 +0,0 @@ ---- - - -id: docker_compose -type: resource -handler: ansible -version: v1 -actions: - run: - - hosts: [docker_compose] - sudo: yes - tasks: - - shell: docker-compose --version - register: compose - ignore_errors: true - - shell: curl -L https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose - when: compose|failed - - shell: chmod +x /usr/local/bin/docker-compose - remove: - - hosts: [docker_compose] - sudo: yes - tasks: - - shell: rm -rf /usr/local/bin/docker-compose diff --git a/schema/resources/node.yml b/schema/resources/node.yml deleted file mode 100644 index cb17948c..00000000 --- a/schema/resources/node.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- - -id: node -type: resource -handler: ansible -version: v1 -input: - ssh_host: 127.0.0.1 - ssh_port: 2222 - connection_type: local - name: first diff --git a/solar/solar/cli.py b/solar/solar/cli.py index 91680785..31a0cb16 100644 --- a/solar/solar/cli.py +++ b/solar/solar/cli.py @@ -46,103 +46,34 @@ class Cmd(object): self.register_actions() self.db = get_db() + def parse(self, args): + parsed = self.parser.parse_args(args) + return parsed.func(parsed) + def register_actions(self): - parser = self.subparser.add_parser('create') - parser.set_defaults(func=getattr(self, 'create')) - parser.add_argument( - '-r', - '--resource', - required=True) - parser.add_argument( - '-t', '--tags', nargs='+', - help='Identifier or resource') - - parser = self.subparser.add_parser('prepare') - parser.set_defaults(func=getattr(self, 'prepare')) - parser.add_argument( - '-a', - '--action', - required=True) - parser.add_argument( - '-r', - '--resources', - nargs='+', - required=True) - - parser = self.subparser.add_parser('exec') - parser.set_defaults(func=getattr(self, 'execute')) - parser.add_argument( - '-a', - '--action', - required=True) - parser.add_argument( - '-r', - '--resources', - nargs='+', - required=True) - - parser = self.subparser.add_parser('show') - parser.set_defaults(func=getattr(self, 'show')) - parser.add_argument( - '-r', - '--resource', - required=True) parser = self.subparser.add_parser('discover') parser.set_defaults(func=getattr(self, 'discover')) - parser = self.subparser.add_parser('clear') - parser.set_defaults(func=getattr(self, 'clear')) - # Perform configuration parser = self.subparser.add_parser('configure') parser.set_defaults(func=getattr(self, 'configure')) parser.add_argument( '-p', '--profile') + parser.add_argument( + '-a', + '--actions', + nargs='+', + required=True) def configure(self, args): - extensions.find_by_provider_from_profile(args.profile, 'configure').configure() + extensions.find_by_provider_from_profile( + args.profile, 'configure').configure(actions=args.actions) def discover(self, args): Discovery({'id': 'discovery'}).execute() - def parse(self, args): - parsed = self.parser.parse_args(args) - return parsed.func(parsed) - - def create(self, args): - self.db.create_resource(args.resource, args.tags) - - def clear(self, args): - self.db.clear() - - def show(self, args): - print self.db[args.resource] - - def prepare(self, args): - - orch = ansible.AnsibleOrchestration( - [yaml.load(self.db[r]) for r in args.resources]) - - utils.create_dir('tmp/group_vars') - with open('tmp/hosts', 'w') as f: - f.write(orch.inventory) - - with open('tmp/group_vars/all', 'w') as f: - f.write(yaml.dump(orch.vars, default_flow_style=False)) - - with open('tmp/main.yml', 'w') as f: - f.write( - yaml.dump(getattr(orch, args.action)(), - default_flow_style=False)) - - def execute(self, args): - self.prepare(args) - sub = subprocess.Popen( - ['ansible-playbook', '-i', 'tmp/hosts', 'tmp/main.yml']) - out, err = sub.communicate() - print out def main(): diff --git a/solar/solar/extensions/modules/ansible.py b/solar/solar/extensions/modules/ansible.py index 847c48ab..88038714 100644 --- a/solar/solar/extensions/modules/ansible.py +++ b/solar/solar/extensions/modules/ansible.py @@ -1,3 +1,5 @@ +import os + import subprocess import yaml @@ -21,6 +23,12 @@ ANSIBLE_INVENTORY = """ """ +def playbook(resource_path, playbook_name): + resource_dir = os.path.dirname(resource_path) + return {'include': '{0}'.format( + os.path.join(resource_dir, playbook_name))} + + class AnsibleOrchestration(base.BaseExtension): ID = 'ansible' @@ -102,22 +110,23 @@ class AnsibleOrchestration(base.BaseExtension): return result - def execute_from_profile(self, profile_action): + def prepare_from_profile(self, profile_action): if profile_action not in self.profile: raise Exception('Action %s not supported', profile_action) paths = self.profile[profile_action] return self.execute_many(paths) - def execute_many(self, paths): + def prepare_many(self, paths): ansible_actions = [] for path in paths: - ansible_actions.extend(self.execute_one(path)) + ansible_actions.extend(self.prepare_one(path)) + return ansible_actions - def execute_one(self, path): + def prepare_one(self, path): """ :param path: docker.actions.run or openstack.action """ @@ -133,14 +142,30 @@ class AnsibleOrchestration(base.BaseExtension): action = resource for step in steps[1:]: action = action[step] - return action - def configure(self): + result = [] + if isinstance(action, list): + for item in action: + result.append(playbook(resource['parent_path'], item)) + else: + result.append(playbook(resource['parent_path'], action)) + + return result + + def configure(self, profile_action='run', actions=None): utils.create_dir('tmp/group_vars') utils.write_to_file(self.inventory, 'tmp/hosts') utils.yaml_dump_to(self.vars, 'tmp/group_vars/all') - utils.yaml_dump_to( - self.execute_from_profile('run'), 'tmp/main.yml') + + if actions: + prepared = self.prepare_many(actions) + elif profile_action: + prepared = self.prepare_from_profile(profile_action) + else: + raise Exception('Either profile_action ' + 'or actions should be provided.') + + utils.yaml_dump_to(prepared, 'tmp/main.yml') sub = subprocess.Popen( ['ansible-playbook', '-i', 'tmp/hosts', 'tmp/main.yml']) diff --git a/solar/solar/extensions/modules/resources.py b/solar/solar/extensions/modules/resources.py index b9ed1e2b..17e56c5a 100644 --- a/solar/solar/extensions/modules/resources.py +++ b/solar/solar/extensions/modules/resources.py @@ -15,7 +15,12 @@ class Resources(base.BaseExtension): FILE_MASK = os.path.join( # TODO(pkaminski): no way we need '..' here... os.path.dirname(__file__), '..', '..', '..', '..', - 'schema', 'resources', '*.yml') + 'examples', 'resources', '*.yml') def resources(self): - return utils.load_by_mask(self.FILE_MASK) + resources = [] + for file_path in utils.find_by_mask(self.FILE_MASK): + res = utils.yaml_load(file_path) + res['parent_path'] = file_path + resources.append(res) + return resources diff --git a/solar/solar/utils.py b/solar/solar/utils.py index 35f8e804..0b38e266 100644 --- a/solar/solar/utils.py +++ b/solar/solar/utils.py @@ -33,9 +33,14 @@ def yaml_dump_to(data, file_path): write_to_file(yaml_dump(data), file_path) +def find_by_mask(mask): + for file_path in glob.glob(mask): + yield os.path.abspath(file_path) + + def load_by_mask(mask): result = [] - for file_path in glob.glob(mask): + for file_path in find_by_mask(mask): result.append(yaml_load(file_path)) return result