o nnh@sddlmZdZdZdZddlZddlZddlmZddl m Z m Z ddl m Z dd lmZdd lmZdd lmZmZmZGd d d ZGdddZGdddeZdS)) annotationsaT name: csvfile author: Jan-Piet Mens (@jpmens) version_added: "1.5" short_description: read data from a TSV or CSV file description: - The csvfile lookup reads the contents of a file in CSV (comma-separated value) format. The lookup looks for the row where the first column matches keyname (which can be multiple words) and returns the value in the O(col) column (default 1, which indexed from 0 means the second column in the file). - At least one keyname is required, provided as a positional argument(s) to the lookup. options: col: description: column to return (0 indexed). default: "1" keycol: description: column to search in (0 indexed). default: 0 type: int version_added: "2.17" default: description: what to return if the value is not found in the file. delimiter: description: field separator in the file, for a tab you can specify V(TAB) or V(\\t). default: TAB file: description: name of the CSV/TSV file to open. default: ansible.csv encoding: description: Encoding (character set) of the used CSV file. default: utf-8 version_added: "2.1" notes: - The default is for TSV files (tab delimited) not CSV (comma delimited) ... yes the name is misleading. - As of version 2.11, the search parameter (text that must match the first column of the file) and filename parameter can be multi-word. - For historical reasons, in the search keyname, quotes are treated literally and cannot be used around the string unless they appear (escaped as required) in the first column of the file you are parsing. seealso: - ref: playbook_task_paths description: Search paths used for relative files. a - name: Match 'Li' on the first column, return the second column (0 based index) ansible.builtin.debug: msg="The atomic number of Lithium is {{ lookup('ansible.builtin.csvfile', 'Li file=elements.csv delimiter=,') }}" - name: msg="Match 'Li' on the first column, but return the 3rd column (columns start counting after the match)" ansible.builtin.debug: msg="The atomic mass of Lithium is {{ lookup('ansible.builtin.csvfile', 'Li file=elements.csv delimiter=, col=2') }}" - name: Define Values From CSV File, this reads file in one go, but you could also use col= to read each in it's own lookup. ansible.builtin.set_fact: loop_ip: "{{ csvline[0] }}" int_ip: "{{ csvline[1] }}" int_mask: "{{ csvline[2] }}" int_name: "{{ csvline[3] }}" local_as: "{{ csvline[4] }}" neighbor_as: "{{ csvline[5] }}" neigh_int_ip: "{{ csvline[6] }}" vars: csvline: "{{ lookup('ansible.builtin.csvfile', bgp_neighbor_ip, file='bgp_neighbors.csv', delimiter=',') }}" delegate_to: localhost # Contents of debug.csv # test1 ret1.1 ret2.1 # test2 ret1.2 ret2.2 # test3 ret1.3 ret2.3 - name: "Lookup multiple keynames in the first column (index 0), returning the values from the second column (index 1)" debug: msg: "{{ lookup('csvfile', 'test1', 'test2', file='debug.csv', delimiter=' ') }}" - name: Lookup multiple keynames using old style syntax debug: msg: "{{ lookup('csvfile', term1, term2) }}" vars: term1: "test1 file=debug.csv delimiter=' '" term2: "test2 file=debug.csv delimiter=' '" zb _raw: description: - value(s) stored in file column type: list elements: str N)MutableSequence) AnsibleErrorAnsibleAssertionError)parse_kv) LookupBase)PY2)to_bytes to_nativeto_textc@s.eZdZdZd ddZddZddZeZd S) CSVRecoderzN Iterator that reads an encoded stream and encodes the input to UTF-8 utf-8cCst|||_dSN)codecs getreaderreader)selffencodingrI/usr/local/lib/python3.10/dist-packages/ansible/plugins/lookup/csvfile.py__init__mszCSVRecoder.__init__cC|Srrrrrr__iter__pzCSVRecoder.__iter__cCst|jdS)Nr )nextrencoderrrr__next__sszCSVRecoder.__next__N)r )__name__ __module__ __qualname____doc__rrrrrrrrr is  r c@s4eZdZdZejdfddZddZeZddZ d S) CSVReaderzu A CSV reader which will iterate over lines in the CSV file "f", which is encoded in the given encoding. r cKs:trt||}nt||}tj|fd|i||_dS)Ndialect)rr rrcsvr)rrr$rkwdsrrrrs zCSVReader.__init__cCst|j}dd|DS)NcSsg|]}t|qSr)r ).0srrr sz&CSVReader.__next__..)rr)rrowrrrrs zCSVReader.__next__cCrrrrrrrrrzCSVReader.__iter__N) rr r!r"r%excelrrrrrrrrr#ys  r#c@s eZdZd ddZd ddZdS) LookupModuler Nrc Csz+tt|d}t|t||d} | D]} t| r(| ||kr(| t|WSqW|Sty?} ztdt| d} ~ ww)Nrb) delimiterrz csvfile: %s)openr r#r lenint Exceptionr) rfilenamekeyr/rdfltcolkeycolrcreaderr*errrread_csvszLookupModule.read_csvc KsXg}|j||d|}|std|D]}t|}d|vr#td|d}z.d} |D]\} } | dkr7q.| |vrAtd| ||| | d} q.| rT|}Wntt fyg} zt| d} ~ ww|ddkrrd |d<| |d |d } | | ||d|d |d |d|d}|durt |t r|D]}||qq||q|S)N) var_optionsdirectz(Search key is required but was not found _raw_paramsFz%s is not a valid optionTr/TAB filesfilerdefaultr7r8) set_options get_optionsrritemsr_deprecate_inline_kv set_option ValueErrorAssertionErrorfind_file_in_search_pathr; isinstancerappend)rterms variableskwargsret paramvalstermkvr5 reset_paramsnamevaluer: lookupfilevarvrrrrunsN   *   zLookupModule.run)r Nr-rr)rr r!r;r[rrrrr,s r,) __future__r DOCUMENTATIONEXAMPLESRETURNrr%collections.abcransible.errorsrransible.parsing.splitterransible.plugins.lookupransible.module_utils.sixr+ansible.module_utils.common.text.convertersr r r r r#r,rrrrs *%