mirror of
				https://github.com/ansible-collections/community.general.git
				synced 2025-10-26 05:50:36 -07:00 
			
		
		
		
	
		
			Some checks are pending
		
		
	
	EOL CI / EOL Sanity (Ⓐ2.16) (push) Waiting to run
				
			EOL CI / EOL Units (Ⓐ2.16+py2.7) (push) Waiting to run
				
			EOL CI / EOL Units (Ⓐ2.16+py3.11) (push) Waiting to run
				
			EOL CI / EOL Units (Ⓐ2.16+py3.6) (push) Waiting to run
				
			EOL CI / EOL I (Ⓐ2.16+alpine3+py:azp/posix/1/) (push) Waiting to run
				
			EOL CI / EOL I (Ⓐ2.16+alpine3+py:azp/posix/2/) (push) Waiting to run
				
			EOL CI / EOL I (Ⓐ2.16+alpine3+py:azp/posix/3/) (push) Waiting to run
				
			EOL CI / EOL I (Ⓐ2.16+fedora38+py:azp/posix/1/) (push) Waiting to run
				
			EOL CI / EOL I (Ⓐ2.16+fedora38+py:azp/posix/2/) (push) Waiting to run
				
			EOL CI / EOL I (Ⓐ2.16+fedora38+py:azp/posix/3/) (push) Waiting to run
				
			EOL CI / EOL I (Ⓐ2.16+opensuse15+py:azp/posix/1/) (push) Waiting to run
				
			EOL CI / EOL I (Ⓐ2.16+opensuse15+py:azp/posix/2/) (push) Waiting to run
				
			EOL CI / EOL I (Ⓐ2.16+opensuse15+py:azp/posix/3/) (push) Waiting to run
				
			nox / Run extra sanity tests (push) Waiting to run
				
			* doc style adjustments: modules e* * doc style adjustments: modules f* * doc style adjustments: modules g* * doc style adjustments: modules h* * Update plugins/modules/easy_install.py Co-authored-by: Felix Fontein <felix@fontein.de> --------- Co-authored-by: Felix Fontein <felix@fontein.de>
		
			
				
	
	
		
			267 lines
		
	
	
	
		
			8.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			267 lines
		
	
	
	
		
			8.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/python
 | |
| # -*- coding: utf-8 -*-
 | |
| 
 | |
| # Copyright 2012 Dag Wieers <dag@wieers.com>
 | |
| # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
 | |
| # SPDX-License-Identifier: GPL-3.0-or-later
 | |
| 
 | |
| from __future__ import absolute_import, division, print_function
 | |
| __metaclass__ = type
 | |
| 
 | |
| 
 | |
| DOCUMENTATION = r"""
 | |
| module: hpilo_info
 | |
| author: Dag Wieers (@dagwieers)
 | |
| short_description: Gather information through an HP iLO interface
 | |
| description:
 | |
|   - This module gathers information on a specific system using its HP iLO interface. These information includes hardware and
 | |
|     network related information useful for provisioning (for example macaddress, uuid).
 | |
|   - This module requires the C(hpilo) python module.
 | |
| extends_documentation_fragment:
 | |
|   - community.general.attributes
 | |
|   - community.general.attributes.info_module
 | |
| options:
 | |
|   host:
 | |
|     description:
 | |
|       - The HP iLO hostname/address that is linked to the physical system.
 | |
|     type: str
 | |
|     required: true
 | |
|   login:
 | |
|     description:
 | |
|       - The login name to authenticate to the HP iLO interface.
 | |
|     type: str
 | |
|     default: Administrator
 | |
|   password:
 | |
|     description:
 | |
|       - The password to authenticate to the HP iLO interface.
 | |
|     type: str
 | |
|     default: admin
 | |
|   ssl_version:
 | |
|     description:
 | |
|       - Change the ssl_version used.
 | |
|     default: TLSv1
 | |
|     type: str
 | |
|     choices: ["SSLv3", "SSLv23", "TLSv1", "TLSv1_1", "TLSv1_2"]
 | |
| requirements:
 | |
|   - hpilo
 | |
| notes:
 | |
|   - This module ought to be run from a system that can access the HP iLO interface directly, either by using C(local_action)
 | |
|     or using C(delegate_to).
 | |
| """
 | |
| 
 | |
