Merge lp:~tilmanbaumann/charms/trusty/contrail-control/trunk into lp:~sdn-charmers/charms/trusty/contrail-control/trunk

Proposed by Tilman Baumann
Status: Needs review
Proposed branch: lp:~tilmanbaumann/charms/trusty/contrail-control/trunk
Merge into: lp:~sdn-charmers/charms/trusty/contrail-control/trunk
Diff against target: 688 lines (+264/-75)
5 files modified
config.yaml (+6/-0)
hooks/contrail_control_hooks.py (+85/-13)
hooks/contrail_control_utils.py (+161/-61)
metadata.yaml (+2/-0)
templates/control-node.conf (+10/-1)
To merge this branch: bzr merge lp:~tilmanbaumann/charms/trusty/contrail-control/trunk
Reviewer Review Type Date Requested Status
Tilman Baumann (community) Approve
Robert Ayres Pending
Review via email: mp+340110@code.launchpad.net

Description of the change

Previously xmpp-auth was only set to true when tls certificates are set.

There is, however, no strong link between the two settings.

This change allows setting this independently as required.

It would undoubtedly be nicer to have this option only in contrail-contrail and read it via context relation from there. This is rather quick and dirty and a bit redundant.
But it is what I built so far...

To post a comment you must log in.
Revision history for this message
Tilman Baumann (tilmanbaumann) wrote :

Please merge

review: Approve

Unmerged revisions

33. By Tilman Baumann

Adding xmpp_auth option

Sparating xmpp_auth_enable from tls settings
Making it switchable via xmpp_auth config option

32. By Dmitrii Shcherbakov

enable TLS for XMPP communication as of contrail 3

TLS is enabled unconditionally for contail 3.0 and above deployments to
make sure communication is secure by default.

XMPP clients are vrouter agents on compute nodes. XMPP servers are
contrail-control nodes.

