DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 1 | import json |
| 2 | import yaml |
DR695H | ae6fedd | 2019-05-01 18:52:33 -0400 | [diff] [blame] | 3 | import io |
DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 4 | import copy |
| 5 | from hashlib import md5 |
| 6 | from paramiko import RSAKey |
| 7 | from paramiko.ssh_exception import PasswordRequiredException |
| 8 | |
DR695H | ae6fedd | 2019-05-01 18:52:33 -0400 | [diff] [blame] | 9 | |
DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 10 | class HEATUtils: |
| 11 | """ Utilities useful for constructing OpenStack HEAT requests """ |
| 12 | |
| 13 | def get_yaml(self, template_file): |
| 14 | """Template Yaml To Json reads a YAML Heat template file returns a JSON string that can be used included in an Openstack Add Stack Request""" |
Yang Xu | 1a18e91 | 2019-05-05 22:59:57 -0400 | [diff] [blame] | 15 | if isinstance(template_file, str) or isinstance(template_file, unicode): |
DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 16 | fin = open(template_file, 'r') |
| 17 | yamlobj = yaml.load(fin) |
| 18 | return yamlobj |
| 19 | return None |
DR695H | ae6fedd | 2019-05-01 18:52:33 -0400 | [diff] [blame] | 20 | |
DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 21 | def template_yaml_to_json(self, template_file): |
| 22 | """Template Yaml To Json reads a YAML Heat template file returns a JSON string that can be used included in an Openstack Add Stack Request""" |
Yang Xu | 1a18e91 | 2019-05-05 22:59:57 -0400 | [diff] [blame] | 23 | contents = None |
| 24 | if isinstance(template_file, str) or isinstance(template_file, unicode): |
DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 25 | fin = open(template_file, 'r') |
| 26 | yamlobj = yaml.load(fin) |
| 27 | fin.close() |
| 28 | if 'heat_template_version' in yamlobj: |
| 29 | datetime = yamlobj['heat_template_version'] |
| 30 | yamlobj['heat_template_version'] = str(datetime) |
DR695H | ae6fedd | 2019-05-01 18:52:33 -0400 | [diff] [blame] | 31 | fout = io.BytesIO() |
DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 32 | json.dump(yamlobj, fout) |
| 33 | contents = fout.getvalue() |
| 34 | fout.close() |
| 35 | return contents |
DR695H | ae6fedd | 2019-05-01 18:52:33 -0400 | [diff] [blame] | 36 | |
DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 37 | def env_yaml_to_json(self, template_file): |
| 38 | """Env Yaml To JSon reads a YAML Heat env file and returns a JSON string that can be used included in an Openstack Add Stack Request""" |
Yang Xu | 1a18e91 | 2019-05-05 22:59:57 -0400 | [diff] [blame] | 39 | if isinstance(template_file, str) or isinstance(template_file, unicode): |
DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 40 | fin = open(template_file, 'r') |
| 41 | yamlobj = yaml.load(fin) |
| 42 | fin.close() |
| 43 | if 'parameters' in yamlobj: |
DR695H | ae6fedd | 2019-05-01 18:52:33 -0400 | [diff] [blame] | 44 | fout = io.BytesIO() |
DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 45 | json.dump(yamlobj['parameters'], fout) |
| 46 | contents = fout.getvalue() |
| 47 | fout.close() |
| 48 | return contents |
| 49 | return None |
DR695H | ae6fedd | 2019-05-01 18:52:33 -0400 | [diff] [blame] | 50 | |
DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 51 | def stack_info_parse(self, stack_info): |
| 52 | """ returns a flattened version of the Openstack Find Stack results """ |
| 53 | d = {} |
| 54 | if isinstance(stack_info, dict): |
| 55 | s = stack_info['stack'] |
| 56 | p = s['parameters'] |
| 57 | d = copy.deepcopy(p) |
| 58 | d['id'] = s['id'] |
| 59 | d['name'] = s['stack_name'] |
| 60 | d['stack_status'] = s['stack_status'] |
DR695H | ae6fedd | 2019-05-01 18:52:33 -0400 | [diff] [blame] | 61 | return d |
| 62 | |
DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 63 | def match_fingerprint(self, pvt_file, pw, fingerprint): |
| 64 | try: |
| 65 | sshKey = RSAKey.from_private_key_file(pvt_file, pw) |
| 66 | keybytes = md5(sshKey.asbytes()).hexdigest() |
DR695H | ae6fedd | 2019-05-01 18:52:33 -0400 | [diff] [blame] | 67 | printableFingerprint = ':'.join(a + b for a, b in zip(keybytes[::2], keybytes[1::2])) |
DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 68 | return printableFingerprint == fingerprint.__str__() |
| 69 | except PasswordRequiredException: |
DR695H | ae6fedd | 2019-05-01 18:52:33 -0400 | [diff] [blame] | 70 | return False |
| 71 | |
DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 72 | def match_private_key_file_to_keypair(self, files, keypair): |
| 73 | for keyfile in files: |
| 74 | if (self.match_fingerprint(keyfile, None, keypair['keypair']['fingerprint'])): |
| 75 | return keyfile |
| 76 | return None |
DR695H | ae6fedd | 2019-05-01 18:52:33 -0400 | [diff] [blame] | 77 | |
DR695H | 5fa0146 | 2017-02-15 18:21:12 -0500 | [diff] [blame] | 78 | def get_openstack_server_ip(self, server, network_name="public", ipversion=4): |
| 79 | ipaddr = None |
| 80 | try: |
| 81 | versions = server['addresses'][network_name] |
| 82 | for version in versions: |
| 83 | if version['version'] == ipversion: |
| 84 | ipaddr = version['addr'] |
| 85 | break; |
| 86 | except ValueError: |
| 87 | return ipaddr |
| 88 | return ipaddr |