| EXAMPLES = r"""
 | |
| - name: Gather facts from a HP iLO interface only if the system is an HP server
 | |
|   community.general.hpilo_info:
 | |
|     host: YOUR_ILO_ADDRESS
 | |
|     login: YOUR_ILO_LOGIN
 | |
|     password: YOUR_ILO_PASSWORD
 | |
|   when: cmdb_hwmodel.startswith('HP ')
 | |
|   delegate_to: localhost
 | |
|   register: results
 | |
| 
 | |
| - ansible.builtin.fail:
 | |
|     msg: 'CMDB serial ({{ cmdb_serialno }}) does not match hardware serial ({{ results.hw_system_serial }}) !'
 | |
|   when: cmdb_serialno != results.hw_system_serial
 | |
| """
 | |
| 
 | |
| RETURN = r"""
 | |
| # Typical output of HP iLO_info for a physical system
 | |
| hw_bios_date:
 | |
|   description: BIOS date.
 | |
|   returned: always
 | |
|   type: str
 | |
|   sample: 05/05/2011
 | |
| 
 | |
| hw_bios_version:
 | |
|   description: BIOS version.
 | |
|   returned: always
 | |
|   type: str
 | |
|   sample: P68
 | |
| 
 | |
| hw_ethX:
 | |
|   description: Interface information (for each interface).
 | |
|   returned: always
 | |
|   type: dict
 | |
|   sample:
 | |
|     - macaddress: 00:11:22:33:44:55
 | |
|       macaddress_dash: 00-11-22-33-44-55
 | |
| 
 | |
| hw_eth_ilo:
 | |
|   description: Interface information (for the iLO network interface).
 | |
|   returned: always
 | |
|   type: dict
 | |
|   sample:
 | |
|     - macaddress: 00:11:22:33:44:BA
 | |
|     - macaddress_dash: 00-11-22-33-44-BA
 | |
| 
 | |
| hw_product_name:
 | |
|   description: Product name.
 | |
|   returned: always
 | |
|   type: str
 | |
|   sample: ProLiant DL360 G7
 | |
| 
 | |
| hw_product_uuid:
 | |
|   description: Product UUID.
 | |
|   returned: always
 | |
|   type: str
 | |
|   sample: ef50bac8-2845-40ff-81d9-675315501dac
 | |
| 
 | |
| hw_system_serial:
 | |
|   description: System serial number.
 | |
|   returned: always
 | |
|   type: str
 | |
|   sample: ABC12345D6
 | |
| 
 | |
| hw_uuid:
 | |
|   description: Hardware UUID.
 | |
|   returned: always
 | |
|   type: str
 | |
|   sample: 123456ABC78901D2
 | |
| 
 | |
| host_power_status:
 | |
|   description:
 | |
|     - Power status of host.
 | |
|     - It is one of V(ON), V(OFF) and V(UNKNOWN).
 | |
|   returned: always
 | |
|   type: str
 | |
|   sample: "ON"
 | |
|   version_added: 3.5.0
 | |
| """
 | |
| 
 | |
| import re
 | |
| import traceback
 | |
| import warnings
 | |
| 
 | |
| HPILO_IMP_ERR = None
 | |
| try:
 | |
|     import hpilo
 | |
|     HAS_HPILO = True
 | |
| except ImportError:
 | |
|     HPILO_IMP_ERR = traceback.format_exc()
 | |
|     HAS_HPILO = False
 | |
| 
 | |
| from ansible.module_utils.basic import AnsibleModule, missing_required_lib
 | |
| from ansible.module_utils.common.text.converters import to_native
 | |
| 
 | |
| 
 | |
| # Suppress warnings from hpilo
 | |
| warnings.simplefilter('ignore')
 | |
| 
 | |
| 
 | |
| def parse_flat_interface(entry, non_numeric='hw_eth_ilo'):
 | |
|     try:
 | |
|         infoname = 'hw_eth' + str(int(entry['Port']) - 1)
 | |
|     except Exception:
 | |
|         infoname = non_numeric
 | |
| 
 | |
|     info = {
 | |
|         'macaddress': entry['MAC'].replace('-', ':'),
 | |
|         'macaddress_dash': entry['MAC']
 | |
|     }
 | |
|     return (infoname, info)
 | |
| 
 | |
| 
 | |
| def main():
 | |
| 
 | |
|     module = AnsibleModule(
 | |
|         argument_spec=dict(
 | |
|             host=dict(type='str', required=True),
 | |
|             login=dict(type='str', default='Administrator'),
 | |
|             password=dict(type='str', default='admin', no_log=True),
 | |
|             ssl_version=dict(type='str', default='TLSv1', choices=['SSLv3', 'SSLv23', 'TLSv1', 'TLSv1_1', 'TLSv1_2']),
 | |
|         ),
 | |
|         supports_check_mode=True,
 | |
|     )
 | |
| 
 | |
|     if not HAS_HPILO:
 | |
|         module.fail_json(msg=missing_required_lib('python-hpilo'), exception=HPILO_IMP_ERR)
 | |
