Merge lp:~dmitriis/charms/trusty/neutron-contrail/trunk into lp:~sdn-charmers/charms/trusty/neutron-contrail/trunk
- Trusty Tahr (14.04)
- trunk
- Merge into trunk
| Status: | Superseded |
|---|---|
| Proposed branch: | lp:~dmitriis/charms/trusty/neutron-contrail/trunk |
| Merge into: | lp:~sdn-charmers/charms/trusty/neutron-contrail/trunk |
| Diff against target: |
1024 lines (+356/-150) 4 files modified
hooks/neutron_contrail_hooks.py (+149/-59) hooks/neutron_contrail_utils.py (+196/-91) metadata.yaml (+2/-0) templates/contrail-vrouter-agent.conf (+9/-0) |
| To merge this branch: | bzr merge lp:~dmitriis/charms/trusty/neutron-contrail/trunk |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Ante Karamatić | Pending | ||
|
Review via email:
|
|||
Commit message
Description of the change
| Dmitrii Shcherbakov (dmitriis) wrote : | # |
- 67. 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.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.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).
Unmerged revisions
- 67. 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.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.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). - 66. By Dmitrii Shcherbakov
-
hooks,utils: pep8 refactoring
Preview Diff
| 1 | === modified file 'hooks/neutron_contrail_hooks.py' |
| 2 | --- hooks/neutron_contrail_hooks.py 2017-03-10 12:57:45 +0000 |
| 3 | +++ hooks/neutron_contrail_hooks.py 2017-03-26 17:44:17 +0000 |
| 4 | @@ -18,7 +18,8 @@ |
| 5 | log, |
| 6 | relation_get, |
| 7 | relation_ids, |
| 8 | - relation_set |
| 9 | + relation_set, |
| 10 | + local_unit, |
| 11 | ) |
| 12 | |
| 13 | from charmhelpers.core.host import ( |
| 14 | @@ -37,6 +38,7 @@ |
| 15 | CONTRAIL_VERSION, |
| 16 | OPENSTACK_VERSION, |
| 17 | configure_vrouter, |
| 18 | + control_network_ip, |
| 19 | disable_vrouter_vgw, |
| 20 | dpkg_version, |
| 21 | drop_caches, |
| 22 | @@ -57,23 +59,25 @@ |
| 23 | write_nodemgr_config, |
| 24 | write_vnc_api_config, |
| 25 | write_vrouter_config, |
| 26 | - write_vrouter_vgw_interfaces |
| 27 | + write_vrouter_vgw_interfaces, |
| 28 | + write_xmpp_tls_files, |
| 29 | ) |
| 30 | |
| 31 | -PACKAGES = [ "contrail-vrouter-dkms", "contrail-vrouter-agent", |
| 32 | - "contrail-utils", "python-jinja2", "python-netifaces", |
| 33 | - "python-netaddr", "contrail-nodemgr" ] |
| 34 | - |
| 35 | -PACKAGES_LBAAS = [ "python-barbicanclient", "haproxy" ] |
| 36 | - |
| 37 | -PACKAGES_VROUTER = [ "contrail-nova-driver" ] |
| 38 | - |
| 39 | -PACKAGES_VROUTER_3_2 = [ "contrail-nova-vif", "contrail-vrouter-init", |
| 40 | - "contrail-vrouter-common" ] |
| 41 | +PACKAGES = ["contrail-vrouter-dkms", "contrail-vrouter-agent", |
| 42 | + "contrail-utils", "python-jinja2", "python-netifaces", |
| 43 | + "python-netaddr", "contrail-nodemgr"] |
| 44 | + |
| 45 | +PACKAGES_LBAAS = ["python-barbicanclient", "haproxy"] |
| 46 | + |
| 47 | +PACKAGES_VROUTER = ["contrail-nova-driver"] |
| 48 | + |
| 49 | +PACKAGES_VROUTER_3_2 = ["contrail-nova-vif", "contrail-vrouter-init", |
| 50 | + "contrail-vrouter-common"] |
| 51 | |
| 52 | hooks = Hooks() |
| 53 | config = config() |
| 54 | |
| 55 | + |
| 56 | def check_local_metadata(): |
| 57 | if not is_leader(): |
| 58 | return |
| 59 | @@ -95,11 +99,13 @@ |
| 60 | unprovision_local_metadata() |
| 61 | leader_set({"local-metadata-provisioned": ""}) |
| 62 | |
| 63 | + |
| 64 | def check_vrouter(): |
| 65 | # check relation dependencies |
| 66 | if config_get("contrail-api-ready") \ |
| 67 | and config_get("control-node-ready") \ |
| 68 | - and config_get("identity-admin-ready"): |
| 69 | + and config_get("identity-admin-ready") \ |
| 70 | + and config_get("tls-certificates-ready"): |
| 71 | if not config_get("vrouter-provisioned"): |
| 72 | provision_vrouter() |
| 73 | config["vrouter-provisioned"] = True |
| 74 | @@ -107,33 +113,36 @@ |
| 75 | unprovision_vrouter() |
| 76 | config["vrouter-provisioned"] = False |
| 77 | |
| 78 | + |
| 79 | @hooks.hook("config-changed") |
| 80 | def config_changed(): |
| 81 | configure_local_metadata() |
| 82 | configure_virtual_gateways() |
| 83 | write_config() |
| 84 | if not units("contrail-discovery") and not units("control-node"): |
| 85 | - config["control-node-ready"] = True if config.get("discovery-server-ip") \ |
| 86 | - else False |
| 87 | + config["control-node-ready"] = True \ |
| 88 | + if config.get("discovery-server-ip") else False |
| 89 | if not units("contrail-api"): |
| 90 | config["contrail-api-ready"] = True if config.get("contrail-api-ip") \ |
| 91 | - else False |
| 92 | + else False |
| 93 | check_vrouter() |
| 94 | check_local_metadata() |
| 95 | |
| 96 | + |
| 97 | def config_get(key): |
| 98 | try: |
| 99 | return config[key] |
| 100 | except KeyError: |
| 101 | return None |
| 102 | |
| 103 | + |
| 104 | def configure_local_metadata(): |
| 105 | if config["local-metadata-server"]: |
| 106 | if "local-metadata-secret" not in config: |
| 107 | # generate secret |
| 108 | secret = str(uuid.uuid4()) |
| 109 | config["local-metadata-secret"] = secret |
| 110 | - settings = { "metadata-shared-secret": secret } |
| 111 | + settings = {"metadata-shared-secret": secret} |
| 112 | # inform relations |
| 113 | for rid in relation_ids("neutron-plugin"): |
| 114 | relation_set(relation_id=rid, relation_settings=settings) |
| 115 | @@ -141,42 +150,47 @@ |
| 116 | if "local-metadata-secret" in config: |
| 117 | # remove secret |
| 118 | del config["local-metadata-secret"] |
| 119 | - settings = { "metadata-shared-secret": None } |
| 120 | + settings = {"metadata-shared-secret": None} |
| 121 | # inform relations |
| 122 | for rid in relation_ids("neutron-plugin"): |
| 123 | relation_set(relation_id=rid, relation_settings=settings) |
| 124 | |
| 125 | + |
| 126 | def configure_virtual_gateways(): |
| 127 | gateways = config.get("virtual-gateways") |
| 128 | previous_gateways = config_get("virtual-gateways-prev") |
| 129 | if gateways != previous_gateways: |
| 130 | # create/destroy virtual gateway interfaces according to new value |
| 131 | - interfaces = { gateway["interface"]: set(gateway["subnets"]) |
| 132 | - for gateway in yaml.safe_load(gateways) } \ |
| 133 | - if gateways else {} |
| 134 | - previous_interfaces = { gateway["interface"]: set(gateway["subnets"]) |
| 135 | - for gateway in yaml.safe_load(previous_gateways) } \ |
| 136 | - if previous_gateways else {} |
| 137 | - ifaces = [ interface for interface, subnets in previous_interfaces.iteritems() |
| 138 | - if interface not in interfaces |
| 139 | - or subnets != interfaces[interface] ] |
| 140 | + interfaces = {gateway["interface"]: set(gateway["subnets"]) |
| 141 | + for gateway in yaml.safe_load(gateways)} \ |
| 142 | + if gateways else {} |
| 143 | + previous_interfaces = {gateway["interface"]: set(gateway["subnets"]) |
| 144 | + for gateway |
| 145 | + in yaml.safe_load(previous_gateways)} \ |
| 146 | + if previous_gateways else {} |
| 147 | + ifaces = [interface for interface, subnets |
| 148 | + in previous_interfaces.iteritems() |
| 149 | + if interface not in interfaces |
| 150 | + or subnets != interfaces[interface]] |
| 151 | if ifaces: |
| 152 | ifdown(ifaces) |
| 153 | |
| 154 | - write_vrouter_vgw_interfaces() |
| 155 | - |
| 156 | - ifaces = [ interface for interface, subnets in interfaces.iteritems() |
| 157 | - if interface not in previous_interfaces |
| 158 | - or subnets != previous_interfaces[interface] ] |
| 159 | - if ifaces: |
| 160 | - ifup(ifaces) |
| 161 | - |
| 162 | - if interfaces: |
| 163 | - enable_vrouter_vgw() |
| 164 | - else: |
| 165 | - disable_vrouter_vgw() |
| 166 | - |
| 167 | - config["virtual-gateways-prev"] = gateways |
| 168 | + write_vrouter_vgw_interfaces() |
| 169 | + |
| 170 | + ifaces = [interface for interface, subnets |
| 171 | + in interfaces.iteritems() |
| 172 | + if interface not in previous_interfaces |
| 173 | + or subnets != previous_interfaces[interface]] |
| 174 | + if ifaces: |
| 175 | + ifup(ifaces) |
| 176 | + |
| 177 | + if interfaces: |
| 178 | + enable_vrouter_vgw() |
| 179 | + else: |
| 180 | + disable_vrouter_vgw() |
| 181 | + |
| 182 | + config["virtual-gateways-prev"] = gateways |
| 183 | + |
| 184 | |
| 185 | @hooks.hook("contrail-api-relation-departed") |
| 186 | @hooks.hook("contrail-api-relation-broken") |
| 187 | @@ -187,6 +201,7 @@ |
| 188 | check_local_metadata() |
| 189 | write_vnc_api_config() |
| 190 | |
| 191 | + |
| 192 | @hooks.hook("contrail-api-relation-changed") |
| 193 | def contrail_api_changed(): |
| 194 | if not relation_get("port"): |
| 195 | @@ -197,6 +212,7 @@ |
| 196 | check_vrouter() |
| 197 | check_local_metadata() |
| 198 | |
| 199 | + |
| 200 | @hooks.hook("contrail-discovery-relation-changed") |
| 201 | def contrail_discovery_changed(): |
| 202 | if not relation_get("port"): |
| 203 | @@ -207,6 +223,7 @@ |
| 204 | check_vrouter() |
| 205 | check_local_metadata() |
| 206 | |
| 207 | + |
| 208 | @hooks.hook("contrail-discovery-relation-departed") |
| 209 | @hooks.hook("contrail-discovery-relation-broken") |
| 210 | def contrail_discovery_departed(): |
| 211 | @@ -218,12 +235,18 @@ |
| 212 | check_local_metadata() |
| 213 | contrail_discovery_relation() |
| 214 | |
| 215 | -@restart_on_change({"/etc/contrail/contrail-vrouter-agent.conf": ["contrail-vrouter-agent"], |
| 216 | - "/etc/contrail/contrail-vrouter-nodemgr.conf": ["contrail-vrouter-nodemgr"]}) |
| 217 | + |
| 218 | +@restart_on_change( |
| 219 | + { |
| 220 | + "/etc/contrail/contrail-vrouter-agent.conf": |
| 221 | + ["contrail-vrouter-agent"], |
| 222 | + "/etc/contrail/contrail-vrouter-nodemgr.conf": |
| 223 | + ["contrail-vrouter-nodemgr"]}) |
| 224 | def contrail_discovery_relation(): |
| 225 | write_vrouter_config() |
| 226 | write_nodemgr_config() |
| 227 | |
| 228 | + |
| 229 | @hooks.hook("control-node-relation-departed") |
| 230 | @hooks.hook("control-node-relation-broken") |
| 231 | def control_node_departed(): |
| 232 | @@ -235,6 +258,7 @@ |
| 233 | check_local_metadata() |
| 234 | control_node_relation() |
| 235 | |
| 236 | + |
| 237 | @hooks.hook("control-node-relation-changed") |
| 238 | def control_node_changed(): |
| 239 | control_node_relation() |
| 240 | @@ -242,10 +266,13 @@ |
| 241 | check_vrouter() |
| 242 | check_local_metadata() |
| 243 | |
| 244 | -@restart_on_change({"/etc/contrail/contrail-vrouter-agent.conf": ["contrail-vrouter-agent"]}) |
| 245 | + |
| 246 | +@restart_on_change( |
| 247 | + {"/etc/contrail/contrail-vrouter-agent.conf": ["contrail-vrouter-agent"]}) |
| 248 | def control_node_relation(): |
| 249 | write_vrouter_config() |
| 250 | |
| 251 | + |
| 252 | @hooks.hook("identity-admin-relation-changed") |
| 253 | def identity_admin_changed(): |
| 254 | if not relation_get("service_hostname"): |
| 255 | @@ -258,6 +285,7 @@ |
| 256 | check_vrouter() |
| 257 | check_local_metadata() |
| 258 | |
| 259 | + |
| 260 | @hooks.hook("identity-admin-relation-departed") |
| 261 | @hooks.hook("identity-admin-relation-broken") |
| 262 | def identity_admin_departed(): |
| 263 | @@ -269,11 +297,12 @@ |
| 264 | if version_compare(CONTRAIL_VERSION, "3.0.2.0-34") >= 0: |
| 265 | write_barbican_auth_config() |
| 266 | |
| 267 | + |
| 268 | @hooks.hook() |
| 269 | def install(): |
| 270 | configure_sources(True, "install-sources", "install-keys") |
| 271 | apt_upgrade(fatal=True, dist=True) |
| 272 | - fix_vrouter_scripts() # bug in 2.0+20141015.1 packages |
| 273 | + fix_vrouter_scripts() # bug in 2.0+20141015.1 packages |
| 274 | apt_install(PACKAGES, fatal=True) |
| 275 | utils.CONTRAIL_VERSION = dpkg_version("contrail-vrouter-agent") |
| 276 | if version_compare(utils.CONTRAIL_VERSION, "3.2") >= 0: |
| 277 | @@ -293,13 +322,15 @@ |
| 278 | try: |
| 279 | modprobe("vrouter") |
| 280 | except CalledProcessError: |
| 281 | - log("vrouter kernel module failed to load, clearing pagecache and retrying") |
| 282 | + log("vrouter kernel module failed to load," |
| 283 | + " clearing pagecache and retrying") |
| 284 | drop_caches() |
| 285 | modprobe("vrouter") |
| 286 | modprobe("vrouter", True, True) |
| 287 | configure_vrouter() |
| 288 | service_restart("nova-compute") |
| 289 | |
| 290 | + |
| 291 | @hooks.hook("neutron-metadata-relation-changed") |
| 292 | def neutron_metadata_changed(): |
| 293 | if not relation_get("shared-secret"): |
| 294 | @@ -307,43 +338,96 @@ |
| 295 | return |
| 296 | neutron_metadata_relation() |
| 297 | |
| 298 | + |
| 299 | @hooks.hook("neutron-metadata-relation-departed") |
| 300 | @hooks.hook("neutron-metadata-relation-broken") |
| 301 | -@restart_on_change({"/etc/contrail/contrail-vrouter-agent.conf": ["contrail-vrouter-agent"]}) |
| 302 | +@restart_on_change( |
| 303 | + {"/etc/contrail/contrail-vrouter-agent.conf": ["contrail-vrouter-agent"]}) |
| 304 | def neutron_metadata_relation(): |
| 305 | write_vrouter_config() |
| 306 | |
| 307 | + |
| 308 | @hooks.hook("neutron-plugin-relation-joined") |
| 309 | def neutron_plugin_joined(): |
| 310 | # create plugin config |
| 311 | section = [] |
| 312 | if version_compare(OPENSTACK_VERSION, "1:2015.1~") < 0: |
| 313 | if version_compare(OPENSTACK_VERSION, "1:2014.2") >= 0: |
| 314 | - section.append(("network_api_class", "nova_contrail_vif.contrailvif.ContrailNetworkAPI")) |
| 315 | + section.append(("network_api_class", |
| 316 | + "nova_contrail_vif.contrailvif" |
| 317 | + ".ContrailNetworkAPI")) |
| 318 | else: |
| 319 | - section.append(("libvirt_vif_driver", "nova_contrail_vif.contrailvif.VRouterVIFDriver")) |
| 320 | - section.append(("firewall_driver", "nova.virt.firewall.NoopFirewallDriver")) |
| 321 | + section.append(("libvirt_vif_driver", |
| 322 | + "nova_contrail_vif.contrailvif.VRouterVIFDriver")) |
| 323 | + section.append( |
| 324 | + ("firewall_driver", |
| 325 | + "nova.virt.firewall.NoopFirewallDriver")) |
| 326 | conf = { |
| 327 | - "nova-compute": { |
| 328 | - "/etc/nova/nova.conf": { |
| 329 | - "sections": { |
| 330 | - "DEFAULT": section |
| 331 | - } |
| 332 | + "nova-compute": { |
| 333 | + "/etc/nova/nova.conf": { |
| 334 | + "sections": { |
| 335 | + "DEFAULT": section |
| 336 | + } |
| 337 | + } |
| 338 | } |
| 339 | - } |
| 340 | } |
| 341 | relation_set(subordinate_configuration=json.dumps(conf)) |
| 342 | |
| 343 | if config["local-metadata-server"]: |
| 344 | - settings = { "metadata-shared-secret": config["local-metadata-secret"] } |
| 345 | + settings = {"metadata-shared-secret": config["local-metadata-secret"]} |
| 346 | relation_set(relation_settings=settings) |
| 347 | |
| 348 | + |
| 349 | +@hooks.hook('tls-certificates-relation-joined') |
| 350 | +def tls_certificates_relation_joined(): |
| 351 | + # a hostname could also be provided as a SAN |
| 352 | + # (Subject Alternative Name) but having this one |
| 353 | + # has certain implications |
| 354 | + # https://tools.ietf.org/html/rfc2818#section-3.1 |
| 355 | + # "If a subjectAltName extension of type dNSName |
| 356 | + # is present, that MUST be used as the identity" |
| 357 | + # Therefore it is not used here as we don't need |
| 358 | + # a DNS infrastructure dependency |
| 359 | + ip_san = control_network_ip() |
| 360 | + settings = { |
| 361 | + 'sans': json.dumps([ip_san, '127.0.0.1']), |
| 362 | + 'common_name': ip_san, |
| 363 | + 'certificate_name': local_unit().replace('/', '_') |
| 364 | + } |
| 365 | + relation_set(relation_settings=settings) |
| 366 | + |
| 367 | + |
| 368 | +@hooks.hook('tls-certificates-relation-changed') |
| 369 | +def tls_certificates_relation_changed(): |
| 370 | + # check that the -provides side have set the data we need |
| 371 | + # and render the affected files |
| 372 | + unitname = local_unit().replace('/', '_') |
| 373 | + cert = '{0}.server.cert'.format(unitname) |
| 374 | + key = '{0}.server.key'.format(unitname) |
| 375 | + certv = relation_get(cert) |
| 376 | + keyv = relation_get(key) |
| 377 | + ca = relation_get('ca') |
| 378 | + |
| 379 | + if certv and keyv and ca: |
| 380 | + write_xmpp_tls_files(certv, keyv, ca) |
| 381 | + config["tls-certificates-ready"] = True |
| 382 | + else: |
| 383 | + log('tls-certificates relation data is not fully available') |
| 384 | + config["tls-certificates-ready"] = False |
| 385 | + |
| 386 | + |
| 387 | +@hooks.hook('tls-certificates-relation-departed') |
| 388 | +def tls_certificates_relation_departed(): |
| 389 | + config["tls-certificates-ready"] = False |
| 390 | + |
| 391 | + |
| 392 | def main(): |
| 393 | try: |
| 394 | hooks.execute(sys.argv) |
| 395 | except UnregisteredHookError as e: |
| 396 | log("Unknown hook {} - skipping.".format(e)) |
| 397 | |
| 398 | + |
| 399 | @hooks.hook("upgrade-charm") |
| 400 | def upgrade_charm(): |
| 401 | write_vrouter_config() |
| 402 | @@ -351,12 +435,18 @@ |
| 403 | write_nodemgr_config() |
| 404 | service_restart("supervisor-vrouter") |
| 405 | |
| 406 | -@restart_on_change({"/etc/contrail/contrail-vrouter-agent.conf": ["contrail-vrouter-agent"], |
| 407 | - "/etc/contrail/contrail-vrouter-nodemgr.conf": ["contrail-vrouter-nodemgr"]}) |
| 408 | + |
| 409 | +@restart_on_change( |
| 410 | + { |
| 411 | + "/etc/contrail/contrail-vrouter-agent.conf": |
| 412 | + ["contrail-vrouter-agent"], |
| 413 | + "/etc/contrail/contrail-vrouter-nodemgr.conf": |
| 414 | + ["contrail-vrouter-nodemgr"]}) |
| 415 | def write_config(): |
| 416 | write_vrouter_config() |
| 417 | write_vnc_api_config() |
| 418 | write_nodemgr_config() |
| 419 | |
| 420 | + |
| 421 | if __name__ == "__main__": |
| 422 | main() |
| 423 | |
| 424 | === modified file 'hooks/neutron_contrail_utils.py' |
| 425 | --- hooks/neutron_contrail_utils.py 2017-03-10 12:57:45 +0000 |
| 426 | +++ hooks/neutron_contrail_utils.py 2017-03-26 17:44:17 +0000 |
| 427 | @@ -24,7 +24,9 @@ |
| 428 | relation_get, |
| 429 | relation_ids, |
| 430 | relation_type, |
| 431 | - remote_unit |
| 432 | + remote_unit, |
| 433 | + unit_private_ip, |
| 434 | + network_get_primary_address, |
| 435 | ) |
| 436 | |
| 437 | from charmhelpers.core.host import service_restart, service_start |
| 438 | @@ -33,17 +35,21 @@ |
| 439 | |
| 440 | apt_pkg.init() |
| 441 | |
| 442 | + |
| 443 | def dpkg_version(pkg): |
| 444 | try: |
| 445 | - return check_output(["dpkg-query", "-f", "${Version}\\n", "-W", pkg]).rstrip() |
| 446 | + return check_output( |
| 447 | + ["dpkg-query", "-f", "${Version}\\n", "-W", pkg]).rstrip() |
| 448 | except CalledProcessError: |
| 449 | return None |
| 450 | |
| 451 | + |
| 452 | CONTRAIL_VERSION = dpkg_version("contrail-vrouter-agent") |
| 453 | OPENSTACK_VERSION = dpkg_version("nova-compute") |
| 454 | |
| 455 | config = config() |
| 456 | |
| 457 | + |
| 458 | def retry(f=None, timeout=10, delay=2): |
| 459 | """Retry decorator. |
| 460 | |
| 461 | @@ -67,6 +73,7 @@ |
| 462 | """ |
| 463 | if not f: |
| 464 | return functools.partial(retry, timeout=timeout, delay=delay) |
| 465 | + |
| 466 | @functools.wraps(f) |
| 467 | def func(*args, **kwargs): |
| 468 | start = time() |
| 469 | @@ -87,6 +94,7 @@ |
| 470 | raise error |
| 471 | return func |
| 472 | |
| 473 | + |
| 474 | def configure_vrouter(): |
| 475 | # run external script to configure vrouter |
| 476 | args = ["./create-vrouter.sh"] |
| 477 | @@ -97,37 +105,43 @@ |
| 478 | args.append(iface) |
| 479 | check_call(args, cwd="scripts") |
| 480 | |
| 481 | + |
| 482 | def contrail_api_ctx(): |
| 483 | ip = config.get("contrail-api-ip") |
| 484 | if ip: |
| 485 | port = config.get("contrail-api-port") |
| 486 | - return { "api_server": ip, |
| 487 | - "api_port": port if port is not None else 8082 } |
| 488 | + return {"api_server": ip, |
| 489 | + "api_port": port if port is not None else 8082} |
| 490 | |
| 491 | - ctxs = [ { "api_server": gethostbyname(relation_get("private-address", unit, rid)), |
| 492 | - "api_port": port } |
| 493 | - for rid in relation_ids("contrail-api") |
| 494 | - for unit, port in |
| 495 | - ((unit, relation_get("port", unit, rid)) for unit in related_units(rid)) |
| 496 | - if port ] |
| 497 | + ctxs = [{"api_server": gethostbyname(relation_get("private-address", |
| 498 | + unit, rid)), |
| 499 | + "api_port": port} |
| 500 | + for rid in relation_ids("contrail-api") |
| 501 | + for unit, port in |
| 502 | + ((unit, relation_get("port", unit, rid)) |
| 503 | + for unit in related_units(rid)) |
| 504 | + if port] |
| 505 | return ctxs[0] if ctxs else {} |
| 506 | |
| 507 | + |
| 508 | def contrail_discovery_ctx(): |
| 509 | ip = config.get("discovery-server-ip") |
| 510 | if ip: |
| 511 | - return { "discovery_server": ip, |
| 512 | - "discovery_port": 5998 } |
| 513 | + return {"discovery_server": ip, |
| 514 | + "discovery_port": 5998} |
| 515 | |
| 516 | - ctxs = [ { "discovery_server": vip if vip \ |
| 517 | - else gethostbyname(relation_get("private-address", unit, rid)), |
| 518 | - "discovery_port": port } |
| 519 | - for rid in relation_ids("contrail-discovery") |
| 520 | - for unit, port, vip in |
| 521 | - ((unit, relation_get("port", unit, rid), relation_get("vip", unit, rid)) |
| 522 | - for unit in related_units(rid)) |
| 523 | - if port ] |
| 524 | + ctxs = [{"discovery_server": vip if vip |
| 525 | + else gethostbyname(relation_get("private-address", unit, rid)), |
| 526 | + "discovery_port": port} |
| 527 | + for rid in relation_ids("contrail-discovery") |
| 528 | + for unit, port, vip in |
| 529 | + ((unit, relation_get("port", unit, rid), |
| 530 | + relation_get("vip", unit, rid)) |
| 531 | + for unit in related_units(rid)) |
| 532 | + if port] |
| 533 | return ctxs[0] if ctxs else {} |
| 534 | |
| 535 | + |
| 536 | @retry(timeout=300) |
| 537 | def contrail_provision_linklocal(api_ip, api_port, service_name, service_ip, |
| 538 | service_port, fabric_ip, fabric_port, op, |
| 539 | @@ -144,6 +158,7 @@ |
| 540 | "--admin_user", user, |
| 541 | "--admin_password", password]) |
| 542 | |
| 543 | + |
| 544 | @retry(timeout=300) |
| 545 | def contrail_provision_vrouter(hostname, ip, api_ip, api_port, op, |
| 546 | user, password, tenant): |
| 547 | @@ -157,10 +172,13 @@ |
| 548 | "--admin_password", password, |
| 549 | "--admin_tenant_name", tenant]) |
| 550 | |
| 551 | + |
| 552 | def control_node_ctx(): |
| 553 | - return { "control_nodes": [ gethostbyname(relation_get("private-address", unit, rid)) |
| 554 | - for rid in relation_ids("control-node") |
| 555 | - for unit in related_units(rid) ] } |
| 556 | + return {"control_nodes": [gethostbyname(relation_get("control_node_ip", |
| 557 | + unit, rid)) |
| 558 | + for rid in relation_ids("control-node") |
| 559 | + for unit in related_units(rid)]} |
| 560 | + |
| 561 | |
| 562 | def disable_vrouter_vgw(): |
| 563 | if os.path.exists("/etc/sysctl.d/60-vrouter-vgw.conf"): |
| 564 | @@ -168,6 +186,7 @@ |
| 565 | os.remove("/etc/sysctl.d/60-vrouter-vgw.conf") |
| 566 | check_call(["sysctl", "-qw", "net.ipv4.ip_forward=0"]) |
| 567 | |
| 568 | + |
| 569 | def drop_caches(): |
| 570 | """Clears OS pagecache""" |
| 571 | log("Clearing pagecache") |
| 572 | @@ -175,25 +194,29 @@ |
| 573 | with open("/proc/sys/vm/drop_caches", "w") as f: |
| 574 | f.write("3\n") |
| 575 | |
| 576 | + |
| 577 | def enable_vrouter_vgw(): |
| 578 | if not os.path.exists("/etc/sysctl.d/60-vrouter-vgw.conf"): |
| 579 | # set sysctl options |
| 580 | shutil.copy("files/60-vrouter-vgw.conf", "/etc/sysctl.d") |
| 581 | service_start("procps") |
| 582 | |
| 583 | + |
| 584 | def fix_kexec_tools(): |
| 585 | if version_compare(CONTRAIL_VERSION, "3.2") >= 0: |
| 586 | # remove crashkernel grub entry |
| 587 | check_call(["sed", "-i", "-e", |
| 588 | - "s/^GRUB_CMDLINE_LINUX_DEFAULT=/#GRUB_CMDLINE_LINUX_DEFAULT=/", |
| 589 | + "s/^GRUB_CMDLINE_LINUX_DEFAULT=/" |
| 590 | + "#GRUB_CMDLINE_LINUX_DEFAULT=/", |
| 591 | "/etc/default/grub.d/kexec-tools.cfg"]) |
| 592 | check_call(["update-grub2"]) |
| 593 | |
| 594 | + |
| 595 | def fix_nodemgr(): |
| 596 | # add files missing from contrail-nodemgr package |
| 597 | dest = "/etc/contrail/supervisord_vrouter_files/" \ |
| 598 | - + ("contrail-vrouter-nodemgr.ini" \ |
| 599 | - if version_compare(CONTRAIL_VERSION, "3.1") >= 0 \ |
| 600 | + + ("contrail-vrouter-nodemgr.ini" |
| 601 | + if version_compare(CONTRAIL_VERSION, "3.1") >= 0 |
| 602 | else "contrail-nodemgr-vrouter.ini") |
| 603 | shutil.copy("files/contrail-nodemgr-vrouter.ini", dest) |
| 604 | pw = pwd.getpwnam("contrail") |
| 605 | @@ -208,14 +231,16 @@ |
| 606 | if version_compare(CONTRAIL_VERSION, "3.1") >= 0 \ |
| 607 | else "files/contrail-vrouter-nodemgr" |
| 608 | shutil.copy(src, "/etc/init.d/contrail-vrouter-nodemgr") |
| 609 | - os.chmod("/etc/init.d/contrail-vrouter-nodemgr", 0755) |
| 610 | + os.chmod("/etc/init.d/contrail-vrouter-nodemgr", 0o755) |
| 611 | |
| 612 | service_restart("supervisor-vrouter") |
| 613 | |
| 614 | + |
| 615 | def fix_permissions(): |
| 616 | - os.chmod("/etc/contrail", 0755) |
| 617 | + os.chmod("/etc/contrail", 0o755) |
| 618 | os.chown("/etc/contrail", 0, 0) |
| 619 | |
| 620 | + |
| 621 | def fix_vrouter_scripts(): |
| 622 | # certain files need to be present for packages |
| 623 | if not os.path.exists("/opt/contrail/bin"): |
| 624 | @@ -224,30 +249,36 @@ |
| 625 | os.symlink("/bin/true", "/opt/contrail/bin/vrouter-post-start.sh") |
| 626 | os.symlink("/bin/true", "/opt/contrail/bin/vrouter-pre-stop.sh") |
| 627 | |
| 628 | + |
| 629 | def identity_admin_ctx(): |
| 630 | - ctxs = [ { "auth_host": gethostbyname(hostname), |
| 631 | - "auth_port": relation_get("service_port", unit, rid), |
| 632 | - "auth_protocol": relation_get("service_protocol", unit, rid), |
| 633 | - "admin_user": relation_get("service_username", unit, rid), |
| 634 | - "admin_password": relation_get("service_password", unit, rid), |
| 635 | - "admin_tenant_name": relation_get("service_tenant_name", unit, rid), |
| 636 | - "auth_region": relation_get("service_region", unit, rid) } |
| 637 | - for rid in relation_ids("identity-admin") |
| 638 | - for unit, hostname in |
| 639 | - ((unit, relation_get("service_hostname", unit, rid)) for unit in related_units(rid)) |
| 640 | - if hostname ] |
| 641 | + ctxs = [{"auth_host": gethostbyname(hostname), |
| 642 | + "auth_port": relation_get("service_port", unit, rid), |
| 643 | + "auth_protocol": relation_get("service_protocol", unit, rid), |
| 644 | + "admin_user": relation_get("service_username", unit, rid), |
| 645 | + "admin_password": relation_get("service_password", unit, rid), |
| 646 | + "admin_tenant_name": relation_get("service_tenant_name", |
| 647 | + unit, rid), |
| 648 | + "auth_region": relation_get("service_region", unit, rid)} |
| 649 | + for rid in relation_ids("identity-admin") |
| 650 | + for unit, hostname in |
| 651 | + ((unit, relation_get("service_hostname", unit, rid)) |
| 652 | + for unit in related_units(rid)) |
| 653 | + if hostname] |
| 654 | return ctxs[0] if ctxs else {} |
| 655 | |
| 656 | + |
| 657 | def ifdown(interfaces=None): |
| 658 | """ifdown an interface or all interfaces""" |
| 659 | log("Taking down {}".format(interfaces if interfaces else "interfaces")) |
| 660 | check_call(["ifdown"] + interfaces if interfaces else ["-a"]) |
| 661 | |
| 662 | + |
| 663 | def ifup(interfaces=None): |
| 664 | """ifup an interface or all interfaces""" |
| 665 | log("Bringing up {}".format(interfaces if interfaces else "interfaces")) |
| 666 | check_call(["ifup"] + interfaces if interfaces else ["-a"]) |
| 667 | |
| 668 | + |
| 669 | def lsmod(module): |
| 670 | """Check if a kernel module is loaded""" |
| 671 | with open("/proc/modules", "r") as modules: |
| 672 | @@ -256,6 +287,7 @@ |
| 673 | return True |
| 674 | return False |
| 675 | |
| 676 | + |
| 677 | def modprobe(module, auto_load=False, dkms_autoinstall=False): |
| 678 | """Load a kernel module. |
| 679 | |
| 680 | @@ -287,19 +319,23 @@ |
| 681 | log("DKMS auto installing for kernel {}".format(kernel)) |
| 682 | check_call(["dkms", "autoinstall", "-k", kernel]) |
| 683 | |
| 684 | + |
| 685 | def network_ctx(): |
| 686 | iface = config.get("control-interface") |
| 687 | - return { "control_network_ip": netifaces.ifaddresses(iface)[netifaces.AF_INET][0]["addr"] } |
| 688 | + return {"control_network_ip": netifaces.ifaddresses( |
| 689 | + iface)[netifaces.AF_INET][0]["addr"]} |
| 690 | + |
| 691 | |
| 692 | def neutron_metadata_ctx(): |
| 693 | if "local-metadata-secret" in config: |
| 694 | - return { "metadata_secret": config["local-metadata-secret"] } |
| 695 | + return {"metadata_secret": config["local-metadata-secret"]} |
| 696 | |
| 697 | - ctxs = [ { "metadata_secret": relation_get("shared-secret", unit, rid) } |
| 698 | - for rid in relation_ids("neutron-metadata") |
| 699 | - for unit in related_units(rid) ] |
| 700 | + ctxs = [{"metadata_secret": relation_get("shared-secret", unit, rid)} |
| 701 | + for rid in relation_ids("neutron-metadata") |
| 702 | + for unit in related_units(rid)] |
| 703 | return ctxs[0] if ctxs else {} |
| 704 | |
| 705 | + |
| 706 | def provision_local_metadata(): |
| 707 | api_port = None |
| 708 | api_ip = config.get("contrail-api-ip") |
| 709 | @@ -308,22 +344,25 @@ |
| 710 | if api_port is None: |
| 711 | api_port = 8082 |
| 712 | else: |
| 713 | - api_ip, api_port = [ (gethostbyname(relation_get("private-address", unit, rid)), |
| 714 | - port) |
| 715 | - for rid in relation_ids("contrail-api") |
| 716 | - for unit, port in |
| 717 | - ((unit, relation_get("port", unit, rid)) for unit in related_units(rid)) |
| 718 | - if port ][0] |
| 719 | - user, password = [ (relation_get("service_username", unit, rid), |
| 720 | - relation_get("service_password", unit, rid)) |
| 721 | - for rid in relation_ids("identity-admin") |
| 722 | - for unit in related_units(rid) |
| 723 | - if relation_get("service_hostname", unit, rid) ][0] |
| 724 | + api_ip, api_port = [(gethostbyname(relation_get("private-address", |
| 725 | + unit, rid)), |
| 726 | + port) |
| 727 | + for rid in relation_ids("contrail-api") |
| 728 | + for unit, port in |
| 729 | + ((unit, relation_get("port", unit, rid)) |
| 730 | + for unit in related_units(rid)) |
| 731 | + if port][0] |
| 732 | + user, password = [(relation_get("service_username", unit, rid), |
| 733 | + relation_get("service_password", unit, rid)) |
| 734 | + for rid in relation_ids("identity-admin") |
| 735 | + for unit in related_units(rid) |
| 736 | + if relation_get("service_hostname", unit, rid)][0] |
| 737 | log("Provisioning local metadata service 127.0.0.1:8775") |
| 738 | contrail_provision_linklocal(api_ip, api_port, "metadata", |
| 739 | "169.254.169.254", 80, "127.0.0.1", 8775, |
| 740 | "add", user, password) |
| 741 | |
| 742 | + |
| 743 | def provision_vrouter(): |
| 744 | hostname = gethostname() |
| 745 | ip = netifaces.ifaddresses("vhost0")[netifaces.AF_INET][0]["addr"] |
| 746 | @@ -334,26 +373,30 @@ |
| 747 | if api_port is None: |
| 748 | api_port = 8082 |
| 749 | else: |
| 750 | - api_ip, api_port = [ (gethostbyname(relation_get("private-address", unit, rid)), |
| 751 | - port) |
| 752 | - for rid in relation_ids("contrail-api") |
| 753 | - for unit, port in |
| 754 | - ((unit, relation_get("port", unit, rid)) for unit in related_units(rid)) |
| 755 | - if port ][0] |
| 756 | - user, password, tenant = [ (relation_get("service_username", unit, rid), |
| 757 | - relation_get("service_password", unit, rid), |
| 758 | - relation_get("service_tenant_name", unit, rid)) |
| 759 | - for rid in relation_ids("identity-admin") |
| 760 | - for unit in related_units(rid) |
| 761 | - if relation_get("service_hostname", unit, rid) ][0] |
| 762 | + api_ip, api_port = [(gethostbyname(relation_get("private-address", |
| 763 | + unit, rid)), port) |
| 764 | + for rid in relation_ids("contrail-api") |
| 765 | + for unit, port in |
| 766 | + ((unit, relation_get("port", unit, rid)) |
| 767 | + for unit in related_units(rid)) |
| 768 | + if port][0] |
| 769 | + user, password, tenant = [(relation_get("service_username", unit, rid), |
| 770 | + relation_get("service_password", unit, rid), |
| 771 | + relation_get("service_tenant_name", unit, rid)) |
| 772 | + for rid in relation_ids("identity-admin") |
| 773 | + for unit in related_units(rid) |
| 774 | + if relation_get("service_hostname", |
| 775 | + unit, rid)][0] |
| 776 | log("Provisioning vrouter {}".format(ip)) |
| 777 | contrail_provision_vrouter(hostname, ip, api_ip, api_port, "add", |
| 778 | user, password, tenant) |
| 779 | |
| 780 | + |
| 781 | def units(relation): |
| 782 | """Return a list of units for the specified relation""" |
| 783 | - return [ unit for rid in relation_ids(relation) |
| 784 | - for unit in related_units(rid) ] |
| 785 | + return [unit for rid in relation_ids(relation) |
| 786 | + for unit in related_units(rid)] |
| 787 | + |
| 788 | |
| 789 | def unprovision_local_metadata(): |
| 790 | relation = relation_type() |
| 791 | @@ -369,20 +412,21 @@ |
| 792 | api_ip = gethostbyname(relation_get("private-address")) |
| 793 | api_port = relation_get("port") |
| 794 | else: |
| 795 | - api_ip, api_port = [ (gethostbyname(relation_get("private-address", unit, rid)), |
| 796 | - relation_get("port", unit, rid)) |
| 797 | - for rid in relation_ids("contrail-api") |
| 798 | - for unit in related_units(rid) ][0] |
| 799 | + api_ip, api_port = [(gethostbyname(relation_get("private-address", |
| 800 | + unit, rid)), |
| 801 | + relation_get("port", unit, rid)) |
| 802 | + for rid in relation_ids("contrail-api") |
| 803 | + for unit in related_units(rid)][0] |
| 804 | user = None |
| 805 | password = None |
| 806 | if relation == "identity-admin": |
| 807 | user = relation_get("service_username") |
| 808 | password = relation_get("service_password") |
| 809 | else: |
| 810 | - user, password = [ (relation_get("service_username", unit, rid), |
| 811 | - relation_get("service_password", unit, rid)) |
| 812 | - for rid in relation_ids("identity-admin") |
| 813 | - for unit in related_units(rid) ][0] |
| 814 | + user, password = [(relation_get("service_username", unit, rid), |
| 815 | + relation_get("service_password", unit, rid)) |
| 816 | + for rid in relation_ids("identity-admin") |
| 817 | + for unit in related_units(rid)][0] |
| 818 | log("Unprovisioning local metadata service 127.0.0.1:8775") |
| 819 | try: |
| 820 | contrail_provision_linklocal(api_ip, api_port, "metadata", |
| 821 | @@ -391,6 +435,7 @@ |
| 822 | except CalledProcessError: |
| 823 | pass |
| 824 | |
| 825 | + |
| 826 | def unprovision_vrouter(): |
| 827 | relation = relation_type() |
| 828 | if relation and not remote_unit(): |
| 829 | @@ -407,10 +452,11 @@ |
| 830 | api_ip = gethostbyname(relation_get("private-address")) |
| 831 | api_port = relation_get("port") |
| 832 | else: |
| 833 | - api_ip, api_port = [ (gethostbyname(relation_get("private-address", unit, rid)), |
| 834 | - relation_get("port", unit, rid)) |
| 835 | - for rid in relation_ids("contrail-api") |
| 836 | - for unit in related_units(rid) ][0] |
| 837 | + api_ip, api_port = [(gethostbyname(relation_get("private-address", |
| 838 | + unit, rid)), |
| 839 | + relation_get("port", unit, rid)) |
| 840 | + for rid in relation_ids("contrail-api") |
| 841 | + for unit in related_units(rid)][0] |
| 842 | user = None |
| 843 | password = None |
| 844 | tenant = None |
| 845 | @@ -419,11 +465,12 @@ |
| 846 | password = relation_get("service_password") |
| 847 | tenant = relation_get("service_tenant_name") |
| 848 | else: |
| 849 | - user, password, tenant = [ (relation_get("service_username", unit, rid), |
| 850 | - relation_get("service_password", unit, rid), |
| 851 | - relation_get("service_tenant_name", unit, rid)) |
| 852 | - for rid in relation_ids("identity-admin") |
| 853 | - for unit in related_units(rid) ][0] |
| 854 | + user, password, tenant = [(relation_get("service_username", unit, rid), |
| 855 | + relation_get("service_password", unit, rid), |
| 856 | + relation_get("service_tenant_name", |
| 857 | + unit, rid)) |
| 858 | + for rid in relation_ids("identity-admin") |
| 859 | + for unit in related_units(rid)][0] |
| 860 | log("Unprovisioning vrouter {}".format(ip)) |
| 861 | try: |
| 862 | contrail_provision_vrouter(hostname, ip, api_ip, api_port, "del", |
| 863 | @@ -431,6 +478,7 @@ |
| 864 | except CalledProcessError: |
| 865 | pass |
| 866 | |
| 867 | + |
| 868 | def vhost_gateway(): |
| 869 | # determine vhost gateway |
| 870 | gateway = config.get("vhost-gateway") |
| 871 | @@ -442,6 +490,7 @@ |
| 872 | gateway = None |
| 873 | return gateway |
| 874 | |
| 875 | + |
| 876 | def vhost_ip(iface): |
| 877 | # return a vhost formatted address and mask - x.x.x.x/xx |
| 878 | addr = netifaces.ifaddresses(iface)[netifaces.AF_INET][0] |
| 879 | @@ -449,14 +498,17 @@ |
| 880 | cidr = netaddr.IPNetwork(ip + "/" + addr["netmask"]).prefixlen |
| 881 | return ip + "/" + str(cidr) |
| 882 | |
| 883 | + |
| 884 | def vhost_phys(): |
| 885 | # run external script to determine physical interface of vhost0 |
| 886 | return check_output(["scripts/vhost-phys.sh"]).rstrip() |
| 887 | |
| 888 | + |
| 889 | def vrouter_ctx(): |
| 890 | - return { "vhost_ip": vhost_ip("vhost0"), |
| 891 | - "vhost_gateway": vhost_gateway(), |
| 892 | - "vhost_physical": vhost_phys() } |
| 893 | + return {"vhost_ip": vhost_ip("vhost0"), |
| 894 | + "vhost_gateway": vhost_gateway(), |
| 895 | + "vhost_physical": vhost_phys()} |
| 896 | + |
| 897 | |
| 898 | def vrouter_vgw_ctx(): |
| 899 | ctx = {} |
| 900 | @@ -467,23 +519,27 @@ |
| 901 | ctx["vgws"] = vgws |
| 902 | return ctx |
| 903 | |
| 904 | + |
| 905 | def write_barbican_auth_config(): |
| 906 | ctx = identity_admin_ctx() |
| 907 | render("contrail-lbaas-auth.conf", |
| 908 | "/etc/contrail/contrail-lbaas-auth.conf", ctx, "root", "contrail", |
| 909 | - 0440) |
| 910 | + 0o440) |
| 911 | + |
| 912 | |
| 913 | def write_nodemgr_config(): |
| 914 | ctx = contrail_discovery_ctx() |
| 915 | render("contrail-vrouter-nodemgr.conf", |
| 916 | "/etc/contrail/contrail-vrouter-nodemgr.conf", ctx) |
| 917 | |
| 918 | + |
| 919 | def write_vnc_api_config(): |
| 920 | ctx = {} |
| 921 | ctx.update(contrail_api_ctx()) |
| 922 | ctx.update(identity_admin_ctx()) |
| 923 | render("vnc_api_lib.ini", "/etc/contrail/vnc_api_lib.ini", ctx) |
| 924 | |
| 925 | + |
| 926 | def write_vrouter_config(): |
| 927 | ctx = {} |
| 928 | ctx.update(control_node_ctx()) |
| 929 | @@ -492,9 +548,58 @@ |
| 930 | ctx.update(network_ctx()) |
| 931 | ctx.update(vrouter_ctx()) |
| 932 | ctx.update(vrouter_vgw_ctx()) |
| 933 | + |
| 934 | + # a tls-certificates guard here is for the upgrade scenario |
| 935 | + tls_implemented = version_compare(CONTRAIL_VERSION, "3.0") >= 0 and\ |
| 936 | + config.get("tls-certificates-ready") |
| 937 | + ctx.update({'tls_implemented': tls_implemented}) |
| 938 | render("contrail-vrouter-agent.conf", |
| 939 | - "/etc/contrail/contrail-vrouter-agent.conf", ctx, perms=0440) |
| 940 | + "/etc/contrail/contrail-vrouter-agent.conf", ctx, perms=0o440) |
| 941 | + |
| 942 | |
| 943 | def write_vrouter_vgw_interfaces(): |
| 944 | ctx = vrouter_vgw_ctx() |
| 945 | render("vrouter-vgw.cfg", "/etc/network/interfaces.d/vrouter-vgw.cfg", ctx) |
| 946 | + |
| 947 | + |
| 948 | +def control_network_ip(): |
| 949 | + ''' |
| 950 | + With Juju 2.x, uses an endpoint (relation) |
| 951 | + network space binding if unspecified will use a "unit private address" |
| 952 | + which is far less explicit if you look at the Juju implementation. |
| 953 | + If you use Juju 2.x and above - bind the control-node endpoint to a network |
| 954 | + space to get a proper address in this function. |
| 955 | + |
| 956 | + If network-get throws an exception (juju 1.x or spaces are not supported) |
| 957 | + will try to fall back to a private-address as returned by Juju. |
| 958 | + ''' |
| 959 | + try: |
| 960 | + address = network_get_primary_address('control-node') |
| 961 | + except NotImplementedError: |
| 962 | + log('Network spaces are not implemented - falling back to' |
| 963 | + ' getting a private address') |
| 964 | + address = unit_private_ip() |
| 965 | + return address |
| 966 | + |
| 967 | + |
| 968 | +def write_xmpp_tls_files(serv_cert, priv_key, ca): |
| 969 | + prefix = '/etc/contrail/ssl' |
| 970 | + certs = os.path.join(prefix, 'certs') |
| 971 | + private = os.path.join(prefix, 'private') |
| 972 | + |
| 973 | + entry = pwd.getpwnam('contrail') |
| 974 | + for p in [prefix, certs, private]: |
| 975 | + if not os.path.exists(p): |
| 976 | + os.makedirs(p, 0o750) |
| 977 | + os.chown(p, entry.pw_uid, entry.pw_gid) |
| 978 | + |
| 979 | + fcontent = { |
| 980 | + os.path.join(certs, 'server.pem'): serv_cert, |
| 981 | + os.path.join(private, 'server-privkey.pem'): priv_key, |
| 982 | + os.path.join(certs, 'ca-cert.pem'): ca, |
| 983 | + } |
| 984 | + |
| 985 | + for filepath, content in fcontent.iteritems(): |
| 986 | + with open(filepath, 'w+') as f: |
| 987 | + f.truncate(0) |
| 988 | + f.write(content) |
| 989 | |
| 990 | === added symlink 'hooks/tls-certificates-relation-changed' |
| 991 | === target is u'neutron_contrail_hooks.py' |
| 992 | === added symlink 'hooks/tls-certificates-relation-departed' |
| 993 | === target is u'neutron_contrail_hooks.py' |
| 994 | === added symlink 'hooks/tls-certificates-relation-joined' |
| 995 | === target is u'neutron_contrail_hooks.py' |
| 996 | === modified file 'metadata.yaml' |
| 997 | --- metadata.yaml 2015-10-13 11:03:57 +0000 |
| 998 | +++ metadata.yaml 2017-03-26 17:44:17 +0000 |
| 999 | @@ -37,3 +37,5 @@ |
| 1000 | interface: keystone-admin |
| 1001 | neutron-metadata: |
| 1002 | interface: neutron-metadata |
| 1003 | + tls-certificates: |
| 1004 | + interface: tls-certificates |
| 1005 | |
| 1006 | === modified file 'templates/contrail-vrouter-agent.conf' |
| 1007 | --- templates/contrail-vrouter-agent.conf 2016-02-05 00:31:01 +0000 |
| 1008 | +++ templates/contrail-vrouter-agent.conf 2017-03-26 17:44:17 +0000 |
| 1009 | @@ -3,6 +3,15 @@ |
| 1010 | # Configuration file maintained by Juju. Local changes may be overwritten. |
| 1011 | ############################################################################### |
| 1012 | |
| 1013 | + |
| 1014 | +{% if tls_implemented -%} |
| 1015 | +[DEFAULT] |
| 1016 | +xmpp_auth_enable=true |
| 1017 | +xmpp_server_cert=/etc/contrail/ssl/certs/server.pem |
| 1018 | +xmpp_server_key=/etc/contrail/ssl/private/server-privkey.pem |
| 1019 | +xmpp_ca_cert=/etc/contrail/ssl/certs/ca-cert.pem |
| 1020 | +{% endif -%} |
| 1021 | + |
| 1022 | {%- if control_nodes %} |
| 1023 | |
| 1024 | [CONTROL-NODE] |
Note: easyrsa charm should be used for PKI https:/ /jujucharms. com/u/container s/easyrsa/
juju add-relation contrail-control easyrsa
juju add-relation neutron-contrail easyrsa