Kubernetes node role refactored.
[ta/config-manager.git] / cmdatahandlers / src / cmdatahandlers / hosts / config.py
1 # Copyright 2019 Nokia
2
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
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14
15 import re
16
17 from cmdatahandlers.api import configerror
18 from cmdatahandlers.api import config
19 from cmdatahandlers.api import utils
20 from serviceprofiles import profiles
21
22 VNF_EMBEDDED_RESERVED_MEMORY = "512Mi"
23 DUAL_VIM_CONTROLLER_RESERVED_MEMORY = "64Gi"
24 DUAL_VIM_DEFAULT_RESERVED_MEMORY = "32Gi"
25 MIDDLEWARE_RESERVED_MEMORY = "12Gi"
26
27 class Config(config.Config):
28     def __init__(self, confman):
29         super(Config, self).__init__(confman)
30         self.ROOT = 'cloud.hosts'
31         self.DOMAIN = 'hosts'
32         try:
33             self.update_service_profiles()
34         except Exception:
35             pass
36
37     def init(self):
38         pass
39
40     def validate(self):
41         hosts = []
42         try:
43             hosts = self.get_hosts()
44         except configerror.ConfigError:
45             pass
46
47         if hosts:
48             utils.validate_list_items_unique(hosts)
49
50         for host in hosts:
51             self._validate_host(host)
52
53     def mask_sensitive_data(self):
54         for hostname in self.config[self.ROOT].keys():
55             self.config[self.ROOT][hostname]['hwmgmt']['password'] = self.MASK
56             self.config[self.ROOT][hostname]['hwmgmt']['snmpv2_trap_community_string'] = self.MASK
57             self.config[self.ROOT][hostname]['hwmgmt']['snmpv3_authpass'] = self.MASK
58             self.config[self.ROOT][hostname]['hwmgmt']['snmpv3_privpass'] = self.MASK
59
60     def _validate_host(self, hostname):
61         self._validate_hwmgmt(hostname)
62         self._validate_service_profiles(hostname)
63         self._validate_network_profiles(hostname)
64         self._validate_performance_profiles(hostname)
65         self._validate_storage_profiles(hostname)
66
67     def _validate_hwmgmt(self, hostname):
68         ip = self.get_hwmgmt_ip(hostname)
69         utils.validate_ipv4_address(ip)
70         self.get_hwmgmt_user(hostname)
71         self.get_hwmgmt_password(hostname)
72         netconf = self.confman.get_networking_config_handler()
73
74         hwmgmtnet = None
75         try:
76             hwmgmtnet = netconf.get_hwmgmt_network_name()
77         except configerror.ConfigError:
78             pass
79
80         if hwmgmtnet:
81             domain = self.get_host_network_domain(hostname)
82             cidr = netconf.get_network_cidr(hwmgmtnet, domain)
83             utils.validate_ip_in_network(ip, cidr)
84
85     def get_hwmgmt_priv_level(self, hostname):
86         """get the hwmgmt IPMI privilege level.  Defaults to ADMINISTRATOR
87
88            Arguments:
89
90            hostname: The name of the node
91
92            Return:
93
94            The prvilege level, or ADMINISTRATOR if unspecified
95
96            Raise:
97
98            ConfigError in-case of an error
99         """
100         self._validate_hostname(hostname)
101
102         if 'hwmgmt' not in self.config[self.ROOT][hostname]:
103             raise configerror.ConfigError('No hwmgmt info defined for host')
104
105         return self.config[self.ROOT][hostname]['hwmgmt'].get('priv_level', 'ADMINISTRATOR')
106
107     def _validate_service_profiles(self, hostname):
108         node_profiles = self.get_service_profiles(hostname)
109         utils.validate_list_items_unique(node_profiles)
110         service_profiles_lib = profiles.Profiles()
111         serviceprofiles = service_profiles_lib.get_service_profiles()
112         for profile in node_profiles:
113             if profile not in serviceprofiles:
114                 raise configerror.ConfigError('Invalid service profile %s specified for host %s' % (profile, hostname))
115
116     def _validate_network_profiles(self, hostname):
117         node_profiles = self.get_network_profiles(hostname)
118         utils.validate_list_items_unique(profiles)
119         netprofconf = self.confman.get_network_profiles_config_handler()
120         netprofiles = netprofconf.get_network_profiles()
121         for profile in node_profiles:
122             if profile not in netprofiles:
123                 raise configerror.ConfigError('Invalid network profile %s specified for host %s' % (profile, hostname))
124
125     def _validate_performance_profiles(self, hostname):
126         node_performance_profiles = []
127         try:
128             node_performance_profiles = self.get_performance_profiles(hostname)
129         except configerror.ConfigError:
130             pass
131
132         if node_performance_profiles:
133             utils.validate_list_items_unique(node_performance_profiles)
134             perfprofconf = self.confman.get_performance_profiles_config_handler()
135             perfprofiles = perfprofconf.get_performance_profiles()
136             for profile in node_performance_profiles:
137                 if profile not in perfprofiles:
138                     raise configerror.ConfigError('Invalid performance profile %s specified for host %s' % (profile, hostname))
139
140     def _validate_storage_profiles(self, hostname):
141         node_storage_profiles = []
142         try:
143             node_storage_profiles = self.get_storage_profiles(hostname)
144         except configerror.ConfigError:
145             pass
146
147         if node_storage_profiles:
148             utils.validate_list_items_unique(node_storage_profiles)
149             storageprofconf = self.confman.get_storage_profiles_config_handler()
150             storageprofiles = storageprofconf.get_storage_profiles()
151             for profile in node_storage_profiles:
152                 if profile not in storageprofiles:
153                     raise configerror.ConfigError('Invalid storage profile %s specific for %s' % (profile, hostname))
154
155     def get_hosts(self):
156         """ get the list of hosts in the cloud
157
158             Return:
159
160             A sorted list of host names
161
162             Raise:
163
164             ConfigError in-case of an error
165         """
166         self.validate_root()
167
168         return sorted(self.config[self.ROOT].keys())
169
170     def get_labels(self, hostname):
171         mandatory_labels = \
172             {"nodetype": self.get_nodetype(hostname),
173              "nodeindex": self.get_nodeindex(hostname),
174              "nodename": self.get_nodename(hostname)}
175         labels = self.config[self.ROOT][hostname].get('labels', {}).copy()
176         labels.update(mandatory_labels)
177
178         if self.is_sriov_enabled(hostname):
179             labels.update({"sriov": "enabled"})
180
181         black_list = ['name']
182         return {name: attributes
183                 for name, attributes in labels.iteritems()
184                 if name not in black_list}
185
186     def get_nodetype(self, hostname):
187         service_profiles_lib = profiles.Profiles()
188         service_profiles = self.get_service_profiles(hostname)
189
190         if service_profiles_lib.get_caasmaster_service_profile() in service_profiles:
191             return service_profiles_lib.get_caasmaster_service_profile()
192         if service_profiles_lib.get_caasworker_service_profile() in service_profiles:
193             return service_profiles_lib.get_caasworker_service_profile()
194
195         return service_profiles[0]
196
197     def set_noderole(self):
198         hosts = self.get_hosts()
199         for host in hosts:
200             self.config[self.ROOT][host]['noderole'] = self.get_noderole(host)
201
202     def set_nodeindex(self):
203         hostsconf = self.confman.get_hosts_config_handler()
204         install_host = utils.get_installation_host_name(hostsconf)
205         self.config[self.ROOT][install_host]['caas_nodeindex'] = 1
206
207         masters = self.get_service_profile_hosts('caas_master')
208         masters.remove(install_host)
209         self._set_nodeindexes(masters, 2)
210         self._set_nodeindexes(self.get_service_profile_hosts('caas_worker'), 1)
211
212     def _set_nodeindexes(self, hosts, base_index):
213         index = base_index
214         for host in hosts:
215             self.config[self.ROOT][host]['caas_nodeindex'] = index
216             index += 1
217
218     def get_nodeindex(self, hostname):
219         return self.config[self.ROOT][hostname]['caas_nodeindex']
220
221     def get_nodename(self, hostname):
222         return "{}{}".format(self.get_nodetype(hostname), self.get_nodeindex(hostname))
223
224     def get_noderole(self, hostname):
225         service_profiles_lib = profiles.Profiles()
226         service_profiles = self.get_service_profiles(hostname)
227
228         if service_profiles_lib.get_caasmaster_service_profile() in service_profiles:
229             return "master"
230         return "worker"
231
232     def is_sriov_enabled(self, hostname):
233         netprofs = self.get_network_profiles(hostname)
234         netprofconf = self.confman.get_network_profiles_config_handler()
235         for netprof in netprofs:
236             if 'sriov_provider_networks' in self.config[netprofconf.ROOT][netprof]:
237                 return True
238         return False
239
240     def get_enabled_hosts(self):
241         """ get the list of enabled hosts in the cloud
242
243             Return:
244
245             A list of host names
246
247             Raise:
248
249             ConfigError in-case of an error
250         """
251         self.validate_root()
252         hosts = self.get_hosts()
253         ret = []
254         for host in hosts:
255             if self.is_host_enabled(host):
256                 ret.append(host)
257         return ret
258
259     def get_hwmgmt_ip(self, hostname):
260         """get the hwmgmt ip address
261
262             Arguments:
263
264             hostname: The name of the node
265
266             Return:
267
268             The BMC ip address as a string
269
270             Raise:
271
272             ConfigError in-case of an error
273         """
274         self._validate_hostname(hostname)
275
276         if 'hwmgmt' not in self.config[self.ROOT][hostname] or 'address' not in self.config[self.ROOT][hostname]['hwmgmt']:
277             raise configerror.ConfigError('No hwmgmt info defined for host')
278
279         return self.config[self.ROOT][hostname]['hwmgmt']['address']
280
281     def get_hwmgmt_user(self, hostname):
282         """get the hwmgmt user
283
284             Arguments:
285
286             hostname: The name of the node
287
288             Return:
289
290             The BMC user name.
291
292             Raise:
293
294             ConfigError in-case of an error
295         """
296         self._validate_hostname(hostname)
297
298         if 'hwmgmt' not in self.config[self.ROOT][hostname] or 'user' not in self.config[self.ROOT][hostname]['hwmgmt']:
299             raise configerror.ConfigError('No hwmgmt info defined for host')
300
301         return self.config[self.ROOT][hostname]['hwmgmt']['user']
302
303     def get_hwmgmt_password(self, hostname):
304         """get the hwmgmt password
305
306            Arguments:
307
308            hostname: The name of the node
309
310            Return:
311
312            The BMC password
313
314            Raise:
315
316            ConfigError in-case of an error
317         """
318         self._validate_hostname(hostname)
319
320         if 'hwmgmt' not in self.config[self.ROOT][hostname] or 'password' not in self.config[self.ROOT][hostname]['hwmgmt']:
321             raise configerror.ConfigError('No hwmgmt info defined for host')
322
323         return self.config[self.ROOT][hostname]['hwmgmt']['password']
324
325     def get_service_profiles(self, hostname):
326         """get the node service profiles
327
328            Arguments:
329
330            hostname: The name of the node
331
332            Return:
333
334            A list containing service profile names
335
336            Raise:
337
338            ConfigError in-case of an error
339         """
340         self._validate_hostname(hostname)
341
342         if 'service_profiles' not in self.config[self.ROOT][hostname]:
343             raise configerror.ConfigError('No service profiles found')
344
345         return self.config[self.ROOT][hostname]['service_profiles']
346
347     def get_performance_profiles(self, hostname):
348         """ get the performance profiles
349
350             Arguments:
351
352             hostname: The name of the node
353
354             Return:
355
356             A list containing the perfromance profile names.
357
358             Raise:
359
360             ConfigError in-case of an error
361         """
362         self._validate_hostname(hostname)
363
364         if 'performance_profiles' not in self.config[self.ROOT][hostname]:
365             raise configerror.ConfigError('No performance profiles found')
366
367         return self.config[self.ROOT][hostname]['performance_profiles']
368
369     def get_network_profiles(self, hostname):
370         """get the node network profiles
371
372            Arguments:
373
374            hostname: The name of the node
375
376            Return:
377
378            A list containing network profile names
379
380            Raise:
381
382            ConfigError in-case of an error
383         """
384         self._validate_hostname(hostname)
385
386         if 'network_profiles' not in self.config[self.ROOT][hostname]:
387             raise configerror.ConfigError('No network profiles found')
388
389         return self.config[self.ROOT][hostname]['network_profiles']
390
391     def get_storage_profiles(self, hostname):
392         """get the node storage profiles
393
394            Arguments:
395
396            hostname: The name of the node
397
398            Return:
399
400            A list containing storage profile names
401
402            Raise:
403
404            ConfigError in-case of an error
405         """
406         self._validate_hostname(hostname)
407
408         if 'storage_profiles' not in self.config[self.ROOT][hostname]:
409             raise configerror.ConfigError('No storage profiles found')
410
411         return self.config[self.ROOT][hostname]['storage_profiles']
412
413     def _validate_hostname(self, hostname):
414         if not self.is_valid_host(hostname):
415             raise configerror.ConfigError('Invalid hostname given %s' % hostname)
416
417     def is_valid_host(self, hostname):
418         """check if a host is valid
419
420            Arguments:
421
422            hostname: The name of the node
423
424            Return:
425
426            True or False
427
428            Raise:
429
430            ConfigError in-case of an error
431         """
432         self.validate_root()
433         if hostname in self.config[self.ROOT]:
434             return True
435         return False
436
437     def get_service_profile_hosts(self, profile):
438         """ get hosts having some service profile
439
440             Argument:
441
442             service profile name
443
444             Return:
445
446             A list of host names
447
448             Raise:
449
450             ConfigError in-case of an error
451         """
452         hosts = self.get_hosts()
453         result = []
454         for host in hosts:
455             node_profiles = self.get_service_profiles(host)
456             if profile in node_profiles:
457                 result.append(host)
458
459         return result
460
461     def get_network_profile_hosts(self, profile):
462         """ get hosts having some network profile
463
464             Argument:
465
466             network profile name
467
468             Return:
469
470             A list of host names
471
472             Raise:
473
474             ConfigError in-case of an error
475         """
476         hosts = self.get_hosts()
477         result = []
478         for host in hosts:
479             node_network_profiles = self.get_network_profiles(host)
480             if profile in node_network_profiles:
481                 result.append(host)
482         if not result:
483             raise configerror.ConfigError('No hosts found for profile %s' % profile)
484
485         return result
486
487     def get_performance_profile_hosts(self, profile):
488         """ get hosts having some performance profile
489
490             Argument:
491
492             performance profile name
493
494             Return:
495
496             A list of host names
497
498             Raise:
499
500             ConfigError in-case of an error
501         """
502         hosts = self.get_hosts()
503         result = []
504         for host in hosts:
505             node_performance_profiles = self.get_performance_profiles(host)
506             if profile in node_performance_profiles:
507                 result.append(host)
508         if not result:
509             raise configerror.ConfigError('No hosts found for profile %s' % profile)
510
511         return result
512
513     def get_storage_profile_hosts(self, profile):
514         """ get hosts having some storage profile
515
516             Argument:
517
518             storage profile name
519
520             Return:
521
522             A list of host names
523
524             Raise:
525
526             ConfigError in-case of an error
527         """
528         hosts = self.get_hosts()
529         result = []
530         for host in hosts:
531             try:
532                 node_storage_profiles = self.get_storage_profiles(host)
533                 if profile in node_storage_profiles:
534                     result.append(host)
535             except configerror.ConfigError:
536                 pass
537
538         if not result:
539             raise configerror.ConfigError('No hosts found for profile %s' % profile)
540
541         return result
542
543     def get_host_network_interface(self, host, network):
544         """ get the host interface used for some network
545
546             Argument:
547
548             the host name
549
550             the network name
551
552             Return:
553
554             The interface name
555
556             Raise:
557
558             ConfigError in-case of an error
559         """
560         node_network_profiles = self.get_network_profiles(host)
561         netprofconf = self.confman.get_network_profiles_config_handler()
562         for profile in node_network_profiles:
563             interfaces = netprofconf.get_profile_network_mapped_interfaces(profile)
564             for interface in interfaces:
565                 networks = netprofconf.get_profile_interface_mapped_networks(profile, interface)
566                 if network in networks:
567                     return interface
568
569         raise configerror.ConfigError('No interfaces found for network %s in host %s' % (network, host))
570
571     def get_host_network_ip_holding_interface(self, host, network):
572         """ get the host ip holding interface some network
573
574             Argument:
575
576             the host name
577
578             the network name
579
580             Return:
581
582             The interface name
583
584             Raise:
585
586             ConfigError in-case of an error
587         """
588         networkingconf = self.confman.get_networking_config_handler()
589         vlan = None
590         try:
591             domain = self.get_host_network_domain(host)
592             vlan = networkingconf.get_network_vlan_id(network, domain)
593         except configerror.ConfigError as exp:
594             pass
595
596         if vlan:
597             return 'vlan'+str(vlan)
598
599         return self.get_host_network_interface(host, network)
600
601     def get_host_networks(self, hostname):
602         """ get the host networks
603
604             Argument:
605
606             The host name
607
608             Return:
609
610             A list of network names
611
612             Raise:
613
614             ConfigError in-case of an error
615         """
616         node_network_profiles = self.get_network_profiles(hostname)
617         netprofconf = self.confman.get_network_profiles_config_handler()
618         result = []
619         for profile in node_network_profiles:
620             interfaces = netprofconf.get_profile_network_mapped_interfaces(profile)
621             for interface in interfaces:
622                 networks = netprofconf.get_profile_interface_mapped_networks(profile, interface)
623                 for network in networks:
624                     if network not in result:
625                         result.append(network)
626         if not result:
627             raise configerror.ConfigError('No networks found for host %s' % hostname)
628
629         return result
630
631     def get_host_having_hwmgmt_address(self, hwmgmtips):
632         """ get the node name matching an ipmi address
633
634             Argument:
635
636             The ipmi address
637
638             Return:
639
640             The node name
641
642             Raise:
643
644             ConfigError in-case of an error
645         """
646         import ipaddress
647         hosts = self.get_hosts()
648         for host in hosts:
649             ip = self.get_hwmgmt_ip(host)
650             for hwmgtip in hwmgmtips:
651                 addr=ipaddress.ip_address(unicode(hwmgtip))
652                 if addr.version == 6:
653                    hwmgtip=addr.compressed
654                    ip=ipaddress.ip_address(unicode(ip))
655                    ip=ip.compressed
656                 if ip == hwmgtip:
657                    return host
658         raise configerror.ConfigError('No hosts are matching the provided hw address %s' % hwmgmtips)
659
660     def set_installation_host(self, name):
661         """ set the installation node
662
663             Argument:
664
665             The installation node name
666
667             Raise:
668
669             ConfigError in-case of an error
670         """
671         self._validate_hostname(name)
672
673         self.config[self.ROOT][name]['installation_host'] = True
674
675     def is_installation_host(self, name):
676         """ get if the node is an installation node
677
678             Argument:
679
680             The node name
681
682             Return:
683
684             True if installation node
685
686             Raise:
687
688             ConfigError in-case of an error
689         """
690         self._validate_hostname(name)
691
692         if 'installation_host' in self.config[self.ROOT][name]:
693             return self.config[self.ROOT][name]['installation_host']
694
695         return False
696
697     def get_installation_host(self):
698         """ get the name of the node used for installation
699
700             Return:
701
702             The node name
703
704             Raise:
705
706             ConfigError in-case of an error
707         """
708         hosts = self.get_hosts()
709         for host in hosts:
710             if self.is_installation_host(host):
711                 return host
712
713         raise configerror.ConfigError('No installation host found')
714
715     def disable_host(self, host):
716         """ disable the hosts visible via configuration.
717             This can be used in bootstrapping phase.
718
719             Argument:
720
721             host to disable
722
723             Raise:
724
725             ConfigError in-case if provided host is not valid
726         """
727         self._validate_hostname(host)
728
729         self.config[self.ROOT][host]['disabled'] = True
730
731     def enable_host(self, host):
732         """ enable  the hosts visible via configuration.
733             This can be used in bootstrapping phase.
734
735             Argument:
736
737             host to enable
738
739             Raise:
740
741             ConfigError in-case if provided host is not valid
742         """
743         self._validate_hostname(host)
744
745         self.config[self.ROOT][host]['disabled'] = False
746
747     def is_host_enabled(self, host):
748         """ is the host enabled
749
750             Argument:
751
752             the host to be checked
753
754             Raise:
755
756             ConfigError in-case if provided host is not valid
757         """
758         self._validate_hostname(host)
759
760         if 'disabled' in self.config[self.ROOT][host]:
761             return not self.config[self.ROOT][host]['disabled']
762
763         return True
764
765     def get_mgmt_mac(self, host):
766         self._validate_hostname(host)
767
768         if 'mgmt_mac' in self.config[self.ROOT][host]:
769             return self.config[self.ROOT][host]['mgmt_mac']
770         return []
771
772     def get_host_network_domain(self, host):
773         self._validate_hostname(host)
774         if 'network_domain' not in self.config[self.ROOT][host]:
775             raise configerror.ConfigError('Missing network domain for host %s' % host)
776         return self.config[self.ROOT][host]['network_domain']
777
778     def get_controllers_network_domain(self):
779         controllers = self.get_service_profile_hosts('controller')
780         domains = set()
781         for controller in controllers:
782             domains.add(self.get_host_network_domain(controller))
783
784         if len(domains) != 1:
785             raise configerror.ConfigError('Controllers in different networking domains not supported')
786         return domains.pop()
787
788     def get_managements_network_domain(self):
789         managements = self.get_service_profile_hosts('management')
790         domains = set()
791         for management in managements:
792             domains.add(self.get_host_network_domain(management))
793         if len(domains) != 1:
794             raise configerror.ConfigError('Management in different networking domains not supported')
795         return domains.pop()
796
797     def update_service_profiles(self):
798         profs = profiles.Profiles()
799         hosts = self.get_hosts()
800         for host in hosts:
801             new_profiles = []
802             current_profiles = self.config[self.ROOT][host]['service_profiles']
803             new_profiles = current_profiles
804             for profile in current_profiles:
805                 included_profiles = profs.get_included_profiles(profile)
806                 new_profiles = utils.add_lists(new_profiles, included_profiles)
807             self.config[self.ROOT][host]['service_profiles'] = new_profiles
808
809     def get_pre_allocated_ips(self, host, network):
810         ips_field = "pre_allocated_ips"
811         self._validate_hostname(host)
812         if (ips_field not in self.config[self.ROOT][host]
813                 or network not in self.config[self.ROOT][host][ips_field]):
814             return None
815         return self.config[self.ROOT][host][ips_field][network]
816
817     def allocate_port(self, host, base, name):
818         used_ports = []
819         hosts = self.get_hosts()
820         for node in hosts:
821             if name in self.config[self.ROOT][node]:
822                 used_ports.append(self.config[self.ROOT][node][name])
823
824         free_port = 0
825
826         for port in range(base, base+1000):
827             if port not in used_ports:
828                 free_port = port
829                 break
830
831         if free_port == 0:
832             raise configerror.ConfigError('No free ports available')
833
834         self.config[self.ROOT][host][name] = free_port
835
836     def add_vbmc_port(self, host):
837         base_vbmc_port = 61600
838         name = 'vbmc_port'
839         self._validate_hostname(host)
840         if name not in self.config[self.ROOT][host]:
841             self.allocate_port(host, base_vbmc_port, name)
842
843     def add_ipmi_terminal_port(self, host):
844         base_console_port = 61401
845         name = 'ipmi_terminal_port'
846         self._validate_hostname(host)
847         if name not in self.config[self.ROOT][host]:
848             self.allocate_port(host, base_console_port, name)
849
850     def get_ceph_osd_disks(self, host):
851         self._validate_hostname(host)
852         caas_disks = self.config[self.ROOT][host].get('caas_disks', [])
853         osd_disks = filter(lambda disk: disk.get('osd_disk', False), caas_disks)
854         return map(lambda disk: _get_path_for_virtio_id(disk), osd_disks)
855
856     def get_system_reserved_memory(self, hostname):
857         caasconf = self.confman.get_caas_config_handler()
858         if caasconf.is_vnf_embedded_deployment():
859             return VNF_EMBEDDED_RESERVED_MEMORY
860
861         profiles = self.get_service_profiles(hostname)
862         if 'controller' in profiles:
863             return DUAL_VIM_CONTROLLER_RESERVED_MEMORY
864         if 'compute' in profiles:
865             return DUAL_VIM_DEFAULT_RESERVED_MEMORY
866
867         return self.config.get(self.ROOT, {}).get('middleware_reserved_memory',
868                                                    MIDDLEWARE_RESERVED_MEMORY)
869
870     def set_default_reserved_memory_to_all_hosts(self, def_memory):
871         for host in self.get_hosts():
872             self.config[self.ROOT][host]['middleware_reserved_memory'] = def_memory
873
874     def set_default_ipmi_priv_level_to_all_hosts(self, def_priv):
875         for host in self.get_hosts():
876             if 'hwmgmt' not in self.config[self.ROOT][host]:
877                 self.config[self.ROOT][host]['hwmgmt'] = {'priv_level': def_priv}
878             elif 'priv_level' not in self.config[self.ROOT][host]['hwmgmt']:
879                 self.config[self.ROOT][host]['hwmgmt']['priv_level'] = def_priv
880
881
882 def _get_path_for_virtio_id(disk):
883     disk_id = disk.get('id', '')
884     if disk_id:
885         return "/dev/disk/by-id/virtio-{}".format(disk_id[:20])
886
887