mirror of
				https://github.com/ansible-collections/community.general.git
				synced 2025-10-26 21:59:38 -07:00 
			
		
		
		
	Use semantic markup (modules t-z) (#6698)
* Use semantic markup.
* Fix escaping.
(cherry picked from commit ccdcf70d69)
Co-authored-by: Felix Fontein <felix@fontein.de>
		
	
			
		
			
				
	
	
		
			223 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			223 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/python
 | |
| # -*- coding: utf-8 -*-
 | |
| 
 | |
| # Copyright (c) 2018, Dag Wieers (@dagwieers) <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: read_csv
 | |
| short_description: Read a CSV file
 | |
| description:
 | |
| - Read a CSV file and return a list or a dictionary, containing one dictionary per row.
 | |
| author:
 | |
| - Dag Wieers (@dagwieers)
 | |
| extends_documentation_fragment:
 | |
| - community.general.attributes
 | |
| attributes:
 | |
|   check_mode:
 | |
|     support: full
 | |
|   diff_mode:
 | |
|     support: none
 | |
| options:
 | |
|   path:
 | |
|     description:
 | |
|     - The CSV filename to read data from.
 | |
|     type: path
 | |
|     required: true
 | |
|     aliases: [ filename ]
 | |
|   key:
 | |
|     description:
 | |
|     - The column name used as a key for the resulting dictionary.
 | |
|     - If O(key) is unset, the module returns a list of dictionaries,
 | |
|       where each dictionary is a row in the CSV file.
 | |
|     type: str
 | |
|   dialect:
 | |
|     description:
 | |
|     - The CSV dialect to use when parsing the CSV file.
 | |
|     - Possible values include V(excel), V(excel-tab) or V(unix).
 | |
|     type: str
 | |
|     default: excel
 | |
|   fieldnames:
 | |
|     description:
 | |
|     - A list of field names for every column.
 | |
|     - This is needed if the CSV does not have a header.
 | |
|     type: list
 | |
|     elements: str
 | |
|   unique:
 | |
|     description:
 | |
|     - Whether the O(key) used is expected to be unique.
 | |
|     type: bool
 | |
|     default: true
 | |
|   delimiter:
 | |
|     description:
 | |
|     - A one-character string used to separate fields.
 | |
|     - When using this parameter, you change the default value used by O(dialect).
 | |
|     - The default value depends on the dialect used.
 | |
|     type: str
 | |
|   skipinitialspace:
 | |
|     description:
 | |
|     - Whether to ignore any whitespaces immediately following the delimiter.
 | |
|     - When using this parameter, you change the default value used by O(dialect).
 | |
|     - The default value depends on the dialect used.
 | |
|     type: bool
 | |
|   strict:
 | |
|     description:
 | |
|     - Whether to raise an exception on bad CSV input.
 | |
|     - When using this parameter, you change the default value used by O(dialect).
 | |
|     - The default value depends on the dialect used.
 | |
|     type: bool
 | |
| seealso:
 | |
|   - plugin: ansible.builtin.csvfile
 | |
|     plugin_type: lookup
 | |
|     description: Can be used to do selective lookups in CSV files from Jinja.
 | |
| '''
 | |
| 
 | |
| EXAMPLES = r'''
 | |
| # Example CSV file with header
 | |
| #
 | |
| #   name,uid,gid
 | |
| #   dag,500,500
 | |
| #   jeroen,501,500
 | |
| 
 | |
| # Read a CSV file and access user 'dag'
 | |
| - name: Read users from CSV file and return a dictionary
 | |
|   community.general.read_csv:
 | |
|     path: users.csv
 | |
|     key: name
 | |
|   register: users
 | |
|   delegate_to: localhost
 | |
| 
 | |
| - ansible.builtin.debug:
 | |
|     msg: 'User {{ users.dict.dag.name }} has UID {{ users.dict.dag.uid }} and GID {{ users.dict.dag.gid }}'
 | |
| 
 | |
| # Read a CSV file and access the first item
 | |
| - name: Read users from CSV file and return a list
 | |
|   community.general.read_csv:
 | |
|     path: users.csv
 | |
|   register: users
 | |
|   delegate_to: localhost
 | |
| 
 | |
| - ansible.builtin.debug:
 | |
|     msg: 'User {{ users.list.1.name }} has UID {{ users.list.1.uid }} and GID {{ users.list.1.gid }}'
 | |
| 
 | |
| # Example CSV file without header and semi-colon delimiter
 | |
| #
 | |
| #   dag;500;500
 | |
| #   jeroen;501;500
 | |
| 
 | |
| # Read a CSV file without headers
 | |
| - name: Read users from CSV file and return a list
 | |
|   community.general.read_csv:
 | |
|     path: users.csv
 | |
|     fieldnames: name,uid,gid
 | |
|     delimiter: ';'
 | |
|   register: users
 | |
|   delegate_to: localhost
 | |
| '''
 | |
| 
 | |
| RETURN = r'''
 | |
| dict:
 | |
|   description: The CSV content as a dictionary.
 | |
|   returned: success
 | |
|   type: dict
 | |
|   sample:
 | |
|     dag:
 | |
|       name: dag
 | |
|       uid: 500
 | |
|       gid: 500
 | |
|     jeroen:
 | |
|       name: jeroen
 | |
|       uid: 501
 | |
|       gid: 500
 | |
| list:
 | |
|   description: The CSV content as a list.
 | |
|   returned: success
 | |
|   type: list
 | |
|   sample:
 | |
|   - name: dag
 | |
|     uid: 500
 | |
|     gid: 500
 | |
|   - name: jeroen
 | |
|     uid: 501
 | |
|     gid: 500
 | |
| '''
 | |
| 
 | |
| from ansible.module_utils.basic import AnsibleModule
 | |
| from ansible.module_utils.common.text.converters import to_native
 | |
| 
 | |
| from ansible_collections.community.general.plugins.module_utils.csv import (initialize_dialect, read_csv, CSVError,
 | |
|                                                                             DialectNotAvailableError,
 | |
|                                                                             CustomDialectFailureError)
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     module = AnsibleModule(
 | |
|         argument_spec=dict(
 | |
|             path=dict(type='path', required=True, aliases=['filename']),
 | |
|             dialect=dict(type='str', default='excel'),
 | |
|             key=dict(type='str', no_log=False),
 | |
|             fieldnames=dict(type='list', elements='str'),
 | |
|             unique=dict(type='bool', default=True),
 | |
|             delimiter=dict(type='str'),
 | |
|             skipinitialspace=dict(type='bool'),
 | |
|             strict=dict(type='bool'),
 | |
|         ),
 | |
|         supports_check_mode=True,
 | |
|     )
 | |
| 
 | |
|     path = module.params['path']
 | |
|     dialect = module.params['dialect']
 | |
|     key = module.params['key']
 | |
|     fieldnames = module.params['fieldnames']
 | |
|     unique = module.params['unique']
 | |
| 
 | |
|     dialect_params = {
 | |
|         "delimiter": module.params['delimiter'],
 | |
|         "skipinitialspace": module.params['skipinitialspace'],
 | |
|         "strict": module.params['strict'],
 | |
|     }
 | |
| 
 | |
|     try:
 | |
|         dialect = initialize_dialect(dialect, **dialect_params)
 | |
|     except (CustomDialectFailureError, DialectNotAvailableError) as e:
 | |
|         module.fail_json(msg=to_native(e))
 | |
| 
 | |
|     try:
 | |
|         with open(path, 'rb') as f:
 | |
|             data = f.read()
 | |
|     except (IOError, OSError) as e:
 | |
|         module.fail_json(msg="Unable to open file: %s" % to_native(e))
 | |
| 
 | |
|     reader = read_csv(data, dialect, fieldnames)
 | |
| 
 | |
|     if key and key not in reader.fieldnames:
 | |
|         module.fail_json(msg="Key '%s' was not found in the CSV header fields: %s" % (key, ', '.join(reader.fieldnames)))
 | |
| 
 | |
|     data_dict = dict()
 | |
|     data_list = list()
 | |
| 
 | |
|     if key is None:
 | |
|         try:
 | |
|             for row in reader:
 | |
|                 data_list.append(row)
 | |
|         except CSVError as e:
 | |
|             module.fail_json(msg="Unable to process file: %s" % to_native(e))
 | |
|     else:
 | |
|         try:
 | |
|             for row in reader:
 | |
|                 if unique and row[key] in data_dict:
 | |
|                     module.fail_json(msg="Key '%s' is not unique for value '%s'" % (key, row[key]))
 | |
|                 data_dict[row[key]] = row
 | |
|         except CSVError as e:
 | |
|             module.fail_json(msg="Unable to process file: %s" % to_native(e))
 | |
| 
 | |
|     module.exit_json(dict=data_dict, list=data_list)
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     main()
 |