Fuel UI
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

installation_info.py 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. # Copyright 2014 Mirantis, Inc.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. # not use this file except in compliance with the License. You may obtain
  5. # 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, WITHOUT
  11. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. # License for the specific language governing permissions and limitations
  13. # under the License.
  14. import copy
  15. import subprocess
  16. from nailgun import consts
  17. from nailgun.db.sqlalchemy.models import NeutronConfig
  18. from nailgun.db.sqlalchemy.models import NovaNetworkConfig
  19. from nailgun.logger import logger
  20. from nailgun.objects import Cluster
  21. from nailgun.objects import ClusterCollection
  22. from nailgun.objects import MasterNodeSettings
  23. from nailgun.objects import NodeCollection
  24. from nailgun.objects.plugin import ClusterPlugin
  25. from nailgun.settings import settings
  26. from nailgun.statistics.utils import get_attr_value
  27. from nailgun.statistics.utils import WhiteListRule
  28. class InstallationInfo(object):
  29. """Collects info about Fuel installation
  30. Includes master nodes, clusters, networks, etc.
  31. Used for collecting info for fuel statistics
  32. """
  33. attributes_white_list = (
  34. # ((path, to, property), 'map_to_name', transform_function)
  35. WhiteListRule(('common', 'libvirt_type', 'value'),
  36. 'libvirt_type', None),
  37. WhiteListRule(('common', 'debug', 'value'), 'debug_mode', None),
  38. WhiteListRule(('common', 'use_cow_images', 'value'),
  39. 'use_cow_images', None),
  40. WhiteListRule(('common', 'auto_assign_floating_ip', 'value'),
  41. 'auto_assign_floating_ip', None),
  42. WhiteListRule(('common', 'nova_quota', 'value'), 'nova_quota', None),
  43. WhiteListRule(('common', 'puppet_debug', 'value'),
  44. 'puppet_debug', None),
  45. WhiteListRule(('common', 'resume_guests_state_on_host_boot', 'value'),
  46. 'resume_guests_state_on_host_boot', None),
  47. WhiteListRule(('common', 'task_deploy', 'value'),
  48. 'task_deploy', None),
  49. WhiteListRule(('common', 'propagate_task_deploy', 'value'),
  50. 'propagate_task_deploy', None),
  51. WhiteListRule(('common', 'security_groups', 'value'),
  52. 'security_groups', None),
  53. WhiteListRule(('corosync', 'verified', 'value'),
  54. 'corosync_verified', None),
  55. WhiteListRule(('public_network_assignment', 'assign_to_all_nodes',
  56. 'value'), 'assign_public_to_all_nodes', None),
  57. WhiteListRule(('neutron_advanced_configuration', 'neutron_l2_pop',
  58. 'value'), 'neutron_l2_pop', None),
  59. WhiteListRule(('neutron_advanced_configuration', 'neutron_dvr',
  60. 'value'), 'neutron_dvr', None),
  61. WhiteListRule(('neutron_advanced_configuration', 'neutron_l3_ha',
  62. 'value'), 'neutron_l3_ha', None),
  63. WhiteListRule(('neutron_advanced_configuration', 'neutron_qos',
  64. 'value'), 'neutron_qos', None),
  65. WhiteListRule(('syslog', 'syslog_transport', 'value'),
  66. 'syslog_transport', None),
  67. WhiteListRule(('atop', 'service_enabled', 'value'),
  68. 'service_enabled', bool),
  69. WhiteListRule(('atop', 'interval', 'value'),
  70. 'interval', None),
  71. WhiteListRule(('atop', 'rotate', 'value'),
  72. 'rotate', None),
  73. WhiteListRule(('provision', 'method', 'value'),
  74. 'provision_method', None),
  75. WhiteListRule(('kernel_params', 'kernel', 'value'),
  76. 'kernel_params', None),
  77. WhiteListRule(('external_mongo', 'mongo_replset', 'value'),
  78. 'external_mongo_replset', bool),
  79. WhiteListRule(('external_ntp', 'ntp_list', 'value'),
  80. 'external_ntp_list', bool),
  81. WhiteListRule(('repo_setup', 'repos', 'value'), 'repos', None),
  82. WhiteListRule(('repo_setup', 'pin_ceph', 'value'),
  83. 'pin_ceph', bool),
  84. WhiteListRule(('repo_setup', 'pin_haproxy', 'value'),
  85. 'pin_haproxy', bool),
  86. WhiteListRule(('repo_setup', 'pin_rabbitmq', 'value'),
  87. 'pin_rabbitmq', bool),
  88. WhiteListRule(('repo_setup', 'repo_type', 'value'),
  89. 'repo_type', None),
  90. WhiteListRule(('storage', 'volumes_lvm', 'value'),
  91. 'volumes_lvm', None),
  92. WhiteListRule(('storage', 'iser', 'value'), 'iser', None),
  93. WhiteListRule(('storage', 'volumes_block_device', 'value'),
  94. 'volumes_block_device', None),
  95. WhiteListRule(('storage', 'volumes_ceph', 'value'),
  96. 'volumes_ceph', None),
  97. WhiteListRule(('storage', 'images_ceph', 'value'),
  98. 'images_ceph', None),
  99. WhiteListRule(('storage', 'ephemeral_ceph', 'value'),
  100. 'ephemeral_ceph', None),
  101. WhiteListRule(('storage', 'objects_ceph', 'value'),
  102. 'objects_ceph', None),
  103. WhiteListRule(('storage', 'auth_s3_keystone_ceph', 'value'),
  104. 'auth_s3_keystone_ceph', None),
  105. WhiteListRule(('storage', 'osd_pool_size', 'value'),
  106. 'osd_pool_size', None),
  107. WhiteListRule(('storage', 'fsid', 'value'),
  108. 'fsid', None),
  109. WhiteListRule(('storage', 'mon_key', 'value'),
  110. 'mon_key', None),
  111. WhiteListRule(('storage', 'admin_key', 'value'),
  112. 'admin_key', None),
  113. WhiteListRule(('storage', 'bootstrap_osd_key', 'value'),
  114. 'bootstrap_osd_key', None),
  115. WhiteListRule(('storage', 'radosgw_key', 'value'),
  116. 'radosgw_key', None),
  117. WhiteListRule(('neutron_mellanox', 'plugin', 'value'),
  118. 'mellanox', None),
  119. WhiteListRule(('neutron_mellanox', 'vf_num', 'value'),
  120. 'mellanox_vf_num', None),
  121. WhiteListRule(('additional_components', 'sahara', 'value'),
  122. 'sahara', None),
  123. WhiteListRule(('additional_components', 'murano', 'value'),
  124. 'murano', None),
  125. WhiteListRule(('additional_components', 'murano-cfapi', 'value'),
  126. 'murano-cfapi', None),
  127. WhiteListRule(('additional_components', 'heat', 'value'),
  128. 'heat', None),
  129. WhiteListRule(('additional_components', 'ceilometer', 'value'),
  130. 'ceilometer', None),
  131. WhiteListRule(('additional_components', 'mongo', 'value'),
  132. 'mongo', None),
  133. WhiteListRule(('additional_components', 'ironic', 'value'),
  134. 'ironic', None),
  135. WhiteListRule(('murano_settings',
  136. 'murano_glance_artifacts_plugin', 'value'),
  137. 'murano_glance_artifacts_plugin', None),
  138. WhiteListRule(('workloads_collector', 'enabled', 'value'),
  139. 'workloads_collector_enabled', None),
  140. WhiteListRule(('public_ssl', 'horizon', 'value'),
  141. 'public_ssl_horizon', None),
  142. WhiteListRule(('public_ssl', 'services', 'value'),
  143. 'public_ssl_services', None),
  144. WhiteListRule(('public_ssl', 'cert_source', 'value'),
  145. 'public_ssl_cert_source', None),
  146. WhiteListRule(('ssh', 'security_enabled', 'value'),
  147. 'security_enabled', bool),
  148. WhiteListRule(('ssh', 'security_networks', 'value'),
  149. 'security_networks', None),
  150. WhiteListRule(('ssh', 'brute_force_protection', 'value'),
  151. 'brute_force_protection', bool),
  152. )
  153. plugin_info_white_list = (
  154. # ((path, to, property), 'map_to_name', transform_function)
  155. WhiteListRule(('id',), 'id', None),
  156. WhiteListRule(('name',), 'name', None),
  157. WhiteListRule(('version',), 'version', None),
  158. WhiteListRule(('releases',), 'releases', None),
  159. WhiteListRule(('fuel_version',), 'fuel_version', None),
  160. WhiteListRule(('package_version',), 'package_version', None),
  161. WhiteListRule(('groups',), 'groups', None),
  162. WhiteListRule(('licenses',), 'licenses', None),
  163. WhiteListRule(('is_hotpluggable',), 'is_hotpluggable', None),
  164. WhiteListRule(('attributes_metadata',), 'attributes_metadata', None),
  165. WhiteListRule(('volumes_metadata',), 'volumes_metadata', None),
  166. WhiteListRule(('roles_metadata',), 'roles_metadata', None),
  167. WhiteListRule(('tags_metadata',), 'tags_metadata', None),
  168. WhiteListRule(('network_roles_metadata',),
  169. 'network_roles_metadata', None),
  170. WhiteListRule(('components_metadata',), 'components_metadata', None),
  171. WhiteListRule(
  172. ('nic_attributes_metadata',), 'nic_attributes_metadata', None),
  173. WhiteListRule(
  174. ('bond_attributes_metadata',), 'bond_attributes_metadata', None),
  175. WhiteListRule(
  176. ('node_attributes_metadata',), 'node_attributes_metadata', None),
  177. WhiteListRule(('deployment_tasks',), 'deployment_tasks', None),
  178. WhiteListRule(('tasks',), 'tasks', None),
  179. )
  180. node_info_white_list = (
  181. # ((path, to, property), 'map_to_name', transform_function)
  182. WhiteListRule(('id',), 'id', None),
  183. WhiteListRule(('group_id',), 'group_id', None),
  184. WhiteListRule(('cluster_id',), 'cluster_id', None),
  185. WhiteListRule(('name',), 'name', None),
  186. WhiteListRule(('labels',), 'labels', None),
  187. WhiteListRule(('roles',), 'roles', None),
  188. WhiteListRule(('primary_tags',), 'primary_tags', None),
  189. WhiteListRule(('os_platform',), 'os', None),
  190. WhiteListRule(('manufacturer',), 'manufacturer', None),
  191. WhiteListRule(('platform_name',), 'platform_name', None),
  192. WhiteListRule(('kernel_params',), 'kernel_params', None),
  193. WhiteListRule(('extensions',), 'extensions', None),
  194. WhiteListRule(('attributes',), 'attributes', None),
  195. WhiteListRule(('status',), 'status', None),
  196. WhiteListRule(('online',), 'online', None),
  197. WhiteListRule(('error_type',), 'error_type', None),
  198. WhiteListRule(('error_msg',), 'error_msg', None),
  199. WhiteListRule(('progress',), 'progress', None),
  200. WhiteListRule(('pending_addition',), 'pending_addition', None),
  201. WhiteListRule(('pending_deletion',), 'pending_deletion', None),
  202. WhiteListRule(('pending_roles',), 'pending_roles', None),
  203. WhiteListRule(('meta',), 'meta', None),
  204. WhiteListRule(('network_template',), 'network_template', None),
  205. WhiteListRule(('vms_conf',), 'vms_conf', None),
  206. )
  207. def fuel_release_info(self):
  208. return settings.VERSION
  209. def fuel_packages_info(self):
  210. command = ['rpm', '-q']
  211. command.extend(consts.STAT_FUEL_PACKAGES)
  212. p = subprocess.Popen(
  213. command,
  214. stdout=subprocess.PIPE,
  215. stderr=subprocess.PIPE)
  216. out, err = p.communicate()
  217. if p.poll() != 0:
  218. logger.error("Command '%s' failed. Error: %s",
  219. " ".join(command), err)
  220. return []
  221. return out.strip().split()
  222. def get_network_configuration_info(self, cluster):
  223. network_config = cluster.network_config
  224. result = {}
  225. if isinstance(network_config, NovaNetworkConfig):
  226. result['net_manager'] = network_config.net_manager
  227. result['fixed_networks_vlan_start'] = \
  228. network_config.fixed_networks_vlan_start
  229. result['fixed_network_size'] = network_config.fixed_network_size
  230. result['fixed_networks_amount'] = \
  231. network_config.fixed_networks_amount
  232. elif isinstance(network_config, NeutronConfig):
  233. result['segmentation_type'] = network_config.segmentation_type
  234. result['net_l23_provider'] = network_config.net_l23_provider
  235. return result
  236. def get_clusters_info(self):
  237. clusters = ClusterCollection.all()
  238. clusters_info = []
  239. for cluster in clusters:
  240. release = cluster.release
  241. nodes_num = NodeCollection.filter_by(
  242. None, cluster_id=cluster.id).count()
  243. cluster_info = {
  244. 'id': cluster.id,
  245. 'nodes_num': nodes_num,
  246. 'release': {
  247. 'os': release.operating_system,
  248. 'name': release.name,
  249. 'version': release.version
  250. },
  251. 'mode': cluster.mode,
  252. 'nodes': self.get_nodes_info(cluster.nodes),
  253. 'node_groups': self.get_node_groups_info(cluster.node_groups),
  254. 'status': cluster.status,
  255. 'extensions': cluster.extensions,
  256. 'attributes': self.get_attributes(
  257. Cluster.get_editable_attributes(cluster),
  258. self.attributes_white_list
  259. ),
  260. 'plugin_links': self.get_plugin_links(
  261. cluster.plugin_links),
  262. 'net_provider': cluster.net_provider,
  263. 'fuel_version': cluster.fuel_version,
  264. 'is_customized': cluster.is_customized,
  265. 'network_configuration': self.get_network_configuration_info(
  266. cluster),
  267. 'installed_plugins': self.get_cluster_plugins_info(cluster),
  268. 'components': cluster.components,
  269. 'cluster_plugins': cluster.cluster_plugins,
  270. 'roles_metadata': cluster.roles_metadata,
  271. 'tags_metadata': cluster.tags_metadata,
  272. 'volumes_metadata': cluster.volumes_metadata,
  273. }
  274. clusters_info.append(cluster_info)
  275. return clusters_info
  276. def get_cluster_plugins_info(self, cluster):
  277. plugins_info = []
  278. for plugin_inst in ClusterPlugin.get_enabled(cluster.id):
  279. plugin_info = self.get_attributes(plugin_inst.__dict__,
  280. self.plugin_info_white_list)
  281. plugins_info.append(plugin_info)
  282. return plugins_info
  283. def get_attributes(self, attributes, white_list):
  284. result_attrs = {}
  285. for path, map_to_name, func in white_list:
  286. try:
  287. result_attrs[map_to_name] = get_attr_value(
  288. path, func, attributes)
  289. except (KeyError, TypeError):
  290. pass
  291. return result_attrs
  292. def get_node_meta(self, node):
  293. meta = copy.deepcopy(node.meta)
  294. if not meta:
  295. return {}
  296. if isinstance(meta.get('system'), dict):
  297. meta['system'].pop('fqdn', None)
  298. meta['system'].pop('serial', None)
  299. if isinstance(meta.get('interfaces'), list):
  300. for interface in meta['interfaces']:
  301. if isinstance(interface, dict):
  302. interface.pop('mac', None)
  303. return meta
  304. def get_nodes_info(self, nodes):
  305. nodes_info = []
  306. for node in nodes:
  307. node_info = self.get_attributes(node, self.node_info_white_list)
  308. node_info['meta'] = self.get_node_meta(node)
  309. node_info['nic_interfaces'] = self.get_node_intefaces_info(
  310. node.nic_interfaces, bond=False)
  311. node_info['bond_interfaces'] = self.get_node_intefaces_info(
  312. node.bond_interfaces, bond=True)
  313. nodes_info.append(node_info)
  314. return nodes_info
  315. def get_node_intefaces_info(self, interfaces, bond):
  316. ifs_info = []
  317. for interface in interfaces:
  318. if_info = {
  319. 'id': interface.id
  320. }
  321. if bond:
  322. if_info['slaves'] = [s.id for s in interface.slaves]
  323. ifs_info.append(if_info)
  324. return ifs_info
  325. def get_node_groups_info(self, node_groups):
  326. groups_info = []
  327. for group in node_groups:
  328. group_info = {
  329. 'id': group.id,
  330. 'nodes': [n.id for n in group.nodes]
  331. }
  332. groups_info.append(group_info)
  333. return groups_info
  334. def get_plugin_links(self, plugin_links):
  335. return [{'id': e.id, 'title': e.title, 'description': e.description,
  336. 'hidden': e.hidden} for e in plugin_links]
  337. def get_installation_info(self):
  338. clusters_info = self.get_clusters_info()
  339. allocated_nodes_num = sum([c['nodes_num'] for c in clusters_info])
  340. unallocated_nodes_num = NodeCollection.filter_by(
  341. None, cluster_id=None).count()
  342. info = {
  343. 'user_information': self.get_user_info(),
  344. 'master_node_uid': self.get_master_node_uid(),
  345. 'fuel_release': self.fuel_release_info(),
  346. 'fuel_packages': self.fuel_packages_info(),
  347. 'clusters': clusters_info,
  348. 'clusters_num': len(clusters_info),
  349. 'allocated_nodes_num': allocated_nodes_num,
  350. 'unallocated_nodes_num': unallocated_nodes_num
  351. }
  352. return info
  353. def get_master_node_uid(self):
  354. return getattr(MasterNodeSettings.get_one(), 'master_node_uid', None)
  355. def get_user_info(self):
  356. try:
  357. stat_settings = MasterNodeSettings.get_one(). \
  358. settings.get("statistics", {})
  359. result = {
  360. "contact_info_provided":
  361. stat_settings.get("user_choice_saved", {}).get("value", False)
  362. and stat_settings.get("send_user_info", {}).get("value", False)
  363. }
  364. if result["contact_info_provided"]:
  365. result["name"] = stat_settings.get("name", {}).get("value")
  366. result["email"] = stat_settings.get("email", {}).get("value")
  367. result["company"] = stat_settings.get("company", {}).\
  368. get("value")
  369. return result
  370. except AttributeError:
  371. return {"contact_info_provided": False}