1 ##############################################################################
2 # Copyright (c) 2016 Tim Rozet (trozet@redhat.com) and others.
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
19 if isinstance(var, bool):
22 return var.lower() in ("true", "yes")
25 def parse_yaml(yaml_file):
26 with open(yaml_file) as f:
27 parsed_dict = yaml.safe_load(f)
31 def dump_yaml(data, file):
33 Dumps data to a file as yaml
34 :param data: yaml to be written to file
35 :param file: filename to write to
38 logging.debug("Writing file {} with "
39 "yaml data:\n{}".format(file, yaml.safe_dump(data)))
40 with open(file, "w") as fh:
41 yaml.safe_dump(data, fh, default_flow_style=False)
44 def dict_objects_to_str(dictionary):
45 if isinstance(dictionary, list):
47 for element in dictionary:
48 if isinstance(element, dict):
49 tmp_list.append(dict_objects_to_str(element))
51 tmp_list.append(str(element))
53 elif not isinstance(dictionary, dict):
54 if not isinstance(dictionary, bool):
55 return str(dictionary)
58 return dict((k, dict_objects_to_str(v)) for
59 k, v in dictionary.items())
62 def run_ansible(ansible_vars, playbook, host='localhost', user='root',
63 tmp_dir=None, dry_run=False):
65 Executes ansible playbook and checks for errors
66 :param ansible_vars: dictionary of variables to inject into ansible run
67 :param playbook: playbook to execute
68 :param tmp_dir: temp directory to store ansible command
69 :param dry_run: Do not actually apply changes
72 logging.info("Executing ansible playbook: {}".format(playbook))
73 inv_host = "{},".format(host)
74 if host == 'localhost':
78 ansible_command = ['ansible-playbook', '--become', '-i', inv_host,
79 '-u', user, '-c', conn_type, playbook, '-vv']
81 ansible_command.append('--check')
83 if isinstance(ansible_vars, dict) and ansible_vars:
84 logging.debug("Ansible variables to be set:\n{}".format(
85 pprint.pformat(ansible_vars)))
86 ansible_command.append('--extra-vars')
87 ansible_command.append(json.dumps(ansible_vars))
89 ansible_tmp = os.path.join(tmp_dir,
90 os.path.basename(playbook) + '.rerun')
91 # FIXME(trozet): extra vars are printed without single quotes
92 # so a dev has to add them manually to the command to rerun
93 # the playbook. Need to test if we can just add the single quotes
94 # to the json dumps to the ansible command and see if that works
95 with open(ansible_tmp, 'w') as fh:
96 fh.write("ANSIBLE_HOST_KEY_CHECKING=FALSE {}".format(
97 ' '.join(ansible_command)))
99 my_env = os.environ.copy()
100 my_env['ANSIBLE_HOST_KEY_CHECKING'] = 'False'
101 logging.info("Executing playbook...this may take some time")
102 p = subprocess.Popen(ansible_command,
103 stdin=subprocess.PIPE,
104 stdout=subprocess.PIPE,
107 universal_newlines=True)
109 x = p.stdout.readline()
113 # append lines to task
115 # log the line and read another
116 x = p.stdout.readline()
117 # deliver the task to info when we get a blank line
120 logging.info(task.replace('\\n', '\n'))
122 x = p.stdout.readline()
123 # clean up and get return code
128 e = "Ansible playbook failed. See Ansible logs for details."