state module for ini_manage and ini_option_set return value fix

This commit is contained in:
Akilesh 2014-01-03 16:17:16 +05:30
parent 32c880f952
commit 7811a1d7ba
2 changed files with 229 additions and 8 deletions

View File

@ -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
View 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])