03b70063376b9431eea30187da0322e3cc4b8686
[snaps.git] / snaps / playbook_runner.py
1 # Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
2 #                    and others.  All rights reserved.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 import argparse
16 import ast
17 import logging
18 import os
19
20 import re
21
22 import yaml
23 from jinja2 import Environment, FileSystemLoader
24
25 from snaps.openstack.os_credentials import ProxySettings
26 from snaps.provisioning import ansible_utils
27
28 __author__ = 'spisarski'
29
30 logger = logging.getLogger('playbook_runner')
31
32
33 def main(parsed_args):
34     """
35     Uses ansible_utils for applying Ansible Playbooks to machines with a
36     private key
37     """
38     logging.basicConfig(level=logging.DEBUG)
39     logger.info('Starting Playbook Runner')
40
41     proxy_settings = None
42     if parsed_args.http_proxy:
43         tokens = re.split(':', parsed_args.http_proxy)
44         proxy_settings = ProxySettings(host=tokens[0], port=tokens[1],
45                                        ssh_proxy_cmd=parsed_args.ssh_proxy_cmd)
46
47     # Ensure can get an SSH client
48     ssh = ansible_utils.ssh_client(
49         parsed_args.ip_addr, parsed_args.host_user,
50         private_key_filepath=parsed_args.priv_key,
51         proxy_settings=proxy_settings)
52     if ssh:
53         ssh.close()
54
55     env = Environment(loader=FileSystemLoader(
56         searchpath=os.path.dirname(parsed_args.env_file)))
57     template = env.get_template(os.path.basename(parsed_args.env_file))
58
59     env_dict = dict()
60     if parsed_args.vars:
61         env_dict = ast.literal_eval(parsed_args.vars)
62
63     output = template.render(**env_dict)
64
65     variables = yaml.load(output)
66
67     if not variables.get('env_file'):
68         variables['env_file'] = parsed_args.env_file
69
70     retval = ansible_utils.apply_playbook(
71         parsed_args.playbook, [parsed_args.ip_addr], parsed_args.host_user,
72         ssh_priv_key_file_path=parsed_args.priv_key,
73         password=parsed_args.password, variables=variables,
74         proxy_setting=proxy_settings)
75     exit(retval)
76
77
78 if __name__ == '__main__':
79     parser = argparse.ArgumentParser()
80     parser.add_argument('-a', '--ip-addr', dest='ip_addr', required=True,
81                         help='The Host IP Address')
82     parser.add_argument('-u', '--host-user', dest='host_user', required=True,
83                         help='Host user account')
84     parser.add_argument('-k', '--priv-key', dest='priv_key', required=False,
85                         help='The location of the private key file')
86     parser.add_argument('-pw', '--password', dest='password', required=False,
87                         help='The host-user password')
88     parser.add_argument('-b', '--playbook', dest='playbook', required=True,
89                         help='Playbook Location')
90     parser.add_argument('-p', '--http-proxy', dest='http_proxy',
91                         required=False, help='<host>:<port>')
92     parser.add_argument('-s', '--ssh-proxy-cmd', dest='ssh_proxy_cmd',
93                         required=False)
94     parser.add_argument('-e', '--env-file', dest='env_file',
95                         help='Yaml file containing playbook substitution vals',
96                         required=False)
97     parser.add_argument('-v', '--vars', dest='vars',
98                         help='String renditon of a dict to pass into '
99                              'playbook for additional subtitution values not '
100                              'found in env_file',
101                         required=False)
102     args = parser.parse_args()
103
104     main(args)