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 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  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', 'images_vcenter', 'value'),
  100. 'images_vcenter', None),
  101. WhiteListRule(('storage', 'ephemeral_ceph', 'value'),
  102. 'ephemeral_ceph', None),
  103. WhiteListRule(('storage', 'objects_ceph', 'value'),
  104. 'objects_ceph', None),
  105. WhiteListRule(('storage', 'auth_s3_keystone_ceph', 'value'),
  106. 'auth_s3_keystone_ceph', None),
  107. WhiteListRule(('storage', 'osd_pool_size', 'value'),
  108. 'osd_pool_size', None),
  109. WhiteListRule(('storage', 'fsid', 'value'),
  110. 'fsid', None),
  111. WhiteListRule(('storage', 'mon_key', 'value'),
  112. 'mon_key', None),
  113. WhiteListRule(('storage', 'admin_key', 'value'),
  114. 'admin_key', None),
  115. WhiteListRule(('storage', 'bootstrap_osd_key', 'value'),
  116. 'bootstrap_osd_key', None),
  117. WhiteListRule(('storage', 'radosgw_key', 'value'),
  118. 'radosgw_key', None),
  119. WhiteListRule(('neutron_mellanox', 'plugin', 'value'),
  120. 'mellanox', None),
  121. WhiteListRule(('neutron_mellanox', 'vf_num', 'value'),
  122. 'mellanox_vf_num', None),
  123. WhiteListRule(('additional_components', 'sahara', 'value'),
  124. 'sahara', None),
  125. WhiteListRule(('additional_components', 'murano', 'value'),
  126. 'murano', None),
  127. WhiteListRule(('additional_components', 'murano-cfapi', 'value'),
  128. 'murano-cfapi', None),
  129. WhiteListRule(('additional_components', 'heat', 'value'),
  130. 'heat', None),
  131. WhiteListRule(('additional_components', 'ceilometer', 'value'),
  132. 'ceilometer', None),
  133. WhiteListRule(('additional_components', 'mongo', 'value'),
  134. 'mongo', None),
  135. WhiteListRule(('additional_components', 'ironic', 'value'),
  136. 'ironic', None),
  137. WhiteListRule(('murano_settings',
  138. 'murano_glance_artifacts_plugin', 'value'),
  139. 'murano_glance_artifacts_plugin', None),
  140. WhiteListRule(('workloads_collector', 'enabled', 'value'),
  141. 'workloads_collector_enabled', None),
  142. WhiteListRule(('public_ssl', 'horizon', 'value'),
  143. 'public_ssl_horizon', None),
  144. WhiteListRule(('public_ssl', 'services', 'value'),
  145. 'public_ssl_services', None),
  146. WhiteListRule(('public_ssl', 'cert_source', 'value'),
  147. 'public_ssl_cert_source', None),
  148. WhiteListRule(('ssh', 'security_enabled', 'value'),
  149. 'security_enabled', bool),
  150. WhiteListRule(('ssh', 'security_networks', 'value'),
  151. 'security_networks', None),
  152. WhiteListRule(('ssh', 'brute_force_protection', 'value'),
  153. 'brute_force_protection', bool),
  154. )
  155. vmware_attributes_white_list = (
  156. # ((path, to, property), 'map_to_name', transform_function)
  157. WhiteListRule(('value', 'availability_zones', 'cinder', 'enable'),
  158. 'vmware_az_cinder_enable', None),
  159. # We add 'vsphere_cluster' into path for enter into nested list.
  160. # Private value of 'vsphere_cluster' is not collected, we only
  161. # computes length of the nested list
  162. WhiteListRule(('value', 'availability_zones', 'nova_computes',
  163. 'vsphere_cluster'), 'vmware_az_nova_computes_num', len),
  164. )
  165. plugin_info_white_list = (
  166. # ((path, to, property), 'map_to_name', transform_function)
  167. WhiteListRule(('id',), 'id', None),
  168. WhiteListRule(('name',), 'name', None),
  169. WhiteListRule(('version',), 'version', None),
  170. WhiteListRule(('releases',), 'releases', None),
  171. WhiteListRule(('fuel_version',), 'fuel_version', None),
  172. WhiteListRule(('package_version',), 'package_version', None),
  173. WhiteListRule(('groups',), 'groups', None),
  174. WhiteListRule(('licenses',), 'licenses', None),
  175. WhiteListRule(('is_hotpluggable',), 'is_hotpluggable', None),
  176. WhiteListRule(('attributes_metadata',), 'attributes_metadata', None),
  177. WhiteListRule(('volumes_metadata',), 'volumes_metadata', None),
  178. WhiteListRule(('roles_metadata',), 'roles_metadata', None),
  179. WhiteListRule(('tags_metadata',), 'tags_metadata', None),
  180. WhiteListRule(('network_roles_metadata',),
  181. 'network_roles_metadata', None),
  182. WhiteListRule(('components_metadata',), 'components_metadata', None),
  183. WhiteListRule(
  184. ('nic_attributes_metadata',), 'nic_attributes_metadata', None),
  185. WhiteListRule(
  186. ('bond_attributes_metadata',), 'bond_attributes_metadata', None),
  187. WhiteListRule(
  188. ('node_attributes_metadata',), 'node_attributes_metadata', None),
  189. WhiteListRule(('deployment_tasks',), 'deployment_tasks', None),
  190. WhiteListRule(('tasks',), 'tasks', None),
  191. )
  192. node_info_white_list = (
  193. # ((path, to, property), 'map_to_name', transform_function)
  194. WhiteListRule(('id',), 'id', None),
  195. WhiteListRule(('group_id',), 'group_id', None),
  196. WhiteListRule(('cluster_id',), 'cluster_id', None),
  197. WhiteListRule(('name',), 'name', None),
  198. WhiteListRule(('labels',), 'labels', None),
  199. WhiteListRule(('roles',), 'roles', None),
  200. WhiteListRule(('primary_tags',), 'primary_tags', None),
  201. WhiteListRule(('os_platform',), 'os', None),
  202. WhiteListRule(('manufacturer',), 'manufacturer', None),
  203. WhiteListRule(('platform_name',), 'platform_name', None),
  204. WhiteListRule(('kernel_params',), 'kernel_params', None),
  205. WhiteListRule(('extensions',), 'extensions', None),
  206. WhiteListRule(('attributes',), 'attributes', None),
  207. WhiteListRule(('status',), 'status', None),
  208. WhiteListRule(('online',), 'online', None),
  209. WhiteListRule(('error_type',), 'error_type', None),
  210. WhiteListRule(('error_msg',), 'error_msg', None),
  211. WhiteListRule(('progress',), 'progress', None),
  212. WhiteListRule(('pending_addition',), 'pending_addition', None),
  213. WhiteListRule(('pending_deletion',), 'pending_deletion', None),
  214. WhiteListRule(('pending_roles',), 'pending_roles', None),
  215. WhiteListRule(('meta',), 'meta', None),
  216. WhiteListRule(('network_template',), 'network_template', None),
  217. WhiteListRule(('vms_conf',), 'vms_conf', None),
  218. )
  219. def fuel_release_info(self):
  220. return settings.VERSION
  221. def fuel_packages_info(self):
  222. command = ['rpm', '-q']
  223. command.extend(consts.STAT_FUEL_PACKAGES)
  224. p = subprocess.Popen(
  225. command,
  226. stdout=subprocess.PIPE,
  227. stderr=subprocess.PIPE)
  228. out, err = p.communicate()
  229. if p.poll() != 0:
  230. logger.error("Command '%s' failed. Error: %s",
  231. " ".join(command), err)
  232. return []
  233. return out.strip().split()
  234. def get_network_configuration_info(self, cluster):
  235. network_config = cluster.network_config
  236. result = {}
  237. if isinstance(network_config, NovaNetworkConfig):
  238. result['net_manager'] = network_config.net_manager
  239. result['fixed_networks_vlan_start'] = \
  240. network_config.fixed_networks_vlan_start
  241. result['fixed_network_size'] = network_config.fixed_network_size
  242. result['fixed_networks_amount'] = \
  243. network_config.fixed_networks_amount
  244. elif isinstance(network_config, NeutronConfig):
  245. result['segmentation_type'] = network_config.segmentation_type
  246. result['net_l23_provider'] = network_config.net_l23_provider
  247. return result
  248. def get_clusters_info(self):
  249. clusters = ClusterCollection.all()
  250. clusters_info = []
  251. for cluster in clusters:
  252. release = cluster.release
  253. nodes_num = NodeCollection.filter_by(
  254. None, cluster_id=cluster.id).count()
  255. vmware_attributes_editable = None
  256. if cluster.vmware_attributes:
  257. vmware_attributes_editable = cluster.vmware_attributes.editable
  258. cluster_info = {
  259. 'id': cluster.id,
  260. 'nodes_num': nodes_num,
  261. 'release': {
  262. 'os': release.operating_system,
  263. 'name': release.name,
  264. 'version': release.version
  265. },
  266. 'mode': cluster.mode,
  267. 'nodes': self.get_nodes_info(cluster.nodes),
  268. 'node_groups': self.get_node_groups_info(cluster.node_groups),
  269. 'status': cluster.status,
  270. 'extensions': cluster.extensions,
  271. 'attributes': self.get_attributes(
  272. Cluster.get_editable_attributes(cluster),
  273. self.attributes_white_list
  274. ),
  275. 'vmware_attributes': self.get_attributes(
  276. vmware_attributes_editable,
  277. self.vmware_attributes_white_list
  278. ),
  279. 'plugin_links': self.get_plugin_links(
  280. cluster.plugin_links),
  281. 'net_provider': cluster.net_provider,
  282. 'fuel_version': cluster.fuel_version,
  283. 'is_customized': cluster.is_customized,
  284. 'network_configuration': self.get_network_configuration_info(
  285. cluster),
  286. 'installed_plugins': self.get_cluster_plugins_info(cluster),
  287. 'components': cluster.components,
  288. 'cluster_plugins': cluster.cluster_plugins,
  289. 'roles_metadata': cluster.roles_metadata,
  290. 'tags_metadata': cluster.tags_metadata,
  291. 'volumes_metadata': cluster.volumes_metadata,
  292. }
  293. clusters_info.append(cluster_info)
  294. return clusters_info
  295. def get_cluster_plugins_info(self, cluster):
  296. plugins_info = []
  297. for plugin_inst in ClusterPlugin.get_enabled(cluster.id):
  298. plugin_info = self.get_attributes(plugin_inst.__dict__,
  299. self.plugin_info_white_list)
  300. plugins_info.append(plugin_info)
  301. return plugins_info
  302. def get_attributes(self, attributes, white_list):
  303. result_attrs = {}
  304. for path, map_to_name, func in white_list:
  305. try:
  306. result_attrs[map_to_name] = get_attr_value(
  307. path, func, attributes)
  308. except (KeyError, TypeError):
  309. pass
  310. return result_attrs
  311. def get_node_meta(self, node):
  312. meta = copy.deepcopy(node.meta)
  313. if not meta:
  314. return {}
  315. if isinstance(meta.get('system'), dict):
  316. meta['system'].pop('fqdn', None)
  317. meta['system'].pop('serial', None)
  318. if isinstance(meta.get('interfaces'), list):
  319. for interface in meta['interfaces']:
  320. if isinstance(interface, dict):
  321. interface.pop('mac', None)
  322. return meta
  323. def get_nodes_info(self, nodes):
  324. nodes_info = []
  325. for node in nodes:
  326. node_info = self.get_attributes(node, self.node_info_white_list)
  327. node_info['meta'] = self.get_node_meta(node)
  328. node_info['nic_interfaces'] = self.get_node_intefaces_info(
  329. node.nic_interfaces, bond=False)
  330. node_info['bond_interfaces'] = self.get_node_intefaces_info(
  331. node.bond_interfaces, bond=True)
  332. nodes_info.append(node_info)
  333. return nodes_info
  334. def get_node_intefaces_info(self, interfaces, bond):
  335. ifs_info = []
  336. for interface in interfaces:
  337. if_info = {
  338. 'id': interface.id
  339. }
  340. if bond:
  341. if_info['slaves'] = [s.id for s in interface.slaves]
  342. ifs_info.append(if_info)
  343. return ifs_info
  344. def get_node_groups_info(self, node_groups):
  345. groups_info = []
  346. for group in node_groups:
  347. group_info = {
  348. 'id': group.id,
  349. 'nodes': [n.id for n in group.nodes]
  350. }
  351. groups_info.append(group_info)
  352. return groups_info
  353. def get_plugin_links(self, plugin_links):
  354. return [{'id': e.id, 'title': e.title, 'description': e.description,
  355. 'hidden': e.hidden} for e in plugin_links]
  356. def get_installation_info(self):
  357. clusters_info = self.get_clusters_info()
  358. allocated_nodes_num = sum([c['nodes_num'] for c in clusters_info])
  359. unallocated_nodes_num = NodeCollection.filter_by(
  360. None, cluster_id=None).count()
  361. info = {
  362. 'user_information': self.get_user_info(),
  363. 'master_node_uid': self.get_master_node_uid(),
  364. 'fuel_release': self.fuel_release_info(),
  365. 'fuel_packages': self.fuel_packages_info(),
  366. 'clusters': clusters_info,
  367. 'clusters_num': len(clusters_info),
  368. 'allocated_nodes_num': allocated_nodes_num,
  369. 'unallocated_nodes_num': unallocated_nodes_num
  370. }
  371. return info
  372. def get_master_node_uid(self):
  373. return getattr(MasterNodeSettings.get_one(), 'master_node_uid', None)
  374. def get_user_info(self):
  375. try:
  376. stat_settings = MasterNodeSettings.get_one(). \
  377. settings.get("statistics", {})
  378. result = {
  379. "contact_info_provided":
  380. stat_settings.get("user_choice_saved", {}).get("value", False)
  381. and stat_settings.get("send_user_info", {}).get("value", False)
  382. }
  383. if result["contact_info_provided"]:
  384. result["name"] = stat_settings.get("name", {}).get("value")
  385. result["email"] = stat_settings.get("email", {}).get("value")
  386. result["company"] = stat_settings.get("company", {}).\
  387. get("value")
  388. return result
  389. except AttributeError:
  390. return {"contact_info_provided": False}