Merge lp:~hopem/charms/trusty/cinder/fix-ssl-inject into lp:~openstack-charmers-archive/charms/trusty/cinder/next

Proposed by Edward Hope-Morley
Status: Merged
Merged at revision: 79
Proposed branch: lp:~hopem/charms/trusty/cinder/fix-ssl-inject
Merge into: lp:~openstack-charmers-archive/charms/trusty/cinder/next
Diff against target: 253 lines (+161/-3)
5 files modified
charm-helpers-hooks.yaml (+1/-1)
hooks/charmhelpers/contrib/openstack/context.py (+59/-1)
hooks/charmhelpers/contrib/openstack/neutron.py (+70/-0)
hooks/charmhelpers/core/hookenv.py (+26/-0)
hooks/charmhelpers/core/host.py (+5/-1)
To merge this branch: bzr merge lp:~hopem/charms/trusty/cinder/fix-ssl-inject
Reviewer Review Type Date Requested Status
Billy Olsen Approve
Review via email: mp+253406@code.launchpad.net
To post a comment you must log in.
81. By Edward Hope-Morley

cleanup

Revision history for this message
Billy Olsen (billy-olsen) wrote :

deloyments work well with ha and non-ha ssl inject. Approve.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'charm-helpers-hooks.yaml'
2--- charm-helpers-hooks.yaml 2015-01-13 14:36:44 +0000
3+++ charm-helpers-hooks.yaml 2015-03-18 18:35:37 +0000
4@@ -1,4 +1,4 @@
5-branch: lp:charm-helpers
6+branch: lp:charm-helpers
7 destination: hooks/charmhelpers
8 include:
9 - core
10
11=== modified file 'hooks/charmhelpers/contrib/openstack/context.py'
12--- hooks/charmhelpers/contrib/openstack/context.py 2015-03-13 13:00:03 +0000
13+++ hooks/charmhelpers/contrib/openstack/context.py 2015-03-18 18:35:37 +0000
14@@ -16,6 +16,7 @@
15
16 import json
17 import os
18+import re
19 import time
20 from base64 import b64decode
21 from subprocess import check_call
22@@ -48,6 +49,8 @@
23 from charmhelpers.core.sysctl import create as sysctl_create
24
25 from charmhelpers.core.host import (
26+ list_nics,
27+ get_nic_hwaddr,
28 mkdir,
29 write_file,
30 )
31@@ -65,12 +68,18 @@
32 from charmhelpers.contrib.openstack.neutron import (
33 neutron_plugin_attribute,
34 )
35+from charmhelpers.contrib.openstack.ip import (
36+ resolve_address,
37+ INTERNAL,
38+)
39 from charmhelpers.contrib.network.ip import (
40 get_address_in_network,
41+ get_ipv4_addr,
42 get_ipv6_addr,
43 get_netmask_for_address,
44 format_ipv6_addr,
45 is_address_in_network,
46+ is_bridge_member,
47 )
48 from charmhelpers.contrib.openstack.utils import get_host_ip
49
50@@ -727,7 +736,14 @@
51 'endpoints': [],
52 'ext_ports': []}
53
54- for cn in self.canonical_names():
55+ cns = self.canonical_names()
56+ if cns:
57+ for cn in cns:
58+ self.configure_cert(cn)
59+ else:
60+ # Expect cert/key provided in config (currently assumed that ca
61+ # uses ip for cn)
62+ cn = resolve_address(endpoint_type=INTERNAL)
63 self.configure_cert(cn)
64
65 addresses = self.get_network_addresses()
66@@ -883,6 +899,48 @@
67 return ctxt
68
69
70+class NeutronPortContext(OSContextGenerator):
71+ NIC_PREFIXES = ['eth', 'bond']
72+
73+ def resolve_ports(self, ports):
74+ """Resolve NICs not yet bound to bridge(s)
75+
76+ If hwaddress provided then returns resolved hwaddress otherwise NIC.
77+ """
78+ if not ports:
79+ return None
80+
81+ hwaddr_to_nic = {}
82+ hwaddr_to_ip = {}
83+ for nic in list_nics(self.NIC_PREFIXES):
84+ hwaddr = get_nic_hwaddr(nic)
85+ hwaddr_to_nic[hwaddr] = nic
86+ addresses = get_ipv4_addr(nic, fatal=False)
87+ addresses += get_ipv6_addr(iface=nic, fatal=False)
88+ hwaddr_to_ip[hwaddr] = addresses
89+
90+ resolved = []
91+ mac_regex = re.compile(r'([0-9A-F]{2}[:-]){5}([0-9A-F]{2})', re.I)
92+ for entry in ports:
93+ if re.match(mac_regex, entry):
94+ # NIC is in known NICs and does NOT hace an IP address
95+ if entry in hwaddr_to_nic and not hwaddr_to_ip[entry]:
96+ # If the nic is part of a bridge then don't use it
97+ if is_bridge_member(hwaddr_to_nic[entry]):
98+ continue
99+
100+ # Entry is a MAC address for a valid interface that doesn't
101+ # have an IP address assigned yet.
102+ resolved.append(hwaddr_to_nic[entry])
103+ else:
104+ # If the passed entry is not a MAC address, assume it's a valid
105+ # interface, and that the user put it there on purpose (we can
106+ # trust it to be the real external network).
107+ resolved.append(entry)
108+
109+ return resolved
110+
111+
112 class OSConfigFlagContext(OSContextGenerator):
113 """Provides support for user-defined config flags.
114
115
116=== modified file 'hooks/charmhelpers/contrib/openstack/neutron.py'
117--- hooks/charmhelpers/contrib/openstack/neutron.py 2015-01-26 09:47:37 +0000
118+++ hooks/charmhelpers/contrib/openstack/neutron.py 2015-03-18 18:35:37 +0000
119@@ -16,6 +16,7 @@
120
121 # Various utilies for dealing with Neutron and the renaming from Quantum.
122
123+import six
124 from subprocess import check_output
125
126 from charmhelpers.core.hookenv import (
127@@ -237,3 +238,72 @@
128 else:
129 # ensure accurate naming for all releases post-H
130 return 'neutron'
131+
132+
133+def parse_mappings(mappings):
134+ parsed = {}
135+ if mappings:
136+ mappings = mappings.split(' ')
137+ for m in mappings:
138+ p = m.partition(':')
139+ if p[1] == ':':
140+ parsed[p[0].strip()] = p[2].strip()
141+
142+ return parsed
143+
144+
145+def parse_bridge_mappings(mappings):
146+ """Parse bridge mappings.
147+
148+ Mappings must be a space-delimited list of provider:bridge mappings.
149+
150+ Returns dict of the form {provider:bridge}.
151+ """
152+ return parse_mappings(mappings)
153+
154+
155+def parse_data_port_mappings(mappings, default_bridge='br-data'):
156+ """Parse data port mappings.
157+
158+ Mappings must be a space-delimited list of bridge:port mappings.
159+
160+ Returns dict of the form {bridge:port}.
161+ """
162+ _mappings = parse_mappings(mappings)
163+ if not _mappings:
164+ if not mappings:
165+ return {}
166+
167+ # For backwards-compatibility we need to support port-only provided in
168+ # config.
169+ _mappings = {default_bridge: mappings.split(' ')[0]}
170+
171+ bridges = _mappings.keys()
172+ ports = _mappings.values()
173+ if len(set(bridges)) != len(bridges):
174+ raise Exception("It is not allowed to have more than one port "
175+ "configured on the same bridge")
176+
177+ if len(set(ports)) != len(ports):
178+ raise Exception("It is not allowed to have the same port configured "
179+ "on more than one bridge")
180+
181+ return _mappings
182+
183+
184+def parse_vlan_range_mappings(mappings):
185+ """Parse vlan range mappings.
186+
187+ Mappings must be a space-delimited list of provider:start:end mappings.
188+
189+ Returns dict of the form {provider: (start, end)}.
190+ """
191+ _mappings = parse_mappings(mappings)
192+ if not _mappings:
193+ return {}
194+
195+ mappings = {}
196+ for p, r in six.iteritems(_mappings):
197+ mappings[p] = tuple(r.split(':'))
198+
199+ return mappings
200
201=== modified file 'hooks/charmhelpers/core/hookenv.py'
202--- hooks/charmhelpers/core/hookenv.py 2015-01-26 09:47:37 +0000
203+++ hooks/charmhelpers/core/hookenv.py 2015-03-18 18:35:37 +0000
204@@ -566,3 +566,29 @@
205 def charm_dir():
206 """Return the root directory of the current charm"""
207 return os.environ.get('CHARM_DIR')
208+
209+
210+@cached
211+def action_get(key=None):
212+ """Gets the value of an action parameter, or all key/value param pairs"""
213+ cmd = ['action-get']
214+ if key is not None:
215+ cmd.append(key)
216+ cmd.append('--format=json')
217+ action_data = json.loads(subprocess.check_output(cmd).decode('UTF-8'))
218+ return action_data
219+
220+
221+def action_set(values):
222+ """Sets the values to be returned after the action finishes"""
223+ cmd = ['action-set']
224+ for k, v in list(values.items()):
225+ cmd.append('{}={}'.format(k, v))
226+ subprocess.check_call(cmd)
227+
228+
229+def action_fail(message):
230+ """Sets the action status to failed and sets the error message.
231+
232+ The results set by action_set are preserved."""
233+ subprocess.check_call(['action-fail', message])
234
235=== modified file 'hooks/charmhelpers/core/host.py'
236--- hooks/charmhelpers/core/host.py 2015-03-13 13:00:03 +0000
237+++ hooks/charmhelpers/core/host.py 2015-03-18 18:35:37 +0000
238@@ -339,12 +339,16 @@
239 def pwgen(length=None):
240 """Generate a random pasword."""
241 if length is None:
242+ # A random length is ok to use a weak PRNG
243 length = random.choice(range(35, 45))
244 alphanumeric_chars = [
245 l for l in (string.ascii_letters + string.digits)
246 if l not in 'l0QD1vAEIOUaeiou']
247+ # Use a crypto-friendly PRNG (e.g. /dev/urandom) for making the
248+ # actual password
249+ random_generator = random.SystemRandom()
250 random_chars = [
251- random.choice(alphanumeric_chars) for _ in range(length)]
252+ random_generator.choice(alphanumeric_chars) for _ in range(length)]
253 return(''.join(random_chars))
254
255

Subscribers

People subscribed via source and target branches