mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 01:18:58 +00:00
state module for ini_manage and ini_option_set return value fix
This commit is contained in:
parent
32c880f952
commit
7811a1d7ba
@ -1,12 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
:maintainer: <ageeleshwar.kandavelu@csscorp.com>
|
||||
:maturity: new
|
||||
:depends: re
|
||||
:platform: all
|
||||
|
||||
Module for editing ini files through saltstack
|
||||
|
||||
use section as DEFAULT_IMPLICIT if your ini file does not have any section
|
||||
for example /etc/sysctl.conf
|
||||
|
||||
@author: akilesh
|
||||
"""
|
||||
|
||||
|
||||
try:
|
||||
import re
|
||||
HAS_RE = True
|
||||
@ -25,12 +30,16 @@ option_regexp1 = re.compile(r'\s*(.+)\s*(=)\s*(.+)\s*')
|
||||
option_regexp2 = re.compile(r'\s*(.+)\s*(:)\s*(.+)\s*')
|
||||
|
||||
|
||||
def ini_option_set(file_name, sections={}):
|
||||
def ini_option_set(file_name, sections={}, summary=True):
|
||||
"""
|
||||
edit ini files
|
||||
file_name: path of ini_file
|
||||
sections: a dictionary representing the ini file
|
||||
|
||||
returns a dictionary containing the changes made
|
||||
|
||||
set summary=False if return data need not have previous option value
|
||||
|
||||
from cli:
|
||||
salt 'target' ini_manage.ini_option_set path_to_ini_file \
|
||||
'{"section_to_change": {"key": "value"}}'
|
||||
@ -58,14 +67,22 @@ def ini_option_set(file_name, sections={}):
|
||||
inifile.update_section(section,
|
||||
option,
|
||||
sections[section][option])
|
||||
changes[section].update(
|
||||
{
|
||||
option: {
|
||||
'before': current_value,
|
||||
'after': sections[section][option]
|
||||
}
|
||||
})
|
||||
if not summary:
|
||||
changes[section].update({option:
|
||||
sections[section][option]})
|
||||
except:
|
||||
changes[section].update({option: 'error encountered'})
|
||||
ret.update({'error':
|
||||
'while setting option {0} in section {0}'.
|
||||
format(option, section)})
|
||||
err_flag = True
|
||||
break
|
||||
else:
|
||||
changes[section].update({option:
|
||||
{'before': current_value,
|
||||
'after': sections[section][option]}})
|
||||
if not err_flag:
|
||||
inifile.flush()
|
||||
ret.update({'changes': changes})
|
||||
|
204
salt/states/ini_manage.py
Normal file
204
salt/states/ini_manage.py
Normal file
@ -0,0 +1,204 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
:maintainer: <ageeleshwar.kandavelu@csscorp.com>
|
||||
:maturity: new
|
||||
:depends: re
|
||||
:platform: all
|
||||
|
||||
Module for managing ini files through salt states
|
||||
|
||||
use section as DEFAULT_IMPLICIT if your ini file does not have any section
|
||||
for example /etc/sysctl.conf
|
||||
"""
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Only load if the mysql module is available
|
||||
'''
|
||||
return 'ini_manage' if 'ini_manage.ini_option_set' in __salt__ else False
|
||||
|
||||
|
||||
def options_present(name, sections={}):
|
||||
"""
|
||||
/home/saltminion/api-paste.ini:
|
||||
ini_manage:
|
||||
- options_present
|
||||
- sections:
|
||||
test:
|
||||
testkey: "testval"
|
||||
secondoption: "secondvalue"
|
||||
test1:
|
||||
testkey1: "testval121"
|
||||
|
||||
options present in file and not specified in sections
|
||||
dict will be untouched
|
||||
changes dict will contain the list of changes made
|
||||
"""
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': "No anomaly detected"
|
||||
}
|
||||
if __opts__['test']:
|
||||
ret['result'] = None
|
||||
ret['comment'] = 'ini file {0} shall be validated for presence of\
|
||||
given options under their respective sections'.format(name)
|
||||
return ret
|
||||
for section in sections:
|
||||
for key in sections[section]:
|
||||
current_value = __salt__['ini_manage.ini_option_get'](name,
|
||||
section,
|
||||
key)
|
||||
if current_value == sections[section][key]:
|
||||
continue
|
||||
ret['changes'] = __salt__['ini_manage.ini_option_set'](name,
|
||||
sections)
|
||||
if 'error' in ret['changes']:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Errors encountered. {0}'.\
|
||||
format(ret['changes'])
|
||||
ret['changes'] = {}
|
||||
else:
|
||||
ret['comment'] = "Changes take effect"
|
||||
return ret
|
||||
|
||||
|
||||
def options_absent(name, sections={}):
|
||||
"""
|
||||
/home/saltminion/api-paste.ini:
|
||||
ini_manage:
|
||||
- options_absent
|
||||
- sections:
|
||||
test:
|
||||
- testkey
|
||||
- secondoption
|
||||
test1:
|
||||
- testkey1
|
||||
|
||||
options present in file and not specified in sections
|
||||
dict will be untouched
|
||||
changes dict will contain the list of changes made
|
||||
"""
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': "No anomaly detected"
|
||||
}
|
||||
if __opts__['test']:
|
||||
ret['result'] = None
|
||||
ret['comment'] = 'ini file {0} shall be validated for absence of\
|
||||
given options under their respective sections'.format(name)
|
||||
return ret
|
||||
for section in sections:
|
||||
for key in sections[section]:
|
||||
current_value = __salt__['ini_manage.ini_option_remove'](name,
|
||||
section,
|
||||
key)
|
||||
if not current_value:
|
||||
continue
|
||||
if not section in ret['changes']:
|
||||
ret['changes'].update({section: {}})
|
||||
ret['changes'][section].update({key: {'before': current_value,
|
||||
'after': None}})
|
||||
ret['comment'] = "Changes take effect"
|
||||
return ret
|
||||
|
||||
|
||||
def sections_present(name, sections={}):
|
||||
"""
|
||||
/home/saltminion/api-paste.ini:
|
||||
ini_manage:
|
||||
- sections_present
|
||||
- sections:
|
||||
test:
|
||||
testkey: testval
|
||||
secondoption: secondvalue
|
||||
test1:
|
||||
testkey1: "testval121"
|
||||
|
||||
options present in file and not specified in sections will be deleted
|
||||
changes dict will contain the sections that changed
|
||||
"""
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': "No anomaly detected"
|
||||
}
|
||||
if __opts__['test']:
|
||||
ret['result'] = None
|
||||
ret['comment'] = 'ini file {0} shall be validated for presence of\
|
||||
given sections with the exact contents'.format(name)
|
||||
return ret
|
||||
for section in sections:
|
||||
cur_section = __salt__['ini_manage.ini_section_get'](name, section)
|
||||
if _same(cur_section, sections[section]):
|
||||
continue
|
||||
__salt__['ini_manage.ini_section_remove'](name, section)
|
||||
changes = __salt__['ini_manage.ini_option_set'](name, {section:
|
||||
sections[section]},
|
||||
summary=False)
|
||||
if 'error' in changes:
|
||||
ret['result'] = False
|
||||
ret['changes'] = 'Errors encountered'
|
||||
return ret
|
||||
ret['changes'][section] = {'before': {section: cur_section},
|
||||
'after': changes['changes']}
|
||||
ret['comment'] = "Changes take effect"
|
||||
return ret
|
||||
|
||||
|
||||
def sections_absent(name, sections=[]):
|
||||
"""
|
||||
/home/saltminion/api-paste.ini:
|
||||
ini_manage:
|
||||
- sections_absent
|
||||
- sections:
|
||||
- test
|
||||
- test1
|
||||
|
||||
options present in file and not specified in sections will be deleted
|
||||
changes dict will contain the sections that changed
|
||||
"""
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': "No anomaly detected"
|
||||
}
|
||||
if __opts__['test']:
|
||||
ret['result'] = None
|
||||
ret['comment'] = 'ini file {0} shall be validated for absense of\
|
||||
given sections'.format(name)
|
||||
return ret
|
||||
for section in sections:
|
||||
cur_section = __salt__['ini_manage.ini_section_remove'](name, section)
|
||||
if not cur_section:
|
||||
continue
|
||||
ret['changes'][section] = {'before': cur_section,
|
||||
'after': None}
|
||||
ret['comment'] = "Changes take effect"
|
||||
return ret
|
||||
|
||||
|
||||
def _same(dict1, dict2):
|
||||
diff = DictDiffer(dict1, dict2)
|
||||
return not (diff.added() or diff.removed() or diff.changed())
|
||||
|
||||
|
||||
class DictDiffer(object):
|
||||
def __init__(self, current_dict, past_dict):
|
||||
self.current_dict = current_dict
|
||||
self.past_dict = past_dict
|
||||
self.set_current = set(current_dict.keys())
|
||||
self.set_past = set(past_dict.keys())
|
||||
self.intersect = self.set_current.intersection(self.set_past)
|
||||
|
||||
def added(self):
|
||||
return self.set_current - self.intersect
|
||||
|
||||
def removed(self):
|
||||
return self.set_past - self.intersect
|
||||
|
||||
def changed(self):
|
||||
return set(o for o in self.intersect if
|
||||
self.past_dict[o] != self.current_dict[o])
|
Loading…
Reference in New Issue
Block a user