3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
17 from jinja2 import Environment
19 from cmframework.apis import cmansibleinventoryconfig
20 from cmdatahandlers.api import utils
24 [ {%- if 'mgmt_mac' in all_vars['hosts'][host] %}
25 {%- for mac_members in all_vars['hosts'][host]['mgmt_mac'] %}
27 "mac": "{{ mac_members }}"
29 {%- if not loop.last %},{%- endif %}
33 "mac": "{{ all_vars['hw_inventory_details'][host]['mgmt_mac'] }}"
40 class zbaremetalnodeinventory(cmansibleinventoryconfig.CMAnsibleInventoryConfigPlugin):
41 def __init__(self, confman, inventory, ownhost):
42 super(zbaremetalnodeinventory, self).__init__(confman, inventory, ownhost)
44 def handle_bootstrapping(self):
47 def handle_provisioning(self):
50 def handle_postconfig(self):
53 def handle_setup(self):
57 def _check_host_single_nic(host_network_profile_value, host_interface_net_mapping):
58 if 'provider_network_interfaces' in host_network_profile_value:
59 host_provider_network_interfaces = host_network_profile_value['provider_network_interfaces']
60 if len(host_interface_net_mapping) == 1 and len(host_provider_network_interfaces) == 1:
61 if host_interface_net_mapping.keys()[0] == host_provider_network_interfaces.keys()[0]:
66 def _generate_linux_bonding_options(options):
67 mode_mapping = {'active-backup': 'active-backup', 'lacp': '802.3ad'}
68 default_options = {'active-backup': 'miimon=100',
69 'lacp': 'lacp_rate=fast miimon=100'}
70 for i in options.split():
71 key, value = i.split('=')
73 if default_options[value]:
74 return 'mode=' + mode_mapping[value] + ' ' + default_options[value]
75 return 'mode=' + mode_mapping[value]
78 def _generate_ovs_bonding_options(options):
79 mode_mapping = {'active-backup': 'active-backup', 'lacp': 'balance-slb',
80 'lacp-layer34': 'balance-tcp'}
81 default_options = {'active-backup': '',
82 'lacp': 'lacp=active other_config:lacp-time=fast other_config:bond-detect-mode=carrier',
83 'lacp-layer34': 'lacp=active other_config:lacp-time=fast other_config:bond-detect-mode=carrier'}
84 for i in options.split():
85 key, value = i.split('=')
87 if default_options[value]:
88 return 'bond_mode=' + mode_mapping[value] + ' ' + default_options[value]
89 return 'bond_mode=' + mode_mapping[value]
92 def _add_static_routes(routes):
95 routes_list.append({"ip_netmask": route["to"], "next_hop": route["via"]})
99 usersconf = self.confman.get_users_config_handler()
100 hostsconf = self.confman.get_hosts_config_handler()
101 admin_user = usersconf.get_admin_user()
102 self.add_global_var("home_dir", "/home/" + admin_user)
103 all_vars = self.inventory['all']['vars']
104 host_locals = self.inventory['_meta']['hostvars']
105 nfs_server_ip = host_locals[all_vars['installation_controller']]['networking']['infra_external']['ip']
107 for host, hostvars in host_locals.iteritems():
108 host_hdd_mapping = hostvars['by_path_disks']
109 host_networking = hostvars['networking']
110 host_network_profiles_list = all_vars['hosts'][host]['network_profiles']
111 host_network_profile_value = all_vars['network_profiles'][host_network_profiles_list[0]]
112 host_interface_net_mapping = host_network_profile_value['interface_net_mapping']
114 infra_bond = {'in_use': False}
115 host_bonding_interfaces = host_network_profile_value.get('bonding_interfaces', {})
116 default_mtu = all_vars['networking'].get('mtu', 1500)
119 if 'sriov_provider_networks' in host_network_profile_value:
120 sriov_nets = host_network_profile_value['sriov_provider_networks']
121 prov_infos = host_networking.get('provider_networks', {})
122 for net_name, sriov_info in sriov_nets.iteritems():
123 if prov_infos.get(net_name):
124 prov_info = prov_infos[net_name]
125 sriov_mtu = prov_info.get('mtu', default_mtu)
126 for iface in sriov_info['interfaces']:
127 sriov_mtus[iface] = sriov_mtu
130 if 'mtu' in all_vars['networking']['infra_internal']:
131 mtu = all_vars['networking']['infra_internal']['mtu']
133 phys_iface_mtu = 1500
134 if 'vlan' in host_networking['infra_internal']:
135 for iface, infras in host_interface_net_mapping.iteritems():
136 if 'infra_internal' in infras:
138 tmp_mtu = default_mtu
139 if 'mtu' in all_vars['networking'][infra]:
140 tmp_mtu = all_vars['networking'][infra]['mtu']
141 if infra == 'cloud_tenant':
142 tmp_mtu = tmp_mtu + 50
143 if tmp_mtu > phys_iface_mtu:
144 phys_iface_mtu = tmp_mtu
146 if host_bonding_interfaces.get(iface):
147 for slave in host_bonding_interfaces[iface]:
148 if slave in sriov_mtus and sriov_mtus[slave] > phys_iface_mtu:
149 phys_iface_mtu = sriov_mtus[slave]
150 elif iface in sriov_mtus and sriov_mtus[iface] > phys_iface_mtu:
151 phys_iface_mtu = sriov_mtus[iface]
155 "capabilities": "boot_option:local",
156 "cpu_arch": platform.machine(),
163 "provisioning_server": nfs_server_ip,
164 "virtmedia_deploy_iso": "file:///opt/images/ironic-deploy.iso",
167 # aarch64 platforms only support EFI bootloaders
168 if platform.machine() == 'aarch64':
169 properties["capabilities"] += ",boot_mode:uefi"
171 if utils.is_virtualized():
172 driver = "ssh_virtmedia"
173 properties["root_device"] = {"by_path": host_hdd_mapping['os']}
174 power["ssh_address"] = all_vars['hosts'][host]['hwmgmt']['address']
175 power["ssh_username"] = all_vars['hosts'][host]['hwmgmt']['user']
176 power["ipmi_port"] = all_vars['hosts'][host]['vbmc_port']
177 power["ipmi_username"] = "admin"
178 power["ipmi_password"] = "password"
179 power["ssh_key_contents"] = "{{ lookup('file', '/etc/userconfig/id_rsa') }}"
180 power["ipmi_address"] = host_locals[all_vars['installation_controller']]['networking']['infra_internal']['ip']
182 driver = "ipmi_virtmedia"
183 power["ipmi_address"] = all_vars['hosts'][host]['hwmgmt']['address']
184 power["ipmi_password"] = all_vars['hosts'][host]['hwmgmt']['password']
185 power["ipmi_username"] = all_vars['hosts'][host]['hwmgmt']['user']
186 power["ipmi_priv_level"] = hostsconf.get_hwmgmt_priv_level(host)
187 power["product_family"] = all_vars['hw_inventory_details'][host]['product_family']
188 power["vendor"] = all_vars['hw_inventory_details'][host]['vendor']
190 if host_hdd_mapping['os'] != "/dev/sda":
191 properties["root_device"] = {"by_path": host_hdd_mapping['os']}
193 properties["root_device"] = {"name": host_hdd_mapping['os']}
195 nics_text = Environment().from_string(nics_json_txt).render(all_vars=all_vars, host=host)
196 nics_inventory = json.loads(nics_text)
199 driver_info["power"] = power
200 #####################################################
202 if 'interface' in host_networking['infra_internal']:
203 if not self._check_host_single_nic(host_network_profile_value, host_interface_net_mapping):
204 if 'bonding_interfaces' in host_network_profile_value:
205 for net_key, net_value in host_interface_net_mapping.iteritems():
207 if "bond" in net_key and "infra_internal" in net_value:
209 for member in host_bonding_interfaces[net_key]:
211 if 'bond' in host_networking['infra_internal']['interface']:
212 member_element["mtu"] = mtu
214 member_element["mtu"] = phys_iface_mtu
215 member_element["name"] = member
216 member_element["type"] = "interface"
217 member_element["use_dhcp"] = False
218 members.append(member_element)
221 "type": "linux_bond",
224 bond_contents["name"] = net_key
225 bond_contents["members"] = members
227 if 'linux_bonding_options' in host_network_profile_value:
228 bond_contents["bonding_options"] = self._generate_linux_bonding_options(host_network_profile_value['linux_bonding_options'])
229 if 'bond' in host_networking['infra_internal']['interface']:
230 bond_contents["addresses"] = [{"ip_netmask": "%s/%s" % (host_networking['infra_internal']['ip'], host_networking['infra_internal']['mask'])}]
231 bond_contents["mtu"] = mtu
232 if 'routes' in host_networking['infra_internal']:
233 routes = host_networking['infra_internal']['routes']
234 bond_contents["routes"] = self._add_static_routes(routes)
236 bond_contents["mtu"] = phys_iface_mtu
238 infra_bond.update({'in_use': True})
240 network_config.append(bond_contents)
241 if 'vlan' in host_networking['infra_internal']:
246 vlan_contents["addresses"] = [{"ip_netmask": "%s/%s" % (host_networking['infra_internal']['ip'], host_networking['infra_internal']['mask'])}]
247 vlan_contents["vlan_id"] = host_networking['infra_internal']['vlan']
248 for net_key, net_value in host_interface_net_mapping.iteritems():
249 if "infra_internal" in net_value:
250 vlan_contents["device"] = net_key
251 vlan_contents["mtu"] = mtu
252 if 'routes' in host_networking['infra_internal']:
253 routes = host_networking['infra_internal']['routes']
254 vlan_contents["routes"] = []
256 vlan_contents["routes"].append({"ip_netmask": route["to"], "next_hop": route["via"]})
257 if not infra_bond["in_use"]:
258 vlan_phy_contents = {
261 "mtu": phys_iface_mtu
263 for net_key, net_value in host_interface_net_mapping.iteritems():
264 if "infra_internal" in net_value:
265 vlan_phy_contents["name"] = net_key
266 network_config.append(vlan_phy_contents)
268 network_config.append(vlan_contents)
270 elif not infra_bond["in_use"]:
272 "name": host_networking['infra_internal']['interface'],
277 phy_contents["addresses"] = [{"ip_netmask": "%s/%s" % (host_networking['infra_internal']['ip'], host_networking['infra_internal']['mask'])}]
278 if 'routes' in host_networking['infra_internal']:
279 routes = host_networking['infra_internal']['routes']
280 phy_contents["routes"] = self._add_static_routes(routes)
282 network_config.append(phy_contents)
284 # --> single_nic_setup <-- #
286 single_nic_contents = {
288 "type": "ovs_bridge",
291 member_elements = {"mtu": phys_iface_mtu, "use_dhcp": False}
292 iface = host_interface_net_mapping.keys()[0]
294 for bond_iface, bond_value in host_bonding_interfaces.iteritems():
295 if bond_iface == iface:
296 if 'ovs_bonding_options' in host_network_profile_value:
297 member_elements["ovs_options"] = self._generate_ovs_bonding_options(host_network_profile_value['ovs_bonding_options'])
298 member_elements["name"] = iface
299 member_elements["type"] = "ovs_bond"
300 member_elements["members"] = []
301 for member in bond_value:
305 "mtu": phys_iface_mtu,
308 member_elements["members"].append(ovs_bond_member)
309 single_nic_contents["members"].append(member_elements)
311 member_elements["name"] = iface
312 member_elements["type"] = "interface"
313 single_nic_contents["members"].append(member_elements)
316 infra = host_networking['infra_internal']
317 infra_elements["use_dhcp"] = False
318 infra_elements["type"] = "vlan"
319 infra_elements["vlan_id"] = infra['vlan']
320 infra_elements["mtu"] = mtu
321 infra_elements["addresses"] = [{"ip_netmask": "%s/%s" % (infra['ip'], infra['mask'])}]
322 if 'routes' in infra:
323 routes = infra['routes']
324 infra_elements["routes"] = self._add_static_routes(routes)
326 single_nic_contents["members"].append(infra_elements)
327 network_config.append(single_nic_contents)
328 #####################################################
329 driver_info["power"]["os_net_config"] = {"network_config": network_config}
331 ironic_node_details = {
334 "network_interface": "noop",
335 "nics": nics_inventory,
336 "properties": properties,
337 "driver_info": driver_info
339 self.add_host_var(host, 'ironic_node_details', ironic_node_details)