Certificates are generated automatically from a PKI charm (e.g. easyrsa
with a Subject Alternative Name field containing an IP address on a
control network which is used by both contrail-control and
neutron-contrail to communicate with each other.

Using a Subject Alternative Name (SAN) with an IP address avoids a
dependency on a DNS infrastructure while keeping the communication
secure between endpoints that are related.

Client authentication by XMPP servers was not supported at the time of
writing hence there is no mention of that in the code.

As of Juju 2.x network spaces can be used if an underlying cloud
supports them. In order to facilitate that support one should bind
control-node endpoint to a specific network space. Otherwise, old
mechanisms such as unit private address are going to be used to retrieve
an ip address to be included into a certificate.

Control node address fetching mechanism has changed as well: instead of
just doing a relation-get for a private IP address of a control-node
unit a different value is taken from the relation data called
control_node_ip (available due to modifications on the contrail-control
side) - it is either an address in the network space which control-node
endpoint is bound to or a fall-back address (unit private address).

31. By Dmitrii Shcherbakov

hooks: pep8 refactoring

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'config.yaml'
2--- config.yaml 2017-03-10 12:54:47 +0000
3+++ config.yaml 2018-02-28 14:49:00 +0000
4@@ -14,6 +14,12 @@
5 The IP address and netmask of the control network (e.g. 192.168.0.0/24).
6 This network will be used for Contrail endpoints.
7 If not specified, default network will be used.
8+ As of Juju 2.x, use network spaces instead and bind the control-node endpoint
9+ to your desired network space instead.
10 ssl-ca:
11 type: string
12 description: PEM encoded X.509 CA certificate for use in SSL.
13+ xmpp_auth:
14+ type: boolean
15+ default: False
16+ description: Use authentication for XMPP vrouter communication
17
18=== modified file 'hooks/contrail_control_hooks.py'
19--- hooks/contrail_control_hooks.py 2017-03-10 12:54:47 +0000
20+++ hooks/contrail_control_hooks.py 2018-02-28 14:49:00 +0000
21@@ -12,7 +12,7 @@
22 log,
23 relation_get,
24 relation_ids,
25- relation_set
26+ relation_set,
27 )
28
29 from charmhelpers.core.host import (
30@@ -39,46 +39,52 @@
31 write_control_config,
32 write_nodemgr_config,
33 write_ssl_ca_certificate,
34- write_vnc_api_config
35+ write_vnc_api_config,
36+ write_xmpp_tls_files,
37 )
38
39-PACKAGES = [ "contrail-control", "contrail-utils", "contrail-nodemgr" ]
40+PACKAGES = ["contrail-control", "contrail-utils", "contrail-nodemgr"]
41
42 hooks = Hooks()
43 config = config()
44
45+
46 def add_control():
47 # check relation dependencies
48 if not config_get("control-provisioned") \
49 and config_get("contrail-api-ready") \
50 and config_get("contrail-discovery-ready") \
51 and config_get("contrail-ifmap-ready") \
52- and config_get("identity-admin-ready"):
53+ and config_get("identity-admin-ready") \
54+ and config_get("tls-certificates-ready"):
55 provision_control()
56 config["control-provisioned"] = True
57
58+
59 @hooks.hook("config-changed")
60 def config_changed():
61 write_config()
62 configure_ssl()
63 if config.get("control-provisioned"):
64 configure_control_network()
65-
66- settings = { "private-address": control_network_ip() }
67+ settings = {"private-address": control_network_ip()}
68 for rid in relation_ids("control-node"):
69 relation_set(relation_id=rid, relation_settings=settings)
70
71+
72 def config_get(key):
73 try:
74 return config[key]
75 except KeyError:
76 return None
77
78+
79 def configure_control_network():
80 if control_network_ip() != config["provisioned-host-ip"]:
81 unprovision_control()
82 provision_control()
83
84+
85 def configure_ssl():
86 cert = config.get("ssl-ca")
87 if cert:
88@@ -86,6 +92,7 @@
89 else:
90 remove_ssl_ca_certificate()
91
92+
93 @hooks.hook("contrail-api-relation-changed")
94 def contrail_api_changed():
95 if not relation_get("port"):
96@@ -95,6 +102,7 @@
97 config["contrail-api-ready"] = True
98 add_control()
99
100+
101 @hooks.hook("contrail-api-relation-departed")
102 @hooks.hook("contrail-api-relation-broken")
103 def contrail_api_departed():
104@@ -103,6 +111,7 @@
105 config["contrail-api-ready"] = False
106 write_vnc_api_config()
107
108+
109 @hooks.hook("contrail-discovery-relation-changed")
110 def contrail_discovery_changed():
111 if not relation_get("port"):
112@@ -112,6 +121,7 @@
113 config["contrail-discovery-ready"] = True
114 add_control()
115
116+
117 @hooks.hook("contrail-discovery-relation-departed")
118 @hooks.hook("contrail-discovery-relation-broken")
119 def contrail_discovery_departed():
120@@ -120,13 +130,18 @@
121 config["contrail-discovery-ready"] = False
122 contrail_discovery_relation()
123
124-@restart_on_change({"/etc/contrail/contrail-control.conf": ["contrail-control"],
125- "/etc/contrail/control-node.conf": ["contrail-control"],
126- "/etc/contrail/contrail-control-nodemgr.conf": ["contrail-control-nodemgr"]})
127+
128+@restart_on_change(
129+ {
130+ "/etc/contrail/contrail-control.conf": ["contrail-control"],
131+ "/etc/contrail/control-node.conf": ["contrail-control"],
132+ "/etc/contrail/contrail-control-nodemgr.conf":
133+ ["contrail-control-nodemgr"]})
134 def contrail_discovery_relation():
135 write_control_config()
136 write_nodemgr_config()
137
138+
139 @hooks.hook("contrail-ifmap-relation-changed")
140 def contrail_ifmap_changed():
141 creds = relation_get("creds")
142@@ -138,6 +153,7 @@
143 config["contrail-ifmap-ready"] = True
144 add_control()
145
146+
147 @hooks.hook("contrail-ifmap-relation-departed")
148 @hooks.hook("contrail-ifmap-relation-broken")
149 def contrail_ifmap_departed():
150@@ -146,16 +162,21 @@
151 config["contrail-ifmap-ready"] = False
152 contrail_ifmap_relation()
153
154-@restart_on_change({"/etc/contrail/contrail-control.conf": ["contrail-control"],
155- "/etc/contrail/control-node.conf": ["contrail-control"]})
156+
157+@restart_on_change(
158+ {
159+ "/etc/contrail/contrail-control.conf": ["contrail-control"],
160+ "/etc/contrail/control-node.conf": ["contrail-control"]})
161 def contrail_ifmap_relation():
162 write_control_config()
163
164+
165 @hooks.hook("control-node-relation-joined")
166 def control_node_joined():
167- settings = { "private-address": control_network_ip() }
168+ settings = {"private-address": control_network_ip()}
169 relation_set(relation_settings=settings)
170
171+
172 @hooks.hook("identity-admin-relation-changed")
173 def identity_admin_changed():
174 if not relation_get("service_hostname"):
175@@ -165,6 +186,7 @@
176 config["identity-admin-ready"] = True
177 add_control()
178
179+
180 @hooks.hook("identity-admin-relation-departed")
181 @hooks.hook("identity-admin-relation-broken")
182 def identity_admin_departed():
183@@ -173,6 +195,50 @@
184 config["identity-admin-ready"] = False
185 write_vnc_api_config()
186
187+
188+@hooks.hook('tls-certificates-relation-joined')
189+def tls_certificates_relation_joined():
190+ # a hostname could also be provided as a SAN
191+ # (Subject Alternative Name) but having this one
192+ # has certain implications
193+ # https://tools.ietf.org/html/rfc2818#section-3.1
194+ # "If a subjectAltName extension of type dNSName
195+ # is present, that MUST be used as the identity"
196+ # Therefore it is not used here as we don't need
197+ # a DNS infrastructure dependency
198+ ip_san = control_network_ip()
199+ settings = {
200+ 'sans': json.dumps([ip_san, '127.0.0.1']),
201+ 'common_name': ip_san,
202+ 'certificate_name': local_unit().replace('/', '_')
203+ }
204+ relation_set(relation_settings=settings)
205+
206+
207+@hooks.hook('tls-certificates-relation-changed')
208+def tls_certificates_relation_changed():
209+ # check that the -provides side have set the data we need
210+ # and render the affected files
211+ unitname = local_unit().replace('/', '_')
212+ cert = '{0}.server.cert'.format(unitname)
213+ key = '{0}.server.key'.format(unitname)
214+ certv = relation_get(cert)
215+ keyv = relation_get(key)
216+ ca = relation_get('ca')
217+
218+ if certv and keyv and ca:
219+ write_xmpp_tls_files(certv, keyv, ca)
220+ config["tls-certificates-ready"] = True
221+ else:
222+ log('tls-certificates relation data is not fully available')
223+ config["tls-certificates-ready"] = False
224+
225+
226+@hooks.hook('tls-certificates-relation-departed')
227+def tls_certificates_relation_departed():
228+ config["tls-certificates-ready"] = False
229+
230+
231 @hooks.hook()
232 def install():
233 configure_sources(True, "install-sources", "install-keys")
234@@ -182,26 +248,32 @@
235 fix_permissions()
236 fix_nodemgr()
237
238+
239 def main():
240 try:
241 hooks.execute(sys.argv)
242 except UnregisteredHookError as e:
243 log("Unknown hook {} - skipping.".format(e))
244
245+
246 def remove_control():
247 if config_get("control-provisioned"):
248 unprovision_control()
249 config["control-provisioned"] = False
250
251+
252 @hooks.hook("upgrade-charm")
253 def upgrade_charm():
254 write_control_config()
255 write_nodemgr_config()
256 service_restart("supervisor-control")
257
258-@restart_on_change({"/etc/contrail/contrail-control.conf": ["contrail-control"]})
259+
260+@restart_on_change(
261+ {"/etc/contrail/contrail-control.conf": ["contrail-control"]})
262 def write_config():
263 write_control_config()
264
265+
266 if __name__ == "__main__":
267 main()
268
269=== modified file 'hooks/contrail_control_utils.py'
270--- hooks/contrail_control_utils.py 2017-03-10 12:54:47 +0000
271+++ hooks/contrail_control_utils.py 2018-02-28 14:49:00 +0000
272@@ -21,26 +21,32 @@
273 log,
274 related_units,
275 relation_get,
276+ relation_set,
277 relation_ids,
278 relation_type,
279 remote_unit,
280- unit_get
281+ unit_private_ip,
282+ network_get_primary_address,
283 )
284 from charmhelpers.core.host import service_restart
285 from charmhelpers.core.templating import render
286
287 apt_pkg.init()
288
289+
290 def dpkg_version(pkg):
291 try:
292- return check_output(["dpkg-query", "-f", "${Version}\\n", "-W", pkg]).rstrip()
293+ return check_output(
294+ ["dpkg-query", "-f", "${Version}\\n", "-W", pkg]).rstrip()
295 except CalledProcessError:
296 return None
297
298+
299 CONTRAIL_VERSION = dpkg_version("contrail-control")
300
301 config = config()
302
303+
304 def retry(f=None, timeout=10, delay=2):
305 """Retry decorator.
306
307@@ -64,6 +70,7 @@
308 """
309 if not f:
310 return functools.partial(retry, timeout=timeout, delay=delay)
311+
312 @functools.wraps(f)
313 def func(*args, **kwargs):
314 start = time()
315@@ -84,29 +91,36 @@
316 raise error
317 return func
318
319+
320 def contrail_api_ctx():
321- ctxs = [ { "api_server": gethostbyname(relation_get("private-address", unit, rid)),
322- "api_port": port }
323- for rid in relation_ids("contrail-api")
324- for unit, port in
325- ((unit, relation_get("port", unit, rid)) for unit in related_units(rid))
326- if port ]
327+ ctxs = [{"api_server": gethostbyname(relation_get("private-address",
328+ unit, rid)),
329+ "api_port": port}
330+ for rid in relation_ids("contrail-api")
331+ for unit, port in
332+ ((unit, relation_get("port", unit, rid))
333+ for unit in related_units(rid))
334+ if port]
335 return ctxs[0] if ctxs else {}
336
337+
338 def contrail_ctx():
339- return { "host_ip": control_network_ip() }
340+ return {"host_ip": control_network_ip()}
341+
342
343 def contrail_discovery_ctx():
344- ctxs = [ { "discovery_server": vip if vip \
345- else gethostbyname(relation_get("private-address", unit, rid)),
346- "discovery_port": port }
347- for rid in relation_ids("contrail-discovery")
348- for unit, port, vip in
349- ((unit, relation_get("port", unit, rid), relation_get("vip", unit, rid))
350- for unit in related_units(rid))
351- if port ]
352+ ctxs = [{"discovery_server": vip if vip
353+ else gethostbyname(relation_get("private-address", unit, rid)),
354+ "discovery_port": port}
355+ for rid in relation_ids("contrail-discovery")
356+ for unit, port, vip in
357+ ((unit, relation_get("port", unit, rid),
358+ relation_get("vip", unit, rid))
359+ for unit in related_units(rid))
360+ if port]
361 return ctxs[0] if ctxs else {}
362
363+
364 def contrail_ifmap_ctx():
365 ctxs = []
366 unit = local_unit()
367@@ -123,6 +137,7 @@
368 ctxs.append(ctx)
369 return ctxs[0] if ctxs else {}
370
371+
372 @retry(timeout=300)
373 def contrail_provision_control(hostname, ip, router_asn, api_ip, api_port, op,
374 user, password, tenant):
375@@ -137,19 +152,42 @@
376 "--admin_password", password,
377 "--admin_tenant_name", tenant])
378
379+
380 def control_network_ip():
381- fallback = gethostbyname(unit_get("private-address"))
382- network = config.get("control-network")
383- if network:
384- return get_address_in_network(network, fallback)
385- else:
386- return fallback
387+ '''
388+ With Juju 2.x, uses an endpoint (relation)
389+ network space binding if unspecified will use a "unit private address"
390+ which is far less explicit if you look at the Juju implementation.
391+ If you use Juju 2.x and above - bind the control-node endpoint to a network
392+ space to get a proper address in this function.
393+
394+ If network-get throws an exception (juju 1.x or spaces are not supported)
395+ will try to fall back to the control-network parameter or a private-address
396+ as returned by Juju.
397+ '''
398+ try:
399+ address = network_get_primary_address('control-node')
400+ except NotImplementedError:
401+ log('Network spaces are not implemented - falling back to'
402+ ' getting a private address')
403+ address = None
404+
405+ if not address:
406+ fallback = gethostbyname(unit_private_ip())
407+ network = config.get("control-network")
408+ if network:
409+ address = get_address_in_network(network, fallback)
410+ else:
411+ address = fallback
412+
413+ return address
414+
415
416 def fix_nodemgr():
417 # add files missing from contrail-nodemgr package
418 dest = "/etc/contrail/supervisord_control_files/" \
419- + ("contrail-control-nodemgr.ini" \
420- if version_compare(CONTRAIL_VERSION, "3.1") >= 0 \
421+ + ("contrail-control-nodemgr.ini"
422+ if version_compare(CONTRAIL_VERSION, "3.1") >= 0
423 else "contrail-nodemgr-control.ini")
424 shutil.copy("files/contrail-nodemgr-control.ini", dest)
425 pw = pwd.getpwnam("contrail")
426@@ -159,7 +197,7 @@
427 if version_compare(CONTRAIL_VERSION, "3.1") >= 0 \
428 else "files/contrail-control-nodemgr"
429 shutil.copy(src, "/etc/init.d/contrail-control-nodemgr")
430- os.chmod("/etc/init.d/contrail-control-nodemgr", 0755)
431+ os.chmod("/etc/init.d/contrail-control-nodemgr", 0o755)
432
433 # fake ntp status when inside a container
434 if is_container():
435@@ -167,20 +205,24 @@
436
437 service_restart("supervisor-control")
438
439+
440 def fix_permissions():
441- os.chmod("/etc/contrail", 0755)
442+ os.chmod("/etc/contrail", 0o755)
443 os.chown("/etc/contrail", 0, 0)
444
445+
446 def identity_admin_ctx():
447- ctxs = [ { "auth_host": gethostbyname(hostname),
448- "auth_port": relation_get("service_port", unit, rid),
449- "auth_protocol": relation_get("service_protocol", unit, rid) }
450- for rid in relation_ids("identity-admin")
451- for unit, hostname in
452- ((unit, relation_get("service_hostname", unit, rid)) for unit in related_units(rid))
453- if hostname ]
454+ ctxs = [{"auth_host": gethostbyname(hostname),
455+ "auth_port": relation_get("service_port", unit, rid),
456+ "auth_protocol": relation_get("service_protocol", unit, rid)}
457+ for rid in relation_ids("identity-admin")
458+ for unit, hostname in
459+ ((unit, relation_get("service_hostname", unit, rid))
460+ for unit in related_units(rid))
461+ if hostname]
462 return ctxs[0] if ctxs else {}
463
464+
465 def is_container():
466 """Return boolean determining if inside container"""
467 try:
468@@ -189,26 +231,36 @@
469 except CalledProcessError:
470 return False
471
472+
473 def provision_control():
474 hostname = gethostname()
475 ip = control_network_ip()
476- api_ip, api_port = [ (gethostbyname(relation_get("private-address", unit, rid)),
477- port)
478- for rid in relation_ids("contrail-api")
479- for unit, port in
480- ((unit, relation_get("port", unit, rid)) for unit in related_units(rid))
481- if port ][0]
482- user, password, tenant = [ (relation_get("service_username", unit, rid),
483- relation_get("service_password", unit, rid),
484- relation_get("service_tenant_name", unit, rid))
485- for rid in relation_ids("identity-admin")
486- for unit in related_units(rid)
487- if relation_get("service_hostname", unit, rid) ][0]
488+ api_ip, api_port = [(gethostbyname(relation_get("private-address",
489+ unit, rid)), port)
490+ for rid in relation_ids("contrail-api")
491+ for unit, port in
492+ ((unit, relation_get("port", unit, rid))
493+ for unit in related_units(rid))
494+ if port][0]
495+ user, password, tenant = [(relation_get("service_username", unit, rid),
496+ relation_get("service_password", unit, rid),
497+ relation_get("service_tenant_name", unit, rid))
498+ for rid in relation_ids("identity-admin")
499+ for unit in related_units(rid)
500+ if relation_get("service_hostname",
501+ unit, rid)][0]
502 log("Provisioning control {}".format(ip))
503 contrail_provision_control(hostname, ip, 64512, api_ip, api_port, "add",
504 user, password, tenant)
505+
506+ # support for network spaces
507+ # see control_network_ip implementation
508+ for rid in relation_ids("control-node"):
509+ relation_set(rid, {'control_node_ip': ip})
510+
511 config["provisioned-host-ip"] = ip
512
513+
514 def remove_ssl_ca_certificate():
515 if os.path.exists("/usr/local/share/ca-certificates/contrail-juju.crt"):
516 os.remove("/usr/local/share/ca-certificates/contrail-juju.crt")
517@@ -217,10 +269,12 @@
518 else:
519 return False
520
521+
522 def units(relation):
523 """Return a list of units for the specified relation"""
524- return [ unit for rid in relation_ids(relation)
525- for unit in related_units(rid) ]
526+ return [unit for rid in relation_ids(relation)
527+ for unit in related_units(rid)]
528+
529
530 def unprovision_control():
531 relation = relation_type()
532@@ -234,10 +288,11 @@
533 api_ip = gethostbyname(relation_get("private-address"))
534 api_port = relation_get("port")
535 else:
536- api_ip, api_port = [ (gethostbyname(relation_get("private-address", unit, rid)),
537- relation_get("port", unit, rid))
538- for rid in relation_ids("contrail-api")
539- for unit in related_units(rid) ][0]
540+ api_ip, api_port = [(gethostbyname(relation_get("private-address",
541+ unit, rid)),
542+ relation_get("port", unit, rid))
543+ for rid in relation_ids("contrail-api")
544+ for unit in related_units(rid)][0]
545 user = None
546 password = None
547 tenant = None
548@@ -246,37 +301,58 @@
549 password = relation_get("service_password")
550 tenant = relation_get("service_tenant_name")
551 else:
552- user, password, tenant = [ (relation_get("service_username", unit, rid),
553- relation_get("service_password", unit, rid),
554- relation_get("service_tenant_name", unit, rid))
555- for rid in relation_ids("identity-admin")
556- for unit in related_units(rid) ][0]
557+ user, password, tenant = [(relation_get("service_username", unit, rid),
558+ relation_get("service_password", unit, rid),
559+ relation_get("service_tenant_name",
560+ unit, rid))
561+ for rid in relation_ids("identity-admin")
562+ for unit in related_units(rid)][0]
563 log("Unprovisioning control {}".format(ip))
564 try:
565- contrail_provision_control(hostname, ip, 64512, api_ip, api_port, "del",
566- user, password, tenant)
567+ contrail_provision_control(
568+ hostname,
569+ ip,
570+ 64512,
571+ api_ip,
572+ api_port,
573+ "del",
574+ user,
575+ password,
576+ tenant)
577 except CalledProcessError:
578 pass
579 del config["provisioned-host-ip"]
580
581+
582 def write_control_config():
583 ctx = {}
584 ctx.update(contrail_ctx())
585 ctx.update(contrail_discovery_ctx())
586 ctx.update(contrail_ifmap_ctx())
587+
588+ xmpp_auth_enable = config.get('xmpp_auth')
589+ ctx.update({"xmpp_auth_enable": xmpp_auth_enable})
590+
591+ # a tls-certificates guard here is for the upgrade scenario
592+ tls_implemented = version_compare(CONTRAIL_VERSION, "3.0") >= 0 and\
593+ config.get("tls-certificates-ready")
594+ ctx.update({'tls_implemented': tls_implemented})
595 target = "/etc/contrail/contrail-control.conf" \
596 if version_compare(CONTRAIL_VERSION, "2.0") >= 0 \
597 else "/etc/contrail/control-node.conf"
598- render("control-node.conf", target, ctx, "root", "contrail", 0440)
599+ render("control-node.conf", target, ctx, "root", "contrail", 0o440)
600+
601
602 def write_nodemgr_config():
603 ctx = contrail_discovery_ctx()
604 render("contrail-control-nodemgr.conf",
605 "/etc/contrail/contrail-control-nodemgr.conf", ctx)
606
607+
608 def write_ssl_ca_certificate(cert):
609 if os.path.exists("/usr/local/share/ca-certificates/contrail-juju.crt"):
610- with open("/usr/local/share/ca-certificates/contrail-juju.crt", "r") as f:
611+ with open("/usr/local/share/ca-certificates/contrail-juju.crt", "r") \
612+ as f:
613 c = f.read()
614 if c == cert:
615 return False
616@@ -285,6 +361,30 @@
617 check_call(["update-ca-certificates"])
618 return True
619
620+
621+def write_xmpp_tls_files(serv_cert, priv_key, ca):
622+ prefix = '/etc/contrail/ssl'
623+ certs = os.path.join(prefix, 'certs')
624+ private = os.path.join(prefix, 'private')
625+
626+ entry = pwd.getpwnam('contrail')
627+ for p in [prefix, certs, private]:
628+ if not os.path.exists(p):
629+ os.makedirs(p, 0o750)
630+ os.chown(p, entry.pw_uid, entry.pw_gid)
631+
632+ fcontent = {
633+ os.path.join(certs, 'server.pem'): serv_cert,
634+ os.path.join(private, 'server-privkey.pem'): priv_key,
635+ os.path.join(certs, 'ca-cert.pem'): ca,
636+ }
637+
638+ for filepath, content in fcontent.iteritems():
639+ with open(filepath, 'w+') as f:
640+ f.truncate(0)
641+ f.write(content)
642+
643+
644 def write_vnc_api_config():
645 ctx = {}
646 ctx.update(contrail_api_ctx())
647
648=== added symlink 'hooks/tls-certificates-relation-changed'
649=== target is u'contrail_control_hooks.py'
650=== added symlink 'hooks/tls-certificates-relation-departed'
651=== target is u'contrail_control_hooks.py'
652=== added symlink 'hooks/tls-certificates-relation-joined'
653=== target is u'contrail_control_hooks.py'
654=== modified file 'metadata.yaml'
655--- metadata.yaml 2015-09-17 21:09:59 +0000
656+++ metadata.yaml 2018-02-28 14:49:00 +0000
657@@ -20,3 +20,5 @@
658 interface: contrail-ifmap
659 identity-admin:
660 interface: keystone-admin
661+ tls-certificates:
662+ interface: tls-certificates
663
664=== modified file 'templates/control-node.conf'
665--- templates/control-node.conf 2015-10-01 12:29:04 +0000
666+++ templates/control-node.conf 2018-02-28 14:49:00 +0000
667@@ -6,6 +6,16 @@
668 [DEFAULT]
669 hostip = {{ host_ip }}
670
671+{% if xmpp_auth_enable -%}
672+xmpp_auth_enable=true
673+{% endif -%}
674+
675+{% if tls_implemented -%}
676+xmpp_server_cert=/etc/contrail/ssl/certs/server.pem
677+xmpp_server_key=/etc/contrail/ssl/private/server-privkey.pem
678+xmpp_ca_cert=/etc/contrail/ssl/certs/ca-cert.pem
679+{% endif -%}
680+
681 [DISCOVERY]
682 server = {{ discovery_server }}
683 port = {{ discovery_port }}
684@@ -13,4 +23,3 @@
685 [IFMAP]
686 user = {{ ifmap_user }}
687 password = {{ ifmap_password }}
688-

Subscribers

People subscribed via source and target branches

to all changes: