Add policy based routing to `caas_oam` network
[ta/infra-ansible.git] / roles / baremetal_interface_config / templates / os_net_config.j2
1 #jinja2: lstrip_blocks: True
2 {#
3 This file is written with conditional check and for loop based indentation.
4 It improved code readability. The output json is not pretty. Run cat <output.json> | python -m json.tool
5 for pretty printing the same.
6 #}
7
8 {%- set CLOUD_TENANT = 'cloud_tenant' %}
9 {%- set VXLAN_HDR_LEN = 50 %}
10
11 {#- initialize some variables -#}
12 {%- set host_networking = hostvars[ansible_hostname]['networking'] %}
13 {%- if 'mtu' in host_networking %}
14     {%- set default_mtu = host_networking['mtu'] %}
15 {%- else %}
16     {%- set default_mtu = 1500 %}
17 {%- endif %}
18 {%- set max_mtu = 9000 %}
19 {%- set host_network_profiles_list = hosts[ansible_hostname]['network_profiles'] %}
20 {%- set host_network_profile_value = hostvars[ansible_hostname]['network_profiles'][host_network_profiles_list[0]] %}
21 {%- set host_interface_net_mapping = host_network_profile_value['interface_net_mapping'] %}
22 {%- if 'bonding_interfaces' in host_network_profile_value %}
23     {%- set host_bonding_interfaces = host_network_profile_value['bonding_interfaces'] %}
24 {%- else %}
25     {%- set host_bonding_interfaces = {} %}
26 {%- endif %}
27 {%- set single_nic_setup = False %}
28 {%- if 'provider_network_interfaces' in host_network_profile_value %}
29     {%- set host_provider_network_interfaces = host_network_profile_value['provider_network_interfaces'] %}
30     {%- set dpdk_in_use = ((host_provider_network_interfaces.itervalues()|first).type == 'ovs-dpdk') %}
31
32     {%- if host_interface_net_mapping|length == 1 and host_provider_network_interfaces|length == 1 %}
33         {%- if host_interface_net_mapping.keys()[0] == host_provider_network_interfaces.keys()[0] %}
34             {%- set single_nic_setup = True %}
35             {%- if CLOUD_TENANT in host_networking.keys() and 'interface' in host_networking[CLOUD_TENANT] %}
36                 {%- set mtu = default_mtu %}
37                 {%- if 'mtu' in host_networking[CLOUD_TENANT] %}
38                     {%- set mtu = host_networking[CLOUD_TENANT]['mtu'] %}
39                 {%- endif %}
40                 {%- set mtu = mtu + VXLAN_HDR_LEN %}
41                 {%- if mtu > max_mtu %}
42                     {%- set max_mtu = mtu %}
43                 {%- endif %}
44             {%- endif %}
45         {%-endif %}
46     {%-endif %}
47
48     {#- make a list of ixgbe devices, needed in ovs-dpdk configuration -#}
49     {%- set ixgbedevs = [] %}
50     {%- for key in hostvars[ansible_hostname].keys() %}
51         {%- if key.startswith('ansible_') %}
52             {%- set value = hostvars[ansible_hostname][key] %}
53             {%- if value is iterable and 'device' in value and 'module' in value and value['module'] == 'ixgbe' %}
54                 {%- if ixgbedevs.append(value['device']) %}{%- endif %}
55             {%- endif %}
56         {%- endif %}
57     {%- endfor %}
58 {%- else %}
59     {%- set host_provider_network_interfaces = {} %}
60     {%- set dpdk_in_use = False %}
61 {%- endif %}
62 {%- set sriov_mtus = {} %}
63 {%- if 'sriov_provider_networks' in host_network_profile_value %}
64     {%- for net,iface_info in host_network_profile_value['sriov_provider_networks'].iteritems() %}
65         {%- for tmp,mtu_info in host_networking['provider_networks'].iteritems() if tmp == net %}
66             {%- if 'mtu' in mtu_info %}{% set mtu = mtu_info['mtu'] %}{% else %}{% set mtu = default_mtu %}{% endif %}
67             {%- for iface in iface_info['interfaces'] %}
68                 {%- if sriov_mtus.update({iface: mtu}) %}{%- endif %}
69             {%- endfor %}
70         {%- endfor %}
71     {%- endfor %}
72 {%- endif %}
73 {%- set external_ceph_cidr = None %}
74 {%- if config_phase != 'setup' and 'external_ceph' in storage['backends'] %}
75     {%- set ext_ceph = storage['backends']['external_ceph'] %}
76     {%- if 'enabled' in ext_ceph and 'cidr' in ext_ceph and ext_ceph['enabled'] %}
77         {%- set external_ceph_cidr = ext_ceph['cidr'] %}
78     {%- endif %}
79 {%- endif %}
80
81 {% macro generate_linux_bonding_options(options) -%}
82     {%- set mode_mapping = {'active-backup' : 'active-backup', 'lacp' : '802.3ad'} -%}
83     {%- set default_options = {
84                                 'active-backup' : 'miimon=100',
85                                 'lacp' : 'lacp_rate=fast miimon=100'
86                               } -%}
87     {%- for i in options.split() -%}
88         {%- set key, value = i.split('=') -%}
89         {%- if key == 'mode' -%}
90             {%- if default_options[value] -%}
91                 {{ 'mode=' ~ mode_mapping[value] ~ ' ' ~ default_options[value] }}
92             {%- else -%}
93                 {{ 'mode=' ~ mode_mapping[value] }}
94             {%- endif -%}
95         {%- endif -%}
96     {%- endfor -%}
97 {%- endmacro %}
98
99 {% macro generate_ovs_bonding_options(options) -%}
100     {%- set mode_mapping = {'active-backup' : 'active-backup', 'lacp' : 'balance-slb', 'lacp-layer34' : 'balance-tcp'} -%}
101     {%- set default_options = {
102                                 'active-backup' : '',
103                                 'lacp' : 'lacp=active other_config:lacp-time=fast other_config:bond-detect-mode=carrier',
104                                 'lacp-layer34' : 'lacp=active other_config:lacp-time=fast other_config:bond-detect-mode=carrier'
105                               } -%}
106     {%- for i in options.split() -%}
107         {%- set key, value = i.split('=') -%}
108         {%- if key == 'mode' -%}
109             {%- if default_options[value] -%}
110                 {{ 'bond_mode=' ~ mode_mapping[value] ~ ' ' ~ default_options[value] }}
111             {%- else -%}
112                 {{ 'bond_mode=' ~ mode_mapping[value] }}
113             {%- endif -%}
114         {%- endif -%}
115     {%- endfor -%}
116 {%- endmacro %}
117
118 {% macro add_static_routes(routes) -%}
119     [
120     {%- for route in routes %}
121         {
122             "ip_netmask": "{{ route.to }}", "next_hop": "{{ route.via }}"
123             {%- if route.table is defined %}, "table": "{{ route.table }}"{% endif %}
124         } {% if not loop.last %},{% endif %}
125     {%- endfor %}
126     ]
127 {%- endmacro %}
128
129 {#- create network configuration input for the os-net-config -#}
130 {
131 "network_config": [
132 {%- set loopvar = {'first_entry': True} %}
133 {%- set configured_phys_ifaces = [] %}
134
135 {#- single nic ifra networks are configured with the ovs provider networks -#}
136 {%- if not single_nic_setup %}
137
138 {#-
139 If all infra ifaces on some phys iface are vlan ifaces then phys iface is configured here.
140 Otherwise it gets configured normally on infra iface configuration in the next loop.
141 -#}
142 {%- for iface,infras in host_interface_net_mapping.iteritems() %}
143     {%- set ifacevars = {'create': True, 'mtu': 0} %}
144     {%- for infra,value in host_networking.iteritems() %}
145         {%- if infra in infras %}
146             {%- if value['interface'] == iface %}
147                 {%- if ifacevars.update({'create': False}) %}{%- endif %}
148             {%- else %}
149                 {%- if 'mtu' in value %}
150                     {%- set mtu = value['mtu'] %}
151                 {%- else %}
152                     {%- set mtu = default_mtu %}
153                 {%- endif %}
154                 {%- if infra == CLOUD_TENANT %}
155                     {%- set mtu = mtu + VXLAN_HDR_LEN %}
156                 {%- endif %}
157                 {%- if mtu > ifacevars.mtu %}
158                     {%- if ifacevars.update({'mtu': mtu}) %}{%- endif %}
159                 {%- endif %}
160             {%- endif %}
161         {%- endif %}
162     {%- endfor %}
163     {%- if 'bond' in iface %}
164         {%- for key,slaves in host_bonding_interfaces.iteritems() if key == iface %}
165             {%- for slave in slaves %}
166                 {%- if slave in sriov_mtus and sriov_mtus[slave] > ifacevars.mtu %}
167                     {%- if ifacevars.update({'mtu': sriov_mtus[slave]}) %}{%- endif %}
168                 {%- endif %}
169             {%- endfor %}
170         {%- endfor %}
171     {%- else %}
172         {%- if iface in sriov_mtus and sriov_mtus[iface] > ifacevars.mtu %}
173             {%- if ifacevars.update({'mtu': sriov_mtus[iface]}) %}{%- endif %}
174         {%- endif %}
175     {%- endif %}
176     {%- if ifacevars.create %}
177         {%- if not loopvar.first_entry %},{%- endif %}
178         {%- if loopvar.update({'first_entry': False}) %}{%- endif %}
179         {
180             "name": "{{iface}}",
181             {%- if 'bond' in iface %}
182                 {%- for key,slaves in host_bonding_interfaces.iteritems() if key == iface %}
183                     "type": "linux_bond",
184                     "mtu": {{ifacevars['mtu']}},
185                     {%- if 'linux_bonding_options' in  host_network_profile_value %}
186                         "bonding_options": "{{ generate_linux_bonding_options(host_network_profile_value['linux_bonding_options']) }}",
187                     {%- endif %}
188                     "members": [ {% for slave in slaves %}
189                         {%- if configured_phys_ifaces.append(slave) %}{%- endif %}
190                         {
191                         "name": "{{slave}}",
192                         "type": "interface",
193                         "mtu": {{ifacevars['mtu']}},
194                         "use_dhcp": false
195                         }
196                         {% if not loop.last %},{% endif %}
197                     {%- endfor %}
198                     ],
199                 {%- endfor %}
200             {%- else %}
201                 {%- if configured_phys_ifaces.append(iface) %}{%- endif %}
202                 "type": "interface",
203             {%- endif %}
204             "mtu": {{ifacevars['mtu']}},
205             "use_dhcp": false
206         }
207     {%- endif %}
208 {%- endfor %}
209
210 {#- configure all infra ifaces (except cloud_tenant if ovs-dpdk in use) -#}
211 {%- for key,value in host_networking.iteritems() %}
212     {%- if value is iterable and 'interface' in value %}
213         {%- if key != CLOUD_TENANT or not dpdk_in_use %}{#- no dpdk or no cloud tenant -#}
214         {%- if 'mtu' in value %}{% set mtu = value['mtu'] %}{% else %}{% set mtu = default_mtu %}{% endif %}
215         {%- if key == CLOUD_TENANT %}{% set mtu = mtu + VXLAN_HDR_LEN %}{% endif %}
216         {%- if not loopvar.first_entry %},{%- endif %}
217         {%- if loopvar.update({'first_entry': False}) %}{%- endif %}
218         {
219         {%- if 'bond' in value['interface'] %}
220             {%- for bond_key,bond_value in host_bonding_interfaces.iteritems() if bond_key == value['interface'] %}
221                 "name": "{{bond_key}}",
222                 "type": "linux_bond",
223                 "members": [ {% for member in bond_value %}
224                     {%- if configured_phys_ifaces.append(member) %}{%- endif %}
225                     {
226                     "name": "{{ member }}",
227                     "type": "interface",
228                     "mtu": {{mtu}},
229                     "use_dhcp": false
230                     }
231                     {% if not loop.last %},{% endif %}
232                 {%- endfor %}
233                 ],
234                 {%- if 'linux_bonding_options' in  host_network_profile_value %}
235                     "bonding_options": "{{ generate_linux_bonding_options(host_network_profile_value['linux_bonding_options']) }}",
236                 {%- endif %}
237             {%- endfor %}
238         {%- elif 'vlan' in value %}
239             "type": "vlan",
240             "vlan_id": {{ value['vlan'] }},
241             {%- for net_key,net_value in host_interface_net_mapping.iteritems() %}
242                 {%- if key in net_value %}
243                     "device": "{{net_key}}",
244                 {%- endif %}
245             {%- endfor %}
246         {%- else %}
247             {%- if configured_phys_ifaces.append(value['interface']) %}{%- endif %}
248             "name": "{{value['interface']}}",
249             "type": "interface",
250         {%- endif %}
251             "addresses": [ { "ip_netmask": "{{ value['ip'] }}/{{value['mask']}}" } ],
252             "mtu": {{mtu}},
253             {%- if (key == "infra_external" or key == "infra_access")
254                     and 'dns' in host_networking
255                     and (ansible_hostname not in groups.get('caas_nodes', [])) %}
256                 "dns_servers": [{% for server in host_networking['dns'] %}"{{ server }}"{% if not loop.last %},{% endif %}{% endfor %}],
257             {%- endif %}
258             {%- set routes = [] %}
259             {%- if 'routes' in value %}
260                 {%- set routes = value['routes'] %}
261             {%- endif %}
262             {%- if config_phase not in ('setup', 'bootstrapping') -%}
263                 {% if 'gateway' in value %}
264                     {%- set caas_oam_gw =  value['gateway'] %}
265                 {% else %}
266                     {# Fall back to most popular self IP as gateway #}
267                     {%- set caas_oam_gw =  value['cidr'] | ipaddr(1) | ipaddr('address') %}
268                 {% endif %}
269                 {%- set caas_oam_route = {
270                     "to": '0.0.0.0/0', "via": caas_oam_gw,
271                     "table": caas_oam_routing_table_name} %}
272                 {%- if key == 'caas_oam' %}
273                     {%- set _ = routes.append(caas_oam_route) %}
274                 {%- elif key == 'infra_internal' %}
275                     {% set bound_host_networks = [] %}
276                     {% for host_networks in (host_interface_net_mapping.keys() | map('extract', host_interface_net_mapping)| list) %}
277                         {% set _ = bound_host_networks.extend(host_networks) %}
278                     {% endfor %}
279                     {%- if 'caas_oam' not in bound_host_networks %}
280                         {%- set _ = routes.append(caas_oam_route) %}
281                     {%- endif %}
282                     {%- set caas_oam_internal_route = {
283                         "to": value['cidr'], "via": value['ip'],
284                         "table": caas_oam_routing_table_name} %}
285                     {%- set _ = routes.append(caas_oam_internal_route) %}
286                 {% endif %}
287             {%- endif -%}
288             {%- if key == 'infra_external' and 'gateway' in value %}
289                 {%- if '.' in value['gateway'] %}
290                     {% set defaultroute = '0.0.0.0/0'%}
291                 {%- else %}
292                     {% set defaultroute = '::/0'%}
293                 {%- endif %}
294                 {%- set gw = {"to": defaultroute, "via": value['gateway']} %}
295                 {%- if routes.append(gw) %}{%- endif %}
296             {%- endif %}
297             {%- if key == 'infra_access' and 'gateway' in value %}
298                 {%- if 'dns' in host_networking %}
299                     {%- if '.' in value['gateway'] %}
300                         {% set mask = '/32' %}
301                     {%- else %}
302                         {% set mask = '/128' %}
303                     {%- endif %}
304                     {%- for server in host_networking['dns'] %}
305                         {%- set dnsroute = server ~ mask %}
306                         {%- set gw = {"to": dnsroute, "via": value['gateway']} %}
307                         {%- if routes.append(gw) %}{%- endif %}
308                     {%- endfor %}
309                 {%- endif %}
310                 {%- if external_ceph_cidr is not none %}
311                     {%- set gw = {"to": external_ceph_cidr, "via": value['gateway']} %}
312                     {%- if routes.append(gw) %}{%- endif %}
313                 {%- endif %}
314             {%- endif %}
315             {%- if routes %}
316                 "routes": {{ add_static_routes(routes) }},
317             {%- endif %}
318             {%- if config_phase not in ('setup', 'bootstrapping') -%}
319                 "rules": [
320                     {"rule": "from {{ caas.oam_cidr }} lookup {{ caas_oam_routing_table_name }}"},
321                     {"rule": "to {{ caas.oam_cidr }} lookup main"}
322                 ],
323             {%- endif -%}
324             "use_dhcp": false
325         }
326         {%- endif %}{#- no dpdk or no cloud tenant -#}
327     {%- endif %}
328 {%- endfor %}
329
330 {%- if config_phase != 'setup' %}
331 {#- configure caas provider network interfaces -#}
332 {%- for iface,value in host_provider_network_interfaces.iteritems() if 'caas' in value['type'] %}
333     {%- if not loopvar.first_entry %},{%- endif %}
334     {%- if loopvar.update({'first_entry': False}) %}{%- endif %}
335     {%- set ifacevars = {'mtu': 0} %}
336     {
337         "name": "{{iface}}",
338         {%- for mapped_net in value['provider_networks'] %}
339             {%- for net,info in host_networking['provider_networks'].iteritems() if net == mapped_net %}
340                 {%- if 'mtu' in info %}
341                     {%- if info['mtu'] > ifacevars.mtu %}
342                         {%- if ifacevars.update({'mtu': info['mtu']}) %}{%- endif %}
343                     {%- endif %}
344                 {%- elif default_mtu > ifacevars.mtu %}
345                     {%- if ifacevars.update({'mtu': default_mtu}) %}{%- endif %}
346                 {%- endif %}
347             {%- endfor %}
348         {%- endfor %}
349         {%- if 'bond' in iface %}
350             {%- for bond,slaves in host_bonding_interfaces.iteritems() if bond == iface %}
351                 {%- for slave in slaves %}
352                     {%- if slave in sriov_mtus and sriov_mtus[slave] > ifacevars.mtu %}
353                         {%- if ifacevars.update({'mtu': sriov_mtus[slave]}) %}{%- endif %}
354                     {%- endif %}
355                 {%- endfor %}
356                 "type": "linux_bond",
357                 "mtu": {{ifacevars.mtu}},
358                 {%- if 'linux_bonding_options' in  host_network_profile_value %}
359                     "bonding_options": "{{ generate_linux_bonding_options(host_network_profile_value['linux_bonding_options']) }}",
360                 {%- endif %}
361                 "members": [ {% for slave in slaves %}
362                     {%- if configured_phys_ifaces.append(slave) %}{%- endif %}
363                     {
364                     "name": "{{slave}}",
365                     "type": "interface",
366                     "mtu": {{ifacevars.mtu}},
367                     "use_dhcp": false
368                     }
369                     {% if not loop.last %},{% endif %}
370                 {%- endfor %}
371                 ],
372             {%- endfor %}
373         {%- else %}
374             {%- if configured_phys_ifaces.append(iface) %}{%- endif %}
375             {%- if iface in sriov_mtus and sriov_mtus[iface] > ifacevars.mtu %}
376                 {%- if ifacevars.update({'mtu': sriov_mtus[iface]}) %}{%- endif %}
377             {%- endif %}
378             "type": "interface",
379         {%- endif %}
380         "mtu": {{ifacevars.mtu}},
381         "use_dhcp": false
382     }
383 {%- endfor %}
384 {%- endif %}{#- if config_phase != 'setup' -#}
385
386 {%- endif %}{#- if not single_nic_setup -#}
387
388 {%- if config_phase != 'setup' or single_nic_setup %}
389
390 {#- configure ovs-* provider network interfaces -#}
391 {%- for key,value in host_provider_network_interfaces|dictsort(true) if 'ovs' in value['type'] %}
392     {%- set keyloop = loop %}
393     {%- if not loopvar.first_entry %},{%- endif %}
394     {%- if loopvar.update({'first_entry': False}) %}{%- endif %}
395     {%- if value['type'] == 'ovs-dpdk' %}
396         {%- for bond_key,bond_value in host_bonding_interfaces.iteritems() if bond_key == key %}
397             {%- for member in bond_value %}
398                 {%- if member not in ixgbedevs %}
399                     {%- if configured_phys_ifaces.append(member) %}{%- endif %}
400                     {
401                         "name": "{{member}}",
402                         "type": "interface",
403                         "mtu": {{max_mtu}},
404                         "use_dhcp": false
405                     },
406                 {%- endif %}
407             {%- endfor %}
408         {%- endfor %}
409         {%- if 'bond' not in key and key not in ixgbedevs %}
410             {%- if configured_phys_ifaces.append(key) %}{%- endif %}
411             {
412                 "name": "{{key}}",
413                 "type": "interface",
414                 "mtu": {{max_mtu}},
415                 "use_dhcp": false
416             },
417         {%- endif %}
418     {%- endif %}
419     {
420         "name": "br-pro{{keyloop.index0}}",
421         {%- if value['type'] == 'ovs-dpdk' %}
422             "type": "ovs_user_bridge",
423         {%- else %}
424             "type": "ovs_bridge",
425         {%- endif %}
426         "members": [
427             {
428             "mtu": {{max_mtu}},
429             {%- if 'bond' in key %}
430                 {%- for bond_key,bond_value in host_bonding_interfaces.iteritems() if bond_key == key %}
431                     {%- if 'ovs_bonding_options' in  host_network_profile_value %}
432                         "ovs_options": "{{ generate_ovs_bonding_options(host_network_profile_value['ovs_bonding_options']) }}",
433                     {%- endif %}
434                     "name": "{{key}}",
435                     {%- if value['type'] == 'ovs-dpdk' %}
436                         "type": "ovs_dpdk_bond",
437                         {%- if 'dpdk_max_rx_queues' in value %}
438                             "rx_queue": {{ value['dpdk_max_rx_queues'] }},
439                         {%- endif %}
440                         "members": [ {%- for member in bond_value %}
441                             {%- if configured_phys_ifaces.append(member) %}{%- endif %}
442                             {
443                             "name": "dpdk-{{member}}",
444                             "type": "ovs_dpdk_port",
445                             "mtu": {{max_mtu}},
446                             "members": [ { "name": "{{member}}", "type": "interface", "mtu": {{max_mtu}}, "use_dhcp": false } ],
447                             "use_dhcp": false
448                             }
449                             {% if not loop.last %},{% endif %}
450                         {%- endfor %}
451                         ],
452                     {%- else %}
453                         "type": "ovs_bond",
454                         "members": [ {% for member in bond_value %}
455                             {%- if configured_phys_ifaces.append(member) %}{%- endif %}
456                             {
457                             "name": "{{ member }}",
458                             "type": "interface",
459                             "mtu": {{max_mtu}},
460                             "use_dhcp": false
461                             }
462                             {% if not loop.last %},{% endif %}
463                         {%- endfor %}
464                         ],
465                     {%- endif %}
466                 {%- endfor %}
467             {%- else %}
468                 {%- if configured_phys_ifaces.append(key) %}{%- endif %}
469                 {%- if value['type'] == 'ovs-dpdk' %}
470                     "name": "dpdk-{{key}}",
471                     "type": "ovs_dpdk_port",
472                     "mtu": {{max_mtu}},
473                     {%- if 'dpdk_max_rx_queues' in value %}
474                         "rx_queue": {{ value['dpdk_max_rx_queues'] }},
475                     {%- endif %}
476                     "members": [ { "name": "{{key}}", "type": "interface", "mtu": {{max_mtu}}, "use_dhcp": false } ],
477                 {%- else %}
478                     "name": "{{key}}",
479                     "type": "interface",
480                 {%- endif %}
481             {%- endif %}
482             "use_dhcp": false
483             }
484             {%- for net in value['provider_networks'] %}
485                 ,
486                 {
487                 "name": "pro{{keyloop.index0}}-pro{{keyloop.index0}}.{{loop.index0}}",
488                 "bridge_name": "br-pro{{keyloop.index0}}",
489                 "type": "ovs_patch_port",
490                 "peer": "pro{{keyloop.index0}}.{{loop.index0}}-pro{{keyloop.index0}}"
491                 }
492             {%- endfor %}
493             {%- if single_nic_setup %}
494                 {#- configure all infra ifaces -#}
495                 {%- for key,value in host_networking.iteritems() %}
496                     {%- if value is iterable and 'interface' in value %}
497                         {%- if 'mtu' in value %}{% set mtu = value['mtu'] %}{% else %}{% set mtu = default_mtu %}{% endif %}
498                         {%- if key == CLOUD_TENANT %}{% set mtu = mtu + VXLAN_HDR_LEN %}{% endif %}
499                         ,
500                         {
501                         "type": "vlan",
502                         "vlan_id": {{ value['vlan'] }},
503                         "addresses": [ { "ip_netmask": "{{ value['ip'] }}/{{value['mask']}}" } ],
504                         "mtu": {{mtu}},
505                         {%- if (key == "infra_external" or key == "infra_access")
506                             and 'dns' in host_networking
507                             and (ansible_hostname not in groups.get('caas_nodes', [])) %}
508                             "dns_servers": [{% for server in host_networking['dns'] %}"{{ server }}"{% if not loop.last %},{% endif %}{% endfor %}],
509                         {%- endif %}
510                         {%- set routes = [] %}
511                         {%- if 'routes' in value %}
512                             {%- set routes = value['routes'] %}
513                         {%- endif %}
514                         {%- if config_phase not in ('setup', 'bootstrapping') -%}
515                             {% if 'gateway' in value %}
516                                 {%- set caas_oam_gw =  value['gateway'] %}
517                             {% else %}
518                                 {# Fall back to most popular self IP as gateway #}
519                                 {%- set caas_oam_gw =  value['cidr'] | ipaddr(1) | ipaddr('address') %}
520                             {% endif %}
521                             {%- set caas_oam_route = {
522                                 "to": '0.0.0.0/0', "via": caas_oam_gw,
523                                 "table": caas_oam_routing_table_name} %}
524                             {%- if key == 'caas_oam' %}
525                                 {%- set _ = routes.append(caas_oam_route) %}
526                             {%- elif key == 'infra_internal' %}
527                                 {% set bound_host_networks = [] %}
528                                 {% for host_networks in (host_interface_net_mapping.keys() | map('extract', host_interface_net_mapping)| list) %}
529                                     {% set _ = bound_host_networks.extend(host_networks) %}
530                                 {% endfor %}
531                                 {%- if 'caas_oam' not in bound_host_networks %}
532                                     {%- set _ = routes.append(caas_oam_route) %}
533                                 {%- endif %}
534                                 {%- set caas_oam_internal_route = {
535                                     "to": value['cidr'], "via": value['ip'],
536                                     "table": caas_oam_routing_table_name} %}
537                                 {%- set _ = routes.append(caas_oam_internal_route) %}
538                             {% endif %}
539                         {%- endif -%}
540                         {%- if key == 'infra_external' and 'gateway' in value %}
541                             {%- if '.' in value['gateway'] %}
542                                 {% set defaultroute = '0.0.0.0/0'%}
543                             {%- else %}
544                                 {% set defaultroute = '::/0'%}
545                             {%- endif %}
546                             {%- set gw = {"to": defaultroute, "via": value['gateway']} %}
547                             {%- if routes.append(gw) %}{%- endif %}
548                         {%- endif %}
549                         {%- if key == 'infra_access' and 'gateway' in value %}
550                             {%- if 'dns' in host_networking %}
551                                 {%- if '.' in value['gateway'] %}
552                                     {% set mask = '/32' %}
553                                 {%- else %}
554                                     {% set mask = '/128' %}
555                                 {%- endif %}
556                                 {%- for server in host_networking['dns'] %}
557                                     {%- set dnsroute = server ~ mask %}
558                                     {%- set gw = {"to": dnsroute, "via": value['gateway']} %}
559                                     {%- if routes.append(gw) %}{%- endif %}
560                                 {%- endfor %}
561                             {%- endif %}
562                             {%- if external_ceph_cidr is not none %}
563                                 {%- set gw = {"to": external_ceph_cidr, "via": value['gateway']} %}
564                                 {%- if routes.append(gw) %}{%- endif %}
565                             {%- endif %}
566                         {%- endif %}
567                         {%- if routes %}
568                             "routes": {{ add_static_routes(routes) }},
569                         {%- endif %}
570                         {%- if config_phase not in ('setup', 'bootstrapping') -%}
571                             "rules": [
572                                 {"rule": "from {{ caas.oam_cidr }} lookup {{ caas_oam_routing_table_name }}"},
573                                 {"rule": "to {{ caas.oam_cidr }} lookup main"}
574                             ],
575                         {%- endif -%}
576                         "use_dhcp": false
577                         }
578                     {%- endif %}
579                 {%- endfor %}
580             {%- endif %}{#- if single_nic_setup -#}
581         ]
582     }
583     {%- for net in value['provider_networks'] %}
584         ,
585         {
586             "name": "br-pro{{keyloop.index0}}.{{loop.index0}}",
587             {%- if value['type'] == 'ovs-dpdk' %}
588                 "type": "ovs_user_bridge",
589             {%- else %}
590                 "type": "ovs_bridge",
591             {%- endif %}
592             "ovs_fail_mode": "secure",
593             "members": [
594                 {
595                 "name": "pro{{keyloop.index0}}.{{loop.index0}}-pro{{keyloop.index0}}",
596                 "bridge_name": "br-pro{{keyloop.index0}}.{{loop.index0}}",
597                 "type": "ovs_patch_port",
598                 "peer": "pro{{keyloop.index0}}-pro{{keyloop.index0}}.{{loop.index0}}"
599                 }
600             ]
601         }
602     {%- endfor %}
603 {%- endfor %}
604
605 {#- configure vxlan bridge for dpdk cloud tenant -#}
606 {%- if CLOUD_TENANT in host_networking.keys() and 'interface' in host_networking[CLOUD_TENANT] and dpdk_in_use %}
607     {%- set net = host_networking[CLOUD_TENANT] %}
608     {%- if not loopvar.first_entry %},{%- endif %}
609     {%- if loopvar.update({'first_entry': False}) %}{%- endif %}
610     {
611         "type": "ovs_user_bridge",
612         "name": "br-vxlan",
613         "addresses": [ { "ip_netmask": "{{ net['ip'] }}/{{net['mask']}}" } ],
614         {%- if 'routes' in net %}
615             "routes": {{ add_static_routes(net['routes']) }},
616         {%- endif %}
617         "members": [{
618             "type": "vlan",
619             "vlan_id": {{ net['vlan'] }},
620             {%- for net_key,net_value in host_interface_net_mapping.iteritems() %}
621                 {%- if CLOUD_TENANT in net_value %}
622                     "device": "{{net_key}}",
623                 {%- endif %}
624             {%- endfor %}
625             {%- if 'mtu' in net %}{% set mtu = net['mtu'] %}{% else %}{% set mtu = default_mtu %}{% endif %}
626             {% set mtu = mtu + VXLAN_HDR_LEN %}
627             "mtu": {{mtu}},
628             "use_dhcp": false
629         }],
630         "ovs_extra": [ "br-set-external-id br-vxlan bridge-id br-vxlan" ]
631     }
632 {%- endif %}
633 {%- endif %}{#- if config_phase != 'setup' or single_nic_setup -#}
634
635 {#- configure sr-iov ifaces -#}
636 {%- if config_phase != 'setup' %}
637     {%- for iface,mtu in sriov_mtus.iteritems() %}
638         {%- if iface not in configured_phys_ifaces %}
639             {%- if not loopvar.first_entry %},{%- endif %}
640             {%- if loopvar.update({'first_entry': False}) %}{%- endif %}
641             {
642                 "name": "{{iface}}",
643                 "type": "interface",
644                 "mtu": {{mtu}},
645                 "use_dhcp": false
646             }
647         {%- endif %}
648     {%- endfor %}
649 {%- endif %}{#- if config_phase != 'setup' -#}
650 {%- if config_phase not in ('setup', 'bootstrapping') %}
651             ,
652             {
653                 "name": "{{ caas_oam_routing_table_name }}",
654                 "type": "route_table",
655                 "table_id": {{ caas_oam_routing_table_id }}
656             }
657 {%- endif %}
658 ]
659 }