diff --git a/docs/gen/zhmc_adapter_module.rst b/docs/gen/zhmc_adapter_module.rst index 10eb63c6..544e27a8 100644 --- a/docs/gen/zhmc_adapter_module.rst +++ b/docs/gen/zhmc_adapter_module.rst @@ -116,7 +116,7 @@ Options -
File path of a log file to which the logic flow of this module as well as interactions with the HMC are logged.
+
File path of a log file to which the logic flow of this module as well as interactions with the HMC are logged. If null, logging will be propagated to the Python root logger.
diff --git a/docs/gen/zhmc_cpc_module.rst b/docs/gen/zhmc_cpc_module.rst index bb8a15dd..48ad446c 100644 --- a/docs/gen/zhmc_cpc_module.rst +++ b/docs/gen/zhmc_cpc_module.rst @@ -116,7 +116,7 @@ Options -
File path of a log file to which the logic flow of this module as well as interactions with the HMC are logged.
+
File path of a log file to which the logic flow of this module as well as interactions with the HMC are logged. If null, logging will be propagated to the Python root logger.
diff --git a/docs/gen/zhmc_crypto_attachment_module.rst b/docs/gen/zhmc_crypto_attachment_module.rst index 4ae0d35d..af987628 100644 --- a/docs/gen/zhmc_crypto_attachment_module.rst +++ b/docs/gen/zhmc_crypto_attachment_module.rst @@ -167,7 +167,7 @@ Options -
File path of a log file to which the logic flow of this module as well as interactions with the HMC are logged.
+
File path of a log file to which the logic flow of this module as well as interactions with the HMC are logged. If null, logging will be propagated to the Python root logger.
@@ -207,7 +207,7 @@ Examples --- # Note: The following examples assume that some variables named 'my_*' are set. - + - name: Gather facts about the crypto configuration of a partition zhmc_crypto_attachment: hmc_host: "{{ my_hmc_host }}" @@ -216,7 +216,7 @@ Examples partition_name: "{{ my_partition_name }}" state: facts register: crypto1 - + - name: Ensure domain 0 on all ep11 adapters is attached in usage mode zhmc_crypto_attachment: hmc_host: "{{ my_hmc_host }}" @@ -228,7 +228,7 @@ Examples adapter_count: -1 domain_range: 0,0 access_mode: usage - + - name: Ensure domains 1-max on all ep11 adapters are attached in control mode zhmc_crypto_attachment: hmc_host: "{{ my_hmc_host }}" @@ -240,7 +240,7 @@ Examples adapter_count: -1 domain_range: 1,-1 access_mode: control - + - name: Ensure domains 0-max on 1 ep11 adapter are attached to in usage mode zhmc_crypto_attachment: hmc_host: "{{ my_hmc_host }}" @@ -252,7 +252,8 @@ Examples adapter_count: 1 domain_range: 0,-1 access_mode: usage - + + Return Values ------------- diff --git a/docs/gen/zhmc_hba_module.rst b/docs/gen/zhmc_hba_module.rst index 123b9902..e712a4ff 100644 --- a/docs/gen/zhmc_hba_module.rst +++ b/docs/gen/zhmc_hba_module.rst @@ -120,6 +120,16 @@ Options + + log_file
+ no + + + +
File path of a log file to which the logic flow of this module as well as interactions with the HMC are logged. If null, logging will be propagated to the Python root logger.
+ + + name
yes @@ -181,7 +191,7 @@ Examples --- # Note: The following examples assume that some variables named 'my_*' are set. - + - name: Ensure HBA exists in the partition zhmc_partition: hmc_host: "{{ my_hmc_host }}" @@ -196,7 +206,7 @@ Examples description: "The port to our V7K #1" device_number: "123F" register: hba1 - + - name: Ensure HBA does not exist in the partition zhmc_partition: hmc_host: "{{ my_hmc_host }}" @@ -206,6 +216,7 @@ Examples name: "{{ my_hba_name }}" state: absent + Return Values ------------- diff --git a/docs/gen/zhmc_nic_module.rst b/docs/gen/zhmc_nic_module.rst index 545c9b84..8f33f699 100644 --- a/docs/gen/zhmc_nic_module.rst +++ b/docs/gen/zhmc_nic_module.rst @@ -120,6 +120,16 @@ Options + + log_file
+ no + + + +
File path of a log file to which the logic flow of this module as well as interactions with the HMC are logged. If null, logging will be propagated to the Python root logger.
+ + + name
yes @@ -181,7 +191,7 @@ Examples --- # Note: The following examples assume that some variables named 'my_*' are set. - + - name: Ensure NIC exists in the partition zhmc_partition: hmc_host: "{{ my_hmc_host }}" @@ -196,7 +206,7 @@ Examples description: "The port to our data network" device_number: "023F" register: nic1 - + - name: Ensure NIC does not exist in the partition zhmc_partition: hmc_host: "{{ my_hmc_host }}" @@ -206,6 +216,7 @@ Examples name: "{{ my_nic_name }}" state: absent + Return Values ------------- diff --git a/docs/gen/zhmc_partition_module.rst b/docs/gen/zhmc_partition_module.rst index 1ee5c290..831ba29c 100644 --- a/docs/gen/zhmc_partition_module.rst +++ b/docs/gen/zhmc_partition_module.rst @@ -121,6 +121,16 @@ Options + + log_file
+ no + + + +
File path of a log file to which the logic flow of this module as well as interactions with the HMC are logged. If null, logging will be propagated to the Python root logger.
+ + + name
yes @@ -177,7 +187,7 @@ Examples --- # Note: The following examples assume that some variables named 'my_*' are set. - + # Because configuring LUN masking in the SAN requires the host WWPN, and the # host WWPN is automatically assigned and will be known only after an HBA has # been added to the partition, the partition needs to be created in stopped @@ -196,7 +206,7 @@ Examples initial_memory: 1024 maximum_memory: 1024 register: part1 - + # After an HBA has been added (see Ansible module zhmc_hba), and LUN masking # has been configured in the SAN, and a bootable image is available at the # configured LUN and target WWPN, the partition can be configured for boot @@ -214,7 +224,7 @@ Examples boot_logical_unit_number: 00000000001 boot_world_wide_port_name: abcdefabcdef register: part1 - + - name: Ensure the partition does not exist zhmc_partition: hmc_host: "{{ my_hmc_host }}" @@ -222,7 +232,7 @@ Examples cpc_name: "{{ my_cpc_name }}" name: "{{ my_partition_name }}" state: absent - + - name: Define crypto configuration zhmc_partition: hmc_host: "{{ my_hmc_host }}" @@ -241,7 +251,7 @@ Examples - domain_index: 1 access_mode: control register: part1 - + - name: Gather facts about a partition zhmc_partition: hmc_host: "{{ my_hmc_host }}" @@ -250,7 +260,8 @@ Examples name: "{{ my_partition_name }}" state: facts register: part1 - + + Return Values ------------- diff --git a/docs/gen/zhmc_storage_group_attachment_module.rst b/docs/gen/zhmc_storage_group_attachment_module.rst index 7e0a0890..1af5aade 100644 --- a/docs/gen/zhmc_storage_group_attachment_module.rst +++ b/docs/gen/zhmc_storage_group_attachment_module.rst @@ -120,6 +120,16 @@ Options + + log_file
+ no + + + +
File path of a log file to which the logic flow of this module as well as interactions with the HMC are logged. If null, logging will be propagated to the Python root logger.
+ + + partition_name
yes @@ -166,7 +176,7 @@ Examples --- # Note: The following examples assume that some variables named 'my_*' are set. - + - name: Gather facts about the attachment zhmc_storage_group_attachment: hmc_host: "{{ my_hmc_host }}" @@ -176,7 +186,7 @@ Examples partition_name: "{{ my_partition_name }}" state: facts register: sga1 - + - name: Ensure the storage group is attached to the partition zhmc_storage_group_attachment: hmc_host: "{{ my_hmc_host }}" @@ -185,7 +195,7 @@ Examples storage_group_name: "{{ my_storage_group_name }}" partition_name: "{{ my_partition_name }}" state: attached - + - name: "Ensure the storage group is not attached to the partition." zhmc_storage_group_attachment: hmc_host: "{{ my_hmc_host }}" @@ -194,7 +204,8 @@ Examples storage_group_name: "{{ my_storage_group_name }}" partition_name: "{{ my_partition_name }}" state: detached - + + Return Values ------------- diff --git a/docs/gen/zhmc_storage_group_module.rst b/docs/gen/zhmc_storage_group_module.rst index 1c7e9ab1..9e0b979f 100644 --- a/docs/gen/zhmc_storage_group_module.rst +++ b/docs/gen/zhmc_storage_group_module.rst @@ -130,6 +130,16 @@ Options + + log_file
+ no + + + +
File path of a log file to which the logic flow of this module as well as interactions with the HMC are logged. If null, logging will be propagated to the Python root logger.
+ + + name
yes @@ -180,7 +190,7 @@ Examples --- # Note: The following examples assume that some variables named 'my_*' are set. - + - name: Gather facts about a storage group zhmc_storage_group: hmc_host: "{{ my_hmc_host }}" @@ -190,7 +200,7 @@ Examples state: facts expand: true register: sg1 - + - name: Ensure the storage group does not exist zhmc_storage_group: hmc_host: "{{ my_hmc_host }}" @@ -198,7 +208,7 @@ Examples cpc_name: "{{ my_cpc_name }}" name: "{{ my_storage_group_name }}" state: absent - + - name: Ensure the storage group exists zhmc_storage_group: hmc_host: "{{ my_hmc_host }}" @@ -214,7 +224,8 @@ Examples connectivity: 4 max-partitions: 1 register: sg1 - + + Return Values ------------- diff --git a/docs/gen/zhmc_storage_volume_module.rst b/docs/gen/zhmc_storage_volume_module.rst index 79c5202e..c23e8519 100644 --- a/docs/gen/zhmc_storage_volume_module.rst +++ b/docs/gen/zhmc_storage_volume_module.rst @@ -120,6 +120,16 @@ Options + + log_file
+ no + + + +
File path of a log file to which the logic flow of this module as well as interactions with the HMC are logged. If null, logging will be propagated to the Python root logger.
+ + + name
yes @@ -179,7 +189,7 @@ Examples --- # Note: The following examples assume that some variables named 'my_*' are set. - + - name: Gather facts about a storage volume zhmc_storage_volume: hmc_host: "{{ my_hmc_host }}" @@ -189,7 +199,7 @@ Examples name: "{{ my_storage_volume_name }}" state: facts register: sv1 - + - name: Ensure the storage volume does not exist zhmc_storage_volume: hmc_host: "{{ my_hmc_host }}" @@ -198,7 +208,7 @@ Examples storage_group_name: "{{ my_storage_group_name }}" name: "{{ my_storage_volume_name }}" state: absent - + - name: Ensure the storage volume exists zhmc_storage_volume: hmc_host: "{{ my_hmc_host }}" @@ -211,7 +221,8 @@ Examples description: "Example storage volume 1" size: 1 register: sv1 - + + Return Values ------------- diff --git a/docs/gen/zhmc_virtual_function_module.rst b/docs/gen/zhmc_virtual_function_module.rst index 936f3686..28313a6f 100644 --- a/docs/gen/zhmc_virtual_function_module.rst +++ b/docs/gen/zhmc_virtual_function_module.rst @@ -120,6 +120,16 @@ Options + + log_file
+ no + + + +
File path of a log file to which the logic flow of this module as well as interactions with the HMC are logged. If null, logging will be propagated to the Python root logger.
+ + + name
yes @@ -180,7 +190,7 @@ Examples --- # Note: The following examples assume that some variables named 'my_*' are set. - + - name: Ensure virtual function exists in the partition zhmc_partition: hmc_host: "{{ my_hmc_host }}" @@ -194,7 +204,7 @@ Examples description: "The accelerator adapter" device_number: "033F" register: vfunction1 - + - name: Ensure virtual function does not exist in the partition zhmc_partition: hmc_host: "{{ my_hmc_host }}" @@ -204,6 +214,7 @@ Examples name: "{{ my_vfunction_name }}" state: absent + Return Values ------------- diff --git a/tests/function/test_func_partition.py b/tests/function/test_func_partition.py index 709d0586..e5dcf322 100755 --- a/tests/function/test_func_partition.py +++ b/tests/function/test_func_partition.py @@ -992,6 +992,7 @@ def test_success( 'name': self.partition_name, 'state': desired_state, 'properties': input_props, + 'log_file': None, 'faked_session': self.session, } @@ -1069,6 +1070,7 @@ def test_facts_success( 'cpc_name': self.cpc.name, 'name': self.partition_name, 'state': desired_state, + 'log_file': None, 'faked_session': self.session, } @@ -1196,6 +1198,7 @@ def test_error_properties( 'name': self.partition_name, 'state': desired_state, 'properties': props, + 'log_file': None, 'faked_session': self.session, } @@ -1263,6 +1266,7 @@ def test_boot_storage_success( 'name': self.partition_name, 'state': desired_state, 'properties': properties, + 'log_file': None, 'faked_session': self.session, } @@ -1341,6 +1345,7 @@ def test_boot_storage_error_hba_not_found( 'name': self.partition_name, 'state': desired_state, 'properties': properties, + 'log_file': None, 'faked_session': self.session, } @@ -1404,6 +1409,7 @@ def test_boot_network_success( 'name': self.partition_name, 'state': desired_state, 'properties': properties, + 'log_file': None, 'faked_session': self.session, } @@ -1480,6 +1486,7 @@ def test_boot_network_error_hba_not_found( 'name': self.partition_name, 'state': desired_state, 'properties': properties, + 'log_file': None, 'faked_session': self.session, } @@ -1555,6 +1562,7 @@ def test_crypto_config_success( 'name': self.partition_name, 'state': desired_state, 'properties': properties, + 'log_file': None, 'faked_session': self.session, } @@ -1740,6 +1748,7 @@ def test_crypto_config_parm_errors( 'name': self.partition_name, 'state': desired_state, 'properties': input_props, + 'log_file': None, 'faked_session': self.session, } diff --git a/tests/unit/test_hba.py b/tests/unit/test_hba.py index a766d3b5..15e22598 100755 --- a/tests/unit/test_hba.py +++ b/tests/unit/test_hba.py @@ -49,6 +49,7 @@ def test_main_success( 'partition_name': 'fake-partition-name', 'name': 'fake-hba-name', 'state': 'absent', + 'log_file': None, } # Return values of perform_task() @@ -82,6 +83,7 @@ def test_main_success( state=dict(required=True, type='str', choices=['absent', 'present']), properties=dict(required=False, type='dict', default={}), + log_file=dict(required=False, type='str', default=None), faked_session=dict(required=False, type='object'), ) assert(ansible_mod_cls.call_args == @@ -121,6 +123,7 @@ def test_main_param_error( 'partition_name': 'fake-partition-name', 'name': 'fake-hba-name', 'state': 'absent', + 'log_file': None, } # Exception raised by perform_task() @@ -174,6 +177,7 @@ def test_pt_present( # Prepare input arguments params = { 'state': 'present', + 'log_file': None, } # Prepare return values @@ -215,6 +219,7 @@ def test_pt_absent( # Prepare input arguments params = { 'state': 'absent', + 'log_file': None, } # Prepare return values diff --git a/tests/unit/test_nic.py b/tests/unit/test_nic.py index bfcc0abf..7a57dbbb 100755 --- a/tests/unit/test_nic.py +++ b/tests/unit/test_nic.py @@ -49,6 +49,7 @@ def test_main_success( 'partition_name': 'fake-partition-name', 'name': 'fake-nic-name', 'state': 'absent', + 'log_file': None, } # Return values of perform_task() @@ -82,6 +83,7 @@ def test_main_success( state=dict(required=True, type='str', choices=['absent', 'present']), properties=dict(required=False, type='dict', default={}), + log_file=dict(required=False, type='str', default=None), faked_session=dict(required=False, type='object'), ) assert(ansible_mod_cls.call_args == @@ -121,6 +123,7 @@ def test_main_param_error( 'partition_name': 'fake-partition-name', 'name': 'fake-nic-name', 'state': 'absent', + 'log_file': None, } # Exception raised by perform_task() @@ -174,6 +177,7 @@ def test_pt_present( # Prepare input arguments params = { 'state': 'present', + 'log_file': None, } # Prepare return values @@ -215,6 +219,7 @@ def test_pt_absent( # Prepare input arguments params = { 'state': 'absent', + 'log_file': None, } # Prepare return values diff --git a/tests/unit/test_partition.py b/tests/unit/test_partition.py index 564c7bef..f24e08ec 100755 --- a/tests/unit/test_partition.py +++ b/tests/unit/test_partition.py @@ -45,6 +45,7 @@ def test_main_success(self, ansible_mod_cls, perform_task_func): 'cpc_name': 'fake-cpc-name', 'name': 'fake-name', 'state': 'absent', + 'log_file': None, } check_mode = False @@ -78,6 +79,7 @@ def test_main_success(self, ansible_mod_cls, perform_task_func): state=dict(required=True, type='str', choices=['absent', 'stopped', 'active', 'facts']), properties=dict(required=False, type='dict', default={}), + log_file=dict(required=False, type='str', default=None), faked_session=dict(required=False, type='object'), ) assert(ansible_mod_cls.call_args == @@ -113,6 +115,7 @@ def test_main_param_error(self, ansible_mod_cls, perform_task_func): 'cpc_name': 'fake-cpc-name', 'name': 'fake-name', 'state': 'absent', + 'log_file': None, } check_mode = False @@ -167,6 +170,7 @@ def test_pt_active(self, ensure_stopped_func, ensure_active_func, # Prepare input arguments params = { 'state': 'active', + 'log_file': None, } check_mode = True @@ -210,6 +214,7 @@ def test_pt_stopped(self, ensure_stopped_func, ensure_active_func, # Prepare input arguments params = { 'state': 'stopped', + 'log_file': None, } check_mode = True @@ -253,6 +258,7 @@ def test_pt_absent(self, ensure_stopped_func, ensure_active_func, # Prepare input arguments params = { 'state': 'absent', + 'log_file': None, } check_mode = False diff --git a/tests/unit/test_virtual_function.py b/tests/unit/test_virtual_function.py index a7753f1c..d1003722 100755 --- a/tests/unit/test_virtual_function.py +++ b/tests/unit/test_virtual_function.py @@ -49,6 +49,7 @@ def test_main_success( 'partition_name': 'fake-partition-name', 'name': 'fake-vfunction-name', 'state': 'absent', + 'log_file': None, } # Return values of perform_task() @@ -82,6 +83,7 @@ def test_main_success( state=dict(required=True, type='str', choices=['absent', 'present']), properties=dict(required=False, type='dict', default={}), + log_file=dict(required=False, type='str', default=None), faked_session=dict(required=False, type='object'), ) assert(ansible_mod_cls.call_args == @@ -121,6 +123,7 @@ def test_main_param_error( 'partition_name': 'fake-partition-name', 'name': 'fake-vfunction-name', 'state': 'absent', + 'log_file': None, } # Exception raised by perform_task() @@ -174,6 +177,7 @@ def test_pt_present( # Prepare input arguments params = { 'state': 'present', + 'log_file': None, } # Prepare return values @@ -215,6 +219,7 @@ def test_pt_absent( # Prepare input arguments params = { 'state': 'absent', + 'log_file': None, } # Prepare return values diff --git a/zhmc_ansible_modules/utils/__init__.py b/zhmc_ansible_modules/utils/__init__.py index f13fcd15..5b14b65e 100644 --- a/zhmc_ansible_modules/utils/__init__.py +++ b/zhmc_ansible_modules/utils/__init__.py @@ -16,7 +16,7 @@ Utility functions for use by more than one Ansible module. """ -from datetime import datetime +import logging from ansible.module_utils import six @@ -460,24 +460,57 @@ def process_normal_property( return create_props, update_props, deactivate -def log(msg, file='debug.log'): +def log_init(logger_name, log_file=None): """ - Append a one-line message to a log file, adding some header info to the - begin of the line. + Set up logging for the loggers of the current Ansible module, and for the + loggers of the underlying zhmcclient package. - The header info that is added to each line, is: - yyyy-mm-dd hh:mm:ss.uuuuuu msg + The log level of these loggers is set to debug. + + If a log file is specified, a log file handler for that log file (with a + log formatter) is created and attached to these loggers. Parameters: - msg (string): The message. Any newlines in the message are replaced by - blanks. + logger_name (string): Name of the logger to be used for the current + Ansible module. - file (string): Path name of the log file to append the message to. + log_file (string): Path name of a log file to log to, or `None`. + If `None`, logging will be propagated to the Python root logger. """ - msg = msg.replace('\n', ' ') + '\n' - ts_dt = datetime.now() - ts_str = ts_dt.strftime('%Y-%m-%d %H:%M:%S.%f') - line = "{0} {1}".format(ts_str, msg) - with open(file, 'a') as fp: - fp.write(line) + + # The datefmt parameter of logging.Formatter() supports the datetime + # formatting placeholders of time.strftime(). Unfortunately, the %f + # placeholder for microseconds is not supported by time.strftime(). + # If datefmt=None, the milliseconds are added manually by the + # logging.Formatter() class. So this is a choice between precision and + # indicating the timezone offset. + # The time is in the local timezone. + # + DATEFMT = '%Y-%m-%dT%H:%M:%S%z' # 2019-02-20T10:54:26+0100 + # DATEFMT = None # 2019-02-20 10:54:26,123 (= local time) + + if log_file: + handler = logging.FileHandler(log_file) + fmt = logging.Formatter( + fmt='%(asctime)s %(levelname)s %(name)s %(process)d %(message)s', + datefmt=DATEFMT) + handler.setFormatter(fmt) + else: + handler = None + + logger = logging.getLogger(logger_name) + logger.setLevel(logging.DEBUG) + if handler: + logger.addHandler(handler) + + logger = logging.getLogger('zhmcclient.hmc') + logger.setLevel(logging.DEBUG) + if handler: + logger.addHandler(handler) + + if False: # Too much gorp, disabled for now + logger = logging.getLogger('zhmcclient.api') + logger.setLevel(logging.DEBUG) + if handler: + logger.addHandler(handler) diff --git a/zhmc_ansible_modules/zhmc_adapter.py b/zhmc_ansible_modules/zhmc_adapter.py index cfca69a5..043f4585 100644 --- a/zhmc_ansible_modules/zhmc_adapter.py +++ b/zhmc_ansible_modules/zhmc_adapter.py @@ -20,8 +20,8 @@ import requests.packages.urllib3 import zhmcclient -from zhmc_ansible_modules.utils import Error, ParameterError, get_hmc_auth, \ - get_session, to_unicode, process_normal_property, eq_hex +from zhmc_ansible_modules.utils import log_init, Error, ParameterError, \ + get_hmc_auth, get_session, to_unicode, process_normal_property, eq_hex # For information on the format of the ANSIBLE_METADATA, DOCUMENTATION, # EXAMPLES, and RETURN strings, see @@ -139,7 +139,8 @@ log_file: description: - "File path of a log file to which the logic flow of this module as well - as interactions with the HMC are logged." + as interactions with the HMC are logged. If null, logging will be + propagated to the Python root logger." required: false default: null faked_session: @@ -244,6 +245,8 @@ # Python logger name for this module LOGGER_NAME = 'zhmc_adapter' +LOGGER = logging.getLogger(LOGGER_NAME) + # Dictionary of properties of adapter resources, in this format: # name: (allowed, create, update, eq_func, type_cast) # where: @@ -282,7 +285,7 @@ 'description': (True, True, True, True, None, to_unicode), 'maximum_transmission_unit_size': (True, True, True, True, None, int), 'type': (True, True, True, True, None, None), - # type: used for Create Hipersockets and for Change Adapter Type + # type used for Create Hipersockets and for Change Adapter Type # read-only properties: 'object_uri': (False, None, False, None, None, None), @@ -404,26 +407,6 @@ def process_properties(adapter, params): return create_props, update_props, change_adapter_type, change_crypto_type -def log_init(log_file): - if log_file: - handler = logging.FileHandler(log_file) - format_string = '%(asctime)s %(name)s %(message)s' - handler.setFormatter(logging.Formatter(format_string)) - - logger = logging.getLogger('zhmcclient.hmc') - logger.addHandler(handler) - logger.setLevel(logging.DEBUG) - - logger = logging.getLogger(LOGGER_NAME) - logger.addHandler(handler) - logger.setLevel(logging.DEBUG) - - -def log(log_file, msg): - logger = logging.getLogger(LOGGER_NAME) - logger.debug(msg) - - def identify_adapter(cpc, name, match_props): """ Identify the target adapter based on its name, or if an adapter with that @@ -467,7 +450,6 @@ def ensure_set(params, check_mode): cpc_name = params['cpc_name'] adapter_name = params['name'] adapter_match = params['match'] - # log_file = params['log_file'] faked_session = params.get('faked_session', None) # No default specified changed = False @@ -544,7 +526,6 @@ def ensure_present(params, check_mode): userid, password = get_hmc_auth(params['hmc_auth']) cpc_name = params['cpc_name'] adapter_name = params['name'] - # log_file = params['log_file'] faked_session = params.get('faked_session', None) # No default specified changed = False @@ -678,7 +659,6 @@ def ensure_absent(params, check_mode): userid, password = get_hmc_auth(params['hmc_auth']) cpc_name = params['cpc_name'] adapter_name = params['name'] - # log_file = params['log_file'] faked_session = params.get('faked_session', None) # No default specified changed = False @@ -719,7 +699,6 @@ def facts(params, check_mode): userid, password = get_hmc_auth(params['hmc_auth']) cpc_name = params['cpc_name'] adapter_name = params['name'] - # log_file = params['log_file'] faked_session = params.get('faked_session', None) # No default specified try: @@ -788,11 +767,11 @@ def main(): supports_check_mode=True) log_file = module.params['log_file'] - log_init(log_file) - if log_file: - _params = dict(module.params) - del _params['hmc_auth'] - log(log_file, "Module entry: params: {!r}".format(_params)) + log_init(LOGGER_NAME, log_file) + + _params = dict(module.params) + del _params['hmc_auth'] + LOGGER.debug("Module entry: params: {!r}".format(_params)) try: @@ -803,14 +782,14 @@ def main(): # input. They have a proper message that stands on its own, so we # simply pass that message on and will not need a traceback. msg = "{}: {}".format(exc.__class__.__name__, exc) - log(log_file, + LOGGER.debug( "Module exit (failure): msg: {!r}". format(msg)) module.fail_json(msg=msg) # Other exceptions are considered module errors and are handled by Ansible # by showing the traceback. - log(log_file, + LOGGER.debug( "Module exit (success): changed: {!r}, adapter: {!r}". format(changed, result)) module.exit_json( diff --git a/zhmc_ansible_modules/zhmc_cpc.py b/zhmc_ansible_modules/zhmc_cpc.py index 8734238e..81756edc 100644 --- a/zhmc_ansible_modules/zhmc_cpc.py +++ b/zhmc_ansible_modules/zhmc_cpc.py @@ -20,8 +20,8 @@ import requests.packages.urllib3 import zhmcclient -from zhmc_ansible_modules.utils import Error, ParameterError, get_hmc_auth, \ - get_session, to_unicode, process_normal_property +from zhmc_ansible_modules.utils import log_init, Error, ParameterError, \ + get_hmc_auth, get_session, to_unicode, process_normal_property # For information on the format of the ANSIBLE_METADATA, DOCUMENTATION, # EXAMPLES, and RETURN strings, see @@ -98,7 +98,8 @@ log_file: description: - "File path of a log file to which the logic flow of this module as well - as interactions with the HMC are logged." + as interactions with the HMC are logged. If null, logging will be + propagated to the Python root logger." required: false default: null faked_session: @@ -176,6 +177,8 @@ # Python logger name for this module LOGGER_NAME = 'zhmc_cpc' +LOGGER = logging.getLogger(LOGGER_NAME) + # Dictionary of properties of CPC resources, in this format: # name: (allowed, create, update, eq_func, type_cast) # where: @@ -264,26 +267,6 @@ def process_properties(cpc, params): return update_props -def log_init(log_file): - if log_file: - handler = logging.FileHandler(log_file) - format_string = '%(asctime)s %(name)s %(message)s' - handler.setFormatter(logging.Formatter(format_string)) - - logger = logging.getLogger('zhmcclient.hmc') - logger.addHandler(handler) - logger.setLevel(logging.DEBUG) - - logger = logging.getLogger(LOGGER_NAME) - logger.addHandler(handler) - logger.setLevel(logging.DEBUG) - - -def log(log_file, msg): - logger = logging.getLogger(LOGGER_NAME) - logger.debug(msg) - - def ensure_set(params, check_mode): """ Identify the target CPC and ensure that the specified properties are set on @@ -299,7 +282,6 @@ def ensure_set(params, check_mode): host = params['hmc_host'] userid, password = get_hmc_auth(params['hmc_auth']) cpc_name = params['name'] - # log_file = params['log_file'] faked_session = params.get('faked_session', None) # No default specified changed = False @@ -349,7 +331,6 @@ def facts(params, check_mode): host = params['hmc_host'] userid, password = get_hmc_auth(params['hmc_auth']) cpc_name = params['name'] - # log_file = params['log_file'] faked_session = params.get('faked_session', None) # No default specified try: @@ -411,11 +392,11 @@ def main(): supports_check_mode=True) log_file = module.params['log_file'] - log_init(log_file) - if log_file: - _params = dict(module.params) - del _params['hmc_auth'] - log(log_file, "Module entry: params: {!r}".format(_params)) + log_init(LOGGER_NAME, log_file) + + _params = dict(module.params) + del _params['hmc_auth'] + LOGGER.debug("Module entry: params: {!r}".format(_params)) try: @@ -426,14 +407,14 @@ def main(): # input. They have a proper message that stands on its own, so we # simply pass that message on and will not need a traceback. msg = "{}: {}".format(exc.__class__.__name__, exc) - log(log_file, + LOGGER.debug( "Module exit (failure): msg: {!r}". format(msg)) module.fail_json(msg=msg) # Other exceptions are considered module errors and are handled by Ansible # by showing the traceback. - log(log_file, + LOGGER.debug( "Module exit (success): changed: {!r}, cpc: {!r}". format(changed, result)) module.exit_json( diff --git a/zhmc_ansible_modules/zhmc_crypto_attachment.py b/zhmc_ansible_modules/zhmc_crypto_attachment.py index 2bb0e4ee..b869e05d 100644 --- a/zhmc_ansible_modules/zhmc_crypto_attachment.py +++ b/zhmc_ansible_modules/zhmc_crypto_attachment.py @@ -20,8 +20,8 @@ import requests.packages.urllib3 import zhmcclient -from zhmc_ansible_modules.utils import Error, ParameterError, get_hmc_auth, \ - get_session +from zhmc_ansible_modules.utils import log_init, Error, ParameterError, \ + get_hmc_auth, get_session # For information on the format of the ANSIBLE_METADATA, DOCUMENTATION, # EXAMPLES, and RETURN strings, see @@ -131,7 +131,8 @@ log_file: description: - "File path of a log file to which the logic flow of this module as well - as interactions with the HMC are logged." + as interactions with the HMC are logged. If null, logging will be + propagated to the Python root logger." required: false default: null faked_session: @@ -242,6 +243,11 @@ }) """ +# Python logger name for this module +LOGGER_NAME = 'zhmc_crypto_attachment' + +LOGGER = logging.getLogger(LOGGER_NAME) + # Conversion of crypto types between module parameter values and HMC values CRYPTO_TYPES_MOD2HMC = { 'acc': 'accelerator', @@ -259,34 +265,6 @@ 'control': 'control', } -# Python logger name for this module -LOGGER_NAME = 'zhmc_crypto_attachment' - - -def log_init(log_file): - if log_file: - handler = logging.FileHandler(log_file) - format_string = '%(asctime)s %(name)s %(message)s' - handler.setFormatter(logging.Formatter(format_string)) - - logger = logging.getLogger('zhmcclient.hmc') - logger.addHandler(handler) - logger.setLevel(logging.DEBUG) - - if False: # Too much gorp, disabled for now - logger = logging.getLogger('zhmcclient.api') - logger.addHandler(handler) - logger.setLevel(logging.DEBUG) - - logger = logging.getLogger(LOGGER_NAME) - logger.addHandler(handler) - logger.setLevel(logging.DEBUG) - - -def log(log_file, msg): - logger = logging.getLogger(LOGGER_NAME) - logger.debug(msg) - def get_partition_config(partition, all_adapters): """ @@ -355,7 +333,6 @@ def ensure_attached(params, check_mode): domain_range = params['domain_range'] access_mode = params['access_mode'] crypto_type = params['crypto_type'] - log_file = params['log_file'] faked_session = params.get('faked_session', None) # No default specified try: @@ -492,13 +469,13 @@ def ensure_attached(params, check_mode): for a_uri in all_adapters: a = all_adapters[a_uri] if a_uri in attached_adapter_uris: - log(log_file, + LOGGER.debug( "Crypto adapter {!r} is already attached to target " "partition {!r}". format(a.name, partition.name)) attached_adapters.append(a) else: - log(log_file, + LOGGER.debug( "Crypto adapter {!r} is not attached to target " "partition {!r}". format(a.name, partition.name)) @@ -524,7 +501,7 @@ def ensure_attached(params, check_mode): else: # This domain is attached to the target partition in the # desired access mode - log(log_file, + LOGGER.debug( "Domain {} is already attached in {!r} mode to target " "partition {!r}". format(di, access_mode, partition.name)) @@ -571,7 +548,7 @@ def ensure_attached(params, check_mode): if missing_count <= 0 and add_domain_config: # Adapters already sufficient, but domains to be attached - log(log_file, + LOGGER.debug( "Attaching domains {!r} in {!r} mode to target partition {!r}". format(add_domains, access_mode, partition.name)) @@ -608,13 +585,13 @@ def ensure_attached(params, check_mode): conflicting_domains[di] = (am, p.name) if conflicting_domains: - log(log_file, + LOGGER.debug( "Skipping adapter {!r} because the following domains " "are already attached to other partitions: {!r}". format(adapter.name, conflicting_domains)) continue - log(log_file, + LOGGER.debug( "Attaching adapter {!r} and domains {!r} in {!r} mode to " "target partition {!r}". format(adapter.name, add_domains, access_mode, @@ -671,7 +648,6 @@ def ensure_detached(params, check_mode): userid, password = get_hmc_auth(params['hmc_auth']) cpc_name = params['cpc_name'] partition_name = params['partition_name'] - log_file = params['log_file'] faked_session = params.get('faked_session', None) # No default specified changed = False @@ -723,7 +699,7 @@ def ensure_detached(params, check_mode): di = dc['domain-index'] remove_domains.append(di) - log(log_file, + LOGGER.debug( "Detaching domains {} and adapters {!r} from target partition " "{!r}". format(remove_domains, remove_adapter_names, partition.name)) @@ -762,7 +738,6 @@ def facts(params, check_mode): userid, password = get_hmc_auth(params['hmc_auth']) cpc_name = params['cpc_name'] partition_name = params['partition_name'] - # log_file = params['log_file'] faked_session = params.get('faked_session', None) # No default specified try: @@ -839,11 +814,11 @@ def main(): supports_check_mode=True) log_file = module.params['log_file'] - log_init(log_file) - if log_file: - _params = dict(module.params) - del _params['hmc_auth'] - log(log_file, "Module entry: params: {!r}".format(_params)) + log_init(LOGGER_NAME, log_file) + + _params = dict(module.params) + del _params['hmc_auth'] + LOGGER.debug("Module entry: params: {!r}".format(_params)) try: @@ -855,14 +830,14 @@ def main(): # input. They have a proper message that stands on its own, so we # simply pass that message on and will not need a traceback. msg = "{}: {}".format(exc.__class__.__name__, exc) - log(log_file, + LOGGER.debug( "Module exit (failure): msg: {!r}". format(msg)) module.fail_json(msg=msg) # Other exceptions are considered module errors and are handled by Ansible # by showing the traceback. - log(log_file, + LOGGER.debug( "Module exit (success): changed: {!r}, crypto_configuration: {!r}, " "changes: {!r}".format(changed, result, changes)) module.exit_json( diff --git a/zhmc_ansible_modules/zhmc_hba.py b/zhmc_ansible_modules/zhmc_hba.py index 1b00c2df..2f3db5e6 100644 --- a/zhmc_ansible_modules/zhmc_hba.py +++ b/zhmc_ansible_modules/zhmc_hba.py @@ -15,11 +15,12 @@ from __future__ import absolute_import, print_function +import logging from ansible.module_utils.basic import AnsibleModule import requests.packages.urllib3 import zhmcclient -from zhmc_ansible_modules.utils import Error, ParameterError, \ +from zhmc_ansible_modules.utils import log_init, Error, ParameterError, \ wait_for_transition_completion, eq_hex, get_hmc_auth, get_session, \ to_unicode, process_normal_property @@ -120,6 +121,13 @@ data model for HBAs when the HBA is being created." required: false default: No input properties + log_file: + description: + - "File path of a log file to which the logic flow of this module as well + as interactions with the HMC are logged. If null, logging will be + propagated to the Python root logger." + required: false + default: null faked_session: description: - "A C(zhmcclient_mock.FakedSession) object that has a mocked HMC set up. @@ -179,6 +187,11 @@ }) """ +# Python logger name for this module +LOGGER_NAME = 'zhmc_hba' + +LOGGER = logging.getLogger(LOGGER_NAME) + # Dictionary of properties of HBA resources, in this format: # name: (allowed, create, update, update_while_active, eq_func, type_cast) # where: @@ -519,6 +532,7 @@ def main(): state=dict(required=True, type='str', choices=['absent', 'present']), properties=dict(required=False, type='dict', default={}), + log_file=dict(required=False, type='str', default=None), faked_session=dict(required=False, type='object'), ) @@ -526,6 +540,13 @@ def main(): argument_spec=argument_spec, supports_check_mode=True) + log_file = module.params['log_file'] + log_init(LOGGER_NAME, log_file) + + _params = dict(module.params) + del _params['hmc_auth'] + LOGGER.debug("Module entry: params: {!r}".format(_params)) + try: changed, result = perform_task(module.params, module.check_mode) @@ -535,10 +556,16 @@ def main(): # input. They have a proper message that stands on its own, so we # simply pass that message on and will not need a traceback. msg = "{}: {}".format(exc.__class__.__name__, exc) + LOGGER.debug( + "Module exit (failure): msg: {!r}". + format(msg)) module.fail_json(msg=msg) # Other exceptions are considered module errors and are handled by Ansible # by showing the traceback. + LOGGER.debug( + "Module exit (success): changed: {!r}, cpc: {!r}". + format(changed, result)) module.exit_json(changed=changed, hba=result) diff --git a/zhmc_ansible_modules/zhmc_nic.py b/zhmc_ansible_modules/zhmc_nic.py index 9952ff98..d0861517 100644 --- a/zhmc_ansible_modules/zhmc_nic.py +++ b/zhmc_ansible_modules/zhmc_nic.py @@ -15,11 +15,12 @@ from __future__ import absolute_import, print_function +import logging from ansible.module_utils.basic import AnsibleModule import requests.packages.urllib3 import zhmcclient -from zhmc_ansible_modules.utils import Error, ParameterError, \ +from zhmc_ansible_modules.utils import log_init, Error, ParameterError, \ wait_for_transition_completion, eq_hex, eq_mac, get_hmc_auth, \ get_session, to_unicode, process_normal_property @@ -120,6 +121,13 @@ data model for NICs when the NIC is being created." required: false default: No input properties + log_file: + description: + - "File path of a log file to which the logic flow of this module as well + as interactions with the HMC are logged. If null, logging will be + propagated to the Python root logger." + required: false + default: null faked_session: description: - "A C(zhmcclient_mock.FakedSession) object that has a mocked HMC set up. @@ -179,6 +187,11 @@ }) """ +# Python logger name for this module +LOGGER_NAME = 'zhmc_nic' + +LOGGER = logging.getLogger(LOGGER_NAME) + # Dictionary of properties of NIC resources, in this format: # name: (allowed, create, update, update_while_active, eq_func, type_cast) # where: @@ -562,6 +575,7 @@ def main(): state=dict(required=True, type='str', choices=['absent', 'present']), properties=dict(required=False, type='dict', default={}), + log_file=dict(required=False, type='str', default=None), faked_session=dict(required=False, type='object'), ) @@ -569,6 +583,13 @@ def main(): argument_spec=argument_spec, supports_check_mode=True) + log_file = module.params['log_file'] + log_init(LOGGER_NAME, log_file) + + _params = dict(module.params) + del _params['hmc_auth'] + LOGGER.debug("Module entry: params: {!r}".format(_params)) + try: changed, result = perform_task(module.params, module.check_mode) @@ -578,10 +599,16 @@ def main(): # input. They have a proper message that stands on its own, so we # simply pass that message on and will not need a traceback. msg = "{}: {}".format(exc.__class__.__name__, exc) + LOGGER.debug( + "Module exit (failure): msg: {!r}". + format(msg)) module.fail_json(msg=msg) # Other exceptions are considered module errors and are handled by Ansible # by showing the traceback. + LOGGER.debug( + "Module exit (success): changed: {!r}, cpc: {!r}". + format(changed, result)) module.exit_json(changed=changed, nic=result) diff --git a/zhmc_ansible_modules/zhmc_partition.py b/zhmc_ansible_modules/zhmc_partition.py index 8a8c6bcf..89b4097b 100644 --- a/zhmc_ansible_modules/zhmc_partition.py +++ b/zhmc_ansible_modules/zhmc_partition.py @@ -15,14 +15,16 @@ from __future__ import absolute_import, print_function +import logging from ansible.module_utils.basic import AnsibleModule from operator import itemgetter import requests.packages.urllib3 import zhmcclient -from zhmc_ansible_modules.utils import Error, ParameterError, StatusError, \ - stop_partition, start_partition, wait_for_transition_completion, eq_hex, \ - get_hmc_auth, get_session, to_unicode, process_normal_property +from zhmc_ansible_modules.utils import log_init, Error, ParameterError, \ + StatusError, stop_partition, start_partition, \ + wait_for_transition_completion, eq_hex, get_hmc_auth, get_session, \ + to_unicode, process_normal_property # For information on the format of the ANSIBLE_METADATA, DOCUMENTATION, # EXAMPLES, and RETURN strings, see @@ -138,6 +140,13 @@ is being created." required: false default: No input properties + log_file: + description: + - "File path of a log file to which the logic flow of this module as well + as interactions with the HMC are logged. If null, logging will be + propagated to the Python root logger." + required: false + default: null faked_session: description: - "A C(zhmcclient_mock.FakedSession) object that has a mocked HMC set up. @@ -258,6 +267,11 @@ }) """ +# Python logger name for this module +LOGGER_NAME = 'zhmc_partition' + +LOGGER = logging.getLogger(LOGGER_NAME) + # Dictionary of properties of partition resources, in this format: # name: (allowed, create, update, update_while_active, eq_func, type_cast) # where: @@ -1016,6 +1030,7 @@ def main(): state=dict(required=True, type='str', choices=['absent', 'stopped', 'active', 'facts']), properties=dict(required=False, type='dict', default={}), + log_file=dict(required=False, type='str', default=None), faked_session=dict(required=False, type='object'), ) @@ -1023,6 +1038,13 @@ def main(): argument_spec=argument_spec, supports_check_mode=True) + log_file = module.params['log_file'] + log_init(LOGGER_NAME, log_file) + + _params = dict(module.params) + del _params['hmc_auth'] + LOGGER.debug("Module entry: params: {!r}".format(_params)) + try: changed, result = perform_task(module.params, module.check_mode) @@ -1032,10 +1054,16 @@ def main(): # input. They have a proper message that stands on its own, so we # simply pass that message on and will not need a traceback. msg = "{}: {}".format(exc.__class__.__name__, exc) + LOGGER.debug( + "Module exit (failure): msg: {!r}". + format(msg)) module.fail_json(msg=msg) # Other exceptions are considered module errors and are handled by Ansible # by showing the traceback. + LOGGER.debug( + "Module exit (success): changed: {!r}, cpc: {!r}". + format(changed, result)) module.exit_json(changed=changed, partition=result) diff --git a/zhmc_ansible_modules/zhmc_storage_group.py b/zhmc_ansible_modules/zhmc_storage_group.py index 823e93af..106435a4 100644 --- a/zhmc_ansible_modules/zhmc_storage_group.py +++ b/zhmc_ansible_modules/zhmc_storage_group.py @@ -15,11 +15,12 @@ from __future__ import absolute_import, print_function +import logging from ansible.module_utils.basic import AnsibleModule import requests.packages.urllib3 import zhmcclient -from zhmc_ansible_modules.utils import Error, ParameterError, \ +from zhmc_ansible_modules.utils import log_init, Error, ParameterError, \ get_hmc_auth, get_session, to_unicode, process_normal_property # For information on the format of the ANSIBLE_METADATA, DOCUMENTATION, @@ -134,6 +135,13 @@ required: false type: bool default: false + log_file: + description: + - "File path of a log file to which the logic flow of this module as well + as interactions with the HMC are logged. If null, logging will be + propagated to the Python root logger." + required: false + default: null faked_session: description: - "A C(zhmcclient_mock.FakedSession) object that has a mocked HMC set up. @@ -229,6 +237,10 @@ }) """ +# Python logger name for this module +LOGGER_NAME = 'zhmc_storage_group' + +LOGGER = logging.getLogger(LOGGER_NAME) # Dictionary of properties of storage group resources, in this format: # name: (allowed, create, update, eq_func, type_cast) @@ -685,6 +697,7 @@ def main(): choices=['absent', 'present', 'facts']), properties=dict(required=False, type='dict', default={}), expand=dict(required=False, type='bool', default=False), + log_file=dict(required=False, type='str', default=None), faked_session=dict(required=False, type='object'), ) @@ -692,6 +705,13 @@ def main(): argument_spec=argument_spec, supports_check_mode=True) + log_file = module.params['log_file'] + log_init(LOGGER_NAME, log_file) + + _params = dict(module.params) + del _params['hmc_auth'] + LOGGER.debug("Module entry: params: {!r}".format(_params)) + try: changed, result = perform_task(module.params, module.check_mode) @@ -701,10 +721,16 @@ def main(): # input. They have a proper message that stands on its own, so we # simply pass that message on and will not need a traceback. msg = "{}: {}".format(exc.__class__.__name__, exc) + LOGGER.debug( + "Module exit (failure): msg: {!r}". + format(msg)) module.fail_json(msg=msg) # Other exceptions are considered module errors and are handled by Ansible # by showing the traceback. + LOGGER.debug( + "Module exit (success): changed: {!r}, cpc: {!r}". + format(changed, result)) module.exit_json(changed=changed, storage_group=result) diff --git a/zhmc_ansible_modules/zhmc_storage_group_attachment.py b/zhmc_ansible_modules/zhmc_storage_group_attachment.py index 4ecfccb4..1e679c52 100644 --- a/zhmc_ansible_modules/zhmc_storage_group_attachment.py +++ b/zhmc_ansible_modules/zhmc_storage_group_attachment.py @@ -15,11 +15,13 @@ from __future__ import absolute_import, print_function +import logging from ansible.module_utils.basic import AnsibleModule import requests.packages.urllib3 import zhmcclient -from zhmc_ansible_modules.utils import Error, get_hmc_auth, get_session +from zhmc_ansible_modules.utils import log_init, Error, \ + get_hmc_auth, get_session # For information on the format of the ANSIBLE_METADATA, DOCUMENTATION, # EXAMPLES, and RETURN strings, see @@ -105,6 +107,13 @@ the attachment status." required: true choices: ['detached', 'attached', 'facts'] + log_file: + description: + - "File path of a log file to which the logic flow of this module as well + as interactions with the HMC are logged. If null, logging will be + propagated to the Python root logger." + required: false + default: null faked_session: description: - "A C(zhmcclient_mock.FakedSession) object that has a mocked HMC set up. @@ -161,6 +170,11 @@ C({"attached": true}) """ +# Python logger name for this module +LOGGER_NAME = 'zhmc_storage_group_attachment' + +LOGGER = logging.getLogger(LOGGER_NAME) + def ensure_attached(params, check_mode): """ @@ -346,6 +360,7 @@ def main(): partition_name=dict(required=True, type='str'), state=dict(required=True, type='str', choices=['detached', 'attached', 'facts']), + log_file=dict(required=False, type='str', default=None), faked_session=dict(required=False, type='object'), ) @@ -353,6 +368,13 @@ def main(): argument_spec=argument_spec, supports_check_mode=True) + log_file = module.params['log_file'] + log_init(LOGGER_NAME, log_file) + + _params = dict(module.params) + del _params['hmc_auth'] + LOGGER.debug("Module entry: params: {!r}".format(_params)) + try: changed, result = perform_task(module.params, module.check_mode) @@ -362,10 +384,16 @@ def main(): # input. They have a proper message that stands on its own, so we # simply pass that message on and will not need a traceback. msg = "{}: {}".format(exc.__class__.__name__, exc) + LOGGER.debug( + "Module exit (failure): msg: {!r}". + format(msg)) module.fail_json(msg=msg) # Other exceptions are considered module errors and are handled by Ansible # by showing the traceback. + LOGGER.debug( + "Module exit (success): changed: {!r}, cpc: {!r}". + format(changed, result)) module.exit_json(changed=changed, storage_group_attachment=result) diff --git a/zhmc_ansible_modules/zhmc_storage_volume.py b/zhmc_ansible_modules/zhmc_storage_volume.py index 7438b0c8..b039961d 100644 --- a/zhmc_ansible_modules/zhmc_storage_volume.py +++ b/zhmc_ansible_modules/zhmc_storage_volume.py @@ -15,13 +15,13 @@ from __future__ import absolute_import, print_function +import logging from ansible.module_utils.basic import AnsibleModule import requests.packages.urllib3 import zhmcclient -from zhmc_ansible_modules.utils import Error, ParameterError, \ - eq_hex, \ - get_hmc_auth, get_session, to_unicode, process_normal_property +from zhmc_ansible_modules.utils import log_init, Error, ParameterError, \ + eq_hex, get_hmc_auth, get_session, to_unicode, process_normal_property # For information on the format of the ANSIBLE_METADATA, DOCUMENTATION, # EXAMPLES, and RETURN strings, see @@ -127,6 +127,13 @@ storage volume is being created." required: false default: No properties. + log_file: + description: + - "File path of a log file to which the logic flow of this module as well + as interactions with the HMC are logged. If null, logging will be + propagated to the Python root logger." + required: false + default: null faked_session: description: - "A C(zhmcclient_mock.FakedSession) object that has a mocked HMC set up. @@ -199,6 +206,11 @@ }) """ +# Python logger name for this module +LOGGER_NAME = 'zhmc_storage_volume' + +LOGGER = logging.getLogger(LOGGER_NAME) + # Dictionary of properties of storage volume resources, in this format: # name: (allowed, create, update, update_while_active, eq_func, type_cast) # where: @@ -592,6 +604,7 @@ def main(): state=dict(required=True, type='str', choices=['absent', 'present', 'facts']), properties=dict(required=False, type='dict', default={}), + log_file=dict(required=False, type='str', default=None), faked_session=dict(required=False, type='object'), ) @@ -599,6 +612,13 @@ def main(): argument_spec=argument_spec, supports_check_mode=True) + log_file = module.params['log_file'] + log_init(LOGGER_NAME, log_file) + + _params = dict(module.params) + del _params['hmc_auth'] + LOGGER.debug("Module entry: params: {!r}".format(_params)) + try: changed, result = perform_task(module.params, module.check_mode) @@ -608,10 +628,16 @@ def main(): # input. They have a proper message that stands on its own, so we # simply pass that message on and will not need a traceback. msg = "{}: {}".format(exc.__class__.__name__, exc) + LOGGER.debug( + "Module exit (failure): msg: {!r}". + format(msg)) module.fail_json(msg=msg) # Other exceptions are considered module errors and are handled by Ansible # by showing the traceback. + LOGGER.debug( + "Module exit (success): changed: {!r}, cpc: {!r}". + format(changed, result)) module.exit_json(changed=changed, storage_volume=result) diff --git a/zhmc_ansible_modules/zhmc_virtual_function.py b/zhmc_ansible_modules/zhmc_virtual_function.py index 47404f0c..74e5602b 100644 --- a/zhmc_ansible_modules/zhmc_virtual_function.py +++ b/zhmc_ansible_modules/zhmc_virtual_function.py @@ -15,11 +15,12 @@ from __future__ import absolute_import, print_function +import logging from ansible.module_utils.basic import AnsibleModule import requests.packages.urllib3 import zhmcclient -from zhmc_ansible_modules.utils import Error, ParameterError, \ +from zhmc_ansible_modules.utils import log_init, Error, ParameterError, \ wait_for_transition_completion, eq_hex, get_hmc_auth, get_session, \ to_unicode, process_normal_property @@ -118,6 +119,13 @@ function is being created." required: false default: No input properties + log_file: + description: + - "File path of a log file to which the logic flow of this module as well + as interactions with the HMC are logged. If null, logging will be + propagated to the Python root logger." + required: false + default: null faked_session: description: - "A C(zhmcclient_mock.FakedSession) object that has a mocked HMC set up. @@ -176,6 +184,11 @@ }) """ +# Python logger name for this module +LOGGER_NAME = 'zhmc_virtual_function' + +LOGGER = logging.getLogger(LOGGER_NAME) + # Dictionary of properties of virtual function resources, in this format: # name: (allowed, create, update, update_while_active, eq_func, type_cast) # where: @@ -500,6 +513,7 @@ def main(): state=dict(required=True, type='str', choices=['absent', 'present']), properties=dict(required=False, type='dict', default={}), + log_file=dict(required=False, type='str', default=None), faked_session=dict(required=False, type='object'), ) @@ -507,6 +521,13 @@ def main(): argument_spec=argument_spec, supports_check_mode=True) + log_file = module.params['log_file'] + log_init(LOGGER_NAME, log_file) + + _params = dict(module.params) + del _params['hmc_auth'] + LOGGER.debug("Module entry: params: {!r}".format(_params)) + try: changed, result = perform_task(module.params, module.check_mode) @@ -516,10 +537,16 @@ def main(): # input. They have a proper message that stands on its own, so we # simply pass that message on and will not need a traceback. msg = "{}: {}".format(exc.__class__.__name__, exc) + LOGGER.debug( + "Module exit (failure): msg: {!r}". + format(msg)) module.fail_json(msg=msg) # Other exceptions are considered module errors and are handled by Ansible # by showing the traceback. + LOGGER.debug( + "Module exit (success): changed: {!r}, cpc: {!r}". + format(changed, result)) module.exit_json(changed=changed, virtual_function=result)