| 
 | |
|     host = module.params['host']
 | |
|     login = module.params['login']
 | |
|     password = module.params['password']
 | |
|     ssl_version = getattr(hpilo.ssl, 'PROTOCOL_' + module.params.get('ssl_version').upper().replace('V', 'v'))
 | |
| 
 | |
|     ilo = hpilo.Ilo(host, login=login, password=password, ssl_version=ssl_version)
 | |
| 
 | |
|     info = {
 | |
|         'module_hw': True,
 | |
|     }
 | |
| 
 | |
|     # TODO: Count number of CPUs, DIMMs and total memory
 | |
|     try:
 | |
|         data = ilo.get_host_data()
 | |
|         power_state = ilo.get_host_power_status()
 | |
|     except hpilo.IloCommunicationError as e:
 | |
|         module.fail_json(msg=to_native(e))
 | |
| 
 | |
|     for entry in data:
 | |
|         if 'type' not in entry:
 | |
|             continue
 | |
|         elif entry['type'] == 0:  # BIOS Information
 | |
|             info['hw_bios_version'] = entry['Family']
 | |
|             info['hw_bios_date'] = entry['Date']
 | |
|         elif entry['type'] == 1:  # System Information
 | |
|             info['hw_uuid'] = entry['UUID']
 | |
|             info['hw_system_serial'] = entry['Serial Number'].rstrip()
 | |
|             info['hw_product_name'] = entry['Product Name']
 | |
|             info['hw_product_uuid'] = entry['cUUID']
 | |
|         elif entry['type'] == 209:  # Embedded NIC MAC Assignment
 | |
|             if 'fields' in entry:
 | |
|                 for (name, value) in [(e['name'], e['value']) for e in entry['fields']]:
 | |
|                     if name.startswith('Port'):
 | |
|                         try:
 | |
|                             infoname = 'hw_eth' + str(int(value) - 1)
 | |
|                         except Exception:
 | |
|                             infoname = 'hw_eth_ilo'
 | |
|                     elif name.startswith('MAC'):
 | |
|                         info[infoname] = {
 | |
|                             'macaddress': value.replace('-', ':'),
 | |
|                             'macaddress_dash': value
 | |
|                         }
 | |
|             else:
 | |
|                 (infoname, entry_info) = parse_flat_interface(entry, 'hw_eth_ilo')
 | |
|                 info[infoname] = entry_info
 | |
|         elif entry['type'] == 209:  # HPQ NIC iSCSI MAC Info
 | |
|             for (name, value) in [(e['name'], e['value']) for e in entry['fields']]:
 | |
|                 if name.startswith('Port'):
 | |
|                     try:
 | |
|                         infoname = 'hw_iscsi' + str(int(value) - 1)
 | |
|                     except Exception:
 | |
|                         infoname = 'hw_iscsi_ilo'
 | |
|                 elif name.startswith('MAC'):
 | |
|                     info[infoname] = {
 | |
|                         'macaddress': value.replace('-', ':'),
 | |
|                         'macaddress_dash': value
 | |
|                     }
 | |
|         elif entry['type'] == 233:  # Embedded NIC MAC Assignment (Alternate data format)
 | |
|             (infoname, entry_info) = parse_flat_interface(entry, 'hw_eth_ilo')
 | |
|             info[infoname] = entry_info
 | |
| 
 | |
|     # Collect health (RAM/CPU data)
 | |
|     health = ilo.get_embedded_health()
 | |
|     info['hw_health'] = health
 | |
| 
 | |
|     memory_details_summary = health.get('memory', {}).get('memory_details_summary')
 | |
|     # RAM as reported by iLO 2.10 on ProLiant BL460c Gen8
 | |
|     if memory_details_summary:
 | |
|         info['hw_memory_details_summary'] = memory_details_summary
 | |
|         info['hw_memory_total'] = 0
 | |
|         for cpu, details in memory_details_summary.items():
 | |
|             cpu_total_memory_size = details.get('total_memory_size')
 | |
|             if cpu_total_memory_size:
 | |
|                 ram = re.search(r'(\d+)\s+(\w+)', cpu_total_memory_size)
 | |
|                 if ram:
 | |
|                     if ram.group(2) == 'GB':
 | |
|                         info['hw_memory_total'] = info['hw_memory_total'] + int(ram.group(1))
 | |
| 
 | |
|         # reformat into a text friendly format
 | |
|         info['hw_memory_total'] = "{0} GB".format(info['hw_memory_total'])
 | |
| 
 | |
|     # Report host state
 | |
|     info['host_power_status'] = power_state or 'UNKNOWN'
 | |
| 
 | |
|     module.exit_json(**info)
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     main()
 |