167167 value: lemonade
168168 mode: '0600'
169169 backup: true
170-
171170- name: Ensure "temperature=cold is in section "[drinks]" in specified file
172171 community.general.ini_file:
173172 path: /etc/anotherconf
174173 section: drinks
175174 option: temperature
176175 value: cold
177176 backup: true
178-
179177- name: Add "beverage=lemon juice" is in section "[drinks]" in specified file
180178 community.general.ini_file:
181179 path: /etc/conf
185183 mode: '0600'
186184 state: present
187185 exclusive: false
188-
189186- name: Ensure multiple values "beverage=coke" and "beverage=pepsi" are in section "[drinks]" in specified file
190187 community.general.ini_file:
191188 path: /etc/conf
196193 - pepsi
197194 mode: '0600'
198195 state: present
199-
200196- name: Add "beverage=lemon juice" outside a section in specified file
201197 community.general.ini_file:
202198 path: /etc/conf
203199 option: beverage
204200 value: lemon juice
205201 state: present
206-
207202- name: Remove the peer configuration for 10.128.0.11/32
208203 community.general.ini_file:
209204 path: /etc/wireguard/wg0.conf
213208 value: 10.128.0.11/32
214209 mode: '0600'
215210 state: absent
216-
217211- name: Add "beverage=lemon juice" outside a section in specified file
218212 community.general.ini_file:
219213 path: /etc/conf
220214 option: beverage
221215 value: lemon juice
222216 state: present
223-
224217- name: Update the public key for peer 10.128.0.12/32
225218 community.general.ini_file:
226219 path: /etc/wireguard/wg0.conf
232225 value: xxxxxxxxxxxxxxxxxxxx
233226 mode: '0600'
234227 state: present
235-
236228- name: Remove the peer configuration for 10.128.0.11/32
237229 community.general.ini_file:
238230 path: /etc/wireguard/wg0.conf
242234 value: 10.4.0.11/32
243235 mode: '0600'
244236 state: absent
245-
246237- name: Update the public key for peer 10.128.0.12/32
247238 community.general.ini_file:
248239 path: /etc/wireguard/wg0.conf
254245 value: xxxxxxxxxxxxxxxxxxxx
255246 mode: '0600'
256247 state: present
248+ - name: Add or replace whole section
249+ community.general.ini_file:
250+ path: /etc/wireguard/wg0.conf
251+ section: Peer
252+ value: |
253+ AllowedIps = 10.4.0.11/32
254+ PublicKey = xxxxxxxxxxxxxxxxxxxx
255+ mode: '0600'
256+ state: present
257257"""
258258
259259import io
@@ -427,74 +427,86 @@ def do_ini(module, filename, section=None, section_has_values=None, option=None,
427427 # 2. edit all the remaining lines where we have a matching option
428428 # 3. delete remaining lines where we have a matching option
429429 # 4. insert missing option line(s) at the end of the section
430-
431- if state == 'present' and option :
432- for index , line in enumerate (section_lines ):
433- if match_function (option , line ):
434- match = match_function (option , line )
435- if values and match .group (8 ) in values :
436- matched_value = match .group (8 )
437- if not matched_value and allow_no_value :
430+ if state == 'present' :
431+ if option :
432+ for index , line in enumerate (section_lines ):
433+ if match_function (option , line ):
434+ match = match_function (option , line )
435+ if values and match .group (8 ) in values :
436+ matched_value = match .group (8 )
437+ if not matched_value and allow_no_value :
438+ # replace existing option with no value line(s)
439+ newline = u'%s\n ' % option
440+ option_no_value_present = True
441+ else :
442+ # replace existing option=value line(s)
443+ newline = assignment_format % (option , matched_value )
444+ (changed , msg ) = update_section_line (option , changed , section_lines , index , changed_lines , ignore_spaces , newline , msg )
445+ values .remove (matched_value )
446+ elif not values and allow_no_value :
438447 # replace existing option with no value line(s)
439448 newline = u'%s\n ' % option
449+ (changed , msg ) = update_section_line (option , changed , section_lines , index , changed_lines , ignore_spaces , newline , msg )
440450 option_no_value_present = True
441- else :
442- # replace existing option=value line(s)
443- newline = assignment_format % (option , matched_value )
444- (changed , msg ) = update_section_line (option , changed , section_lines , index , changed_lines , ignore_spaces , newline , msg )
445- values .remove (matched_value )
446- elif not values and allow_no_value :
447- # replace existing option with no value line(s)
448- newline = u'%s\n ' % option
449- (changed , msg ) = update_section_line (option , changed , section_lines , index , changed_lines , ignore_spaces , newline , msg )
450- option_no_value_present = True
451- break
452-
453- if state == 'present' and exclusive and not allow_no_value :
454- # override option with no value to option with value if not allow_no_value
455- if len (values ) > 0 :
456- for index , line in enumerate (section_lines ):
457- if not changed_lines [index ] and match_function (option , line ):
458- newline = assignment_format % (option , values .pop (0 ))
459- (changed , msg ) = update_section_line (option , changed , section_lines , index , changed_lines , ignore_spaces , newline , msg )
460- if len (values ) == 0 :
461451 break
462- # remove all remaining option occurrences from the rest of the section
463- for index in range (len (section_lines ) - 1 , 0 , - 1 ):
464- if not changed_lines [index ] and match_function (option , section_lines [index ]):
465- del section_lines [index ]
466- del changed_lines [index ]
467- changed = True
468- msg = 'option changed'
469452
470- if state == 'present' :
471- # insert missing option line(s) at the end of the section
472- for index in range (len (section_lines ), 0 , - 1 ):
473- # search backwards for previous non-blank or non-comment line
474- if not non_blank_non_comment_pattern .match (section_lines [index - 1 ]):
475- if option and values :
476- # insert option line(s)
477- for element in values [::- 1 ]:
478- # items are added backwards, so traverse the list backwards to not confuse the user
479- # otherwise some of their options might appear in reverse order for whatever fancy reason ¯\_(ツ)_/¯
480- if element is not None :
481- # insert option=value line
482- section_lines .insert (index , assignment_format % (option , element ))
483- msg = 'option added'
484- changed = True
485- elif element is None and allow_no_value :
486- # insert option with no value line
487- section_lines .insert (index , u'%s\n ' % option )
488- msg = 'option added'
489- changed = True
490- elif option and not values and allow_no_value and not option_no_value_present :
491- # insert option with no value line(s)
492- section_lines .insert (index , u'%s\n ' % option )
493- msg = 'option added'
494- changed = True
495- break
453+ if exclusive and not allow_no_value :
454+ # override option with no value to option with value if not allow_no_value
455+ if len (values ) > 0 :
456+ for index , line in enumerate (section_lines ):
457+ if not changed_lines [index ] and match_function (option , line ):
458+ newline = assignment_format % (option , values .pop (0 ))
459+ (changed , msg ) = update_section_line (option , changed , section_lines , index , changed_lines , ignore_spaces , newline , msg )
460+ if len (values ) == 0 :
461+ break
462+ # remove all remaining option occurrences from the rest of the section
463+ for index in range (len (section_lines ) - 1 , 0 , - 1 ):
464+ if not changed_lines [index ] and match_function (
465+ option , section_lines [index ]
466+ ):
467+ del section_lines [index ]
468+ del changed_lines [index ]
469+ changed = True
470+ msg = 'option changed'
471+
472+ # insert missing option line(s) at the end of the section
473+ for index in range (len (section_lines ), 0 , - 1 ):
474+ # search backwards for previous non-blank or non-comment line
475+ if not non_blank_non_comment_pattern .match (section_lines [index - 1 ]):
476+ if values :
477+ # insert option line(s)
478+ for element in values [::- 1 ]:
479+ # items are added backwards, so traverse the list backwards to not confuse the user
480+ # otherwise some of their options might appear in reverse order for whatever fancy reason ¯\_(ツ)_/¯
481+ if element is not None :
482+ # insert option=value line
483+ section_lines .insert (
484+ index , assignment_format % (option , element )
485+ )
486+ msg = 'option added'
487+ changed = True
488+ elif element is None and allow_no_value :
489+ # insert option with no value line
490+ section_lines .insert (index , u'%s\n ' % option )
491+ msg = 'option added'
492+ changed = True
493+ elif allow_no_value and not option_no_value_present :
494+ # insert option with no value line(s)
495+ section_lines .insert (index , u'%s\n ' % option )
496+ msg = 'option added'
497+ changed = True
498+ break
499+ elif within_section and len (section_lines ) > 0 and len (values ) > 0 :
500+ original = '' .join (section_lines [1 :])
501+ replacement = '' .join (values )
502+ if not replacement .endswith ('\n ' ):
503+ replacement += '\n '
504+ if original != replacement :
505+ section_lines = [section_lines [0 ], replacement ]
506+ msg = 'section replaced'
507+ changed = True
496508
497- if state == 'absent' :
509+ if state == 'absent' :
498510 if option :
499511 if exclusive :
500512 # delete all option line(s) with given option and ignore value
@@ -539,11 +551,20 @@ def do_ini(module, filename, section=None, section_has_values=None, option=None,
539551 for value in condition ['values' ]:
540552 if value not in values :
541553 values .append (value )
542- if option and values :
543- for value in values :
544- ini_lines .append (assignment_format % (option , value ))
545- elif option and not values and allow_no_value :
546- ini_lines .append (u'%s\n ' % option )
554+ if option :
555+ if values :
556+ for value in values :
557+ ini_lines .append (assignment_format % (option , value ))
558+ elif not values and allow_no_value :
559+ ini_lines .append ('%s\n ' % option )
560+ else :
561+ msg = 'only section added'
562+ elif len (values ) > 0 :
563+ replacement = '' .join (values )
564+ if not replacement .endswith ('\n ' ):
565+ replacement += '\n '
566+ ini_lines .append (replacement )
567+ msg = 'section added'
547568 else :
548569 msg = 'only section added'
549570 changed = True
@@ -659,4 +680,4 @@ def main():
659680
660681
661682if __name__ == '__main__' :
662- main ()
683+ main ()
0 commit comments