Skip to content

Commit

Permalink
Some minor fixes and improvements
Browse files Browse the repository at this point in the history
Including:
- Don't verify LDAP cert by default
- Fix logging error when option --quiet is used
- Add --log-file option
- Improve logging module
- Remove option --verbose
- Catch more LDAP exceptions
- Update tox/travis configs
- Update README files
- Bump version to 2.6.1
  • Loading branch information
peterpakos committed Dec 22, 2017
1 parent 03c6818 commit 343d0b8
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 82 deletions.
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ matrix:
env: TOXENV=pep8py2
- python: "3.6"
env: TOXENV=pep8py3
- python: "2.7"
env: TOXENV=packagepy2
- python: "3.6"
env: TOXENV=packagepy3
install:
- pip install --upgrade pip setuptools wheel tox
script:
- tox
- python setup.py packages
notifications:
email:
on_success: change
Expand Down
70 changes: 43 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,30 @@
Formerly known as ipa_check_consistency and check_ipa_consistency

## Tool to check consistency across FreeIPA servers
The tool can be used as a standalone consistency checker as well as a Nagios/Opsview plug-in (check [Nagios section below](#nagios-plug-in-mode) for more info).
The tool can be used as a standalone consistency checker as well as a
Nagios/Opsview plug-in (check [Nagios section below](#nagios-plug-in-mode) for
more info).

The script was originally written and developed in BASH (until version [v1.3.0](https://github.com/peterpakos/checkipaconsistency/tree/v1.3.0)) and eventually ported to Python in v2.0.0.
The script was originally written and then developed in BASH (until version
[v1.3.0](https://github.com/peterpakos/checkipaconsistency/tree/v1.3.0)) and
eventually ported to Python in v2.0.0.

It has been tested with multiple FreeIPA 4.2+ deployments across a range of operating systems.
It has been tested with multiple FreeIPA 4.2+ deployments across a range of
operating systems.

Requirements:
* FreeIPA 4.2+
* Python 2.7+/3.3+
* Python modules listed in [requirements.txt](https://github.com/peterpakos/checkipaconsistency/blob/master/requirements.txt)
* Python modules listed in
[requirements.txt](https://github.com/peterpakos/checkipaconsistency/blob/master/requirements.txt)

If you spot any problems or have any improvement ideas then feel free to open an issue and I will be glad to look at it for you.
If you spot any problems or have any improvement ideas then feel free to open
an issue and I will be glad to look into it for you.

## Installation
A recommended way of installing the tool is pip install.

Once installed, a command line tool `cipa` will be available.
Once installed, a command line tool `cipa` should be available in your system's PATH.

### pip install
The tool is available in PyPI and can be installed using pip:
Expand All @@ -28,7 +35,8 @@ $ pip install checkipaconsistency
$ cipa --help
```

Please note, in RHEL/CentOS you may also need to install the following packages:
Please note, in RHEL/CentOS you may also need to install the following
packages:
```
$ yum install python-devel openldap-devel
```
Expand All @@ -43,17 +51,21 @@ $ ./cipa --help
```

## Configuration
By default, the tool reads its configuration from `~/.config/checkipaconsistency` file (the location can be overridden by setting environment variable `XDG_CONFIG_HOME`). If the config file (or directory) does not exist then it will be automatically created and populated with sample config upon the next run. Alternatively, you can specify all required options directly from the command line.
By default, the tool reads its configuration from
`~/.config/checkipaconsistency` file (the location can be overridden by setting
environment variable `XDG_CONFIG_HOME`). If the config file (or directory) does
not exist then it will be automatically created and populated with sample
config upon the next run. Alternatively, you can specify all required options
directly from the command line.

## Help
```
$ cipa --help
usage: cipa [-H [HOSTS [HOSTS ...]]] [-d [DOMAIN]]
[-D [BINDDN]] [-W [BINDPW]] [--version] [--help]
[--debug] [--verbose] [--quiet] [--no-header]
[--no-border]
[-n [{,all,users,ustage,upres,ugroups,hosts,hgroups,hbac,sudo,zones,certs,ldap,ghosts,bind,msdcs,replica}]]
[-w WARNING] [-c CRITICAL]
usage: cipa [-H [HOSTS [HOSTS ...]]] [-d [DOMAIN]] [-D [BINDDN]] [-W [BINDPW]]
[--version] [--help] [--debug] [--quiet] [-l [LOG_FILE]]
[--no-header] [--no-border]
[-n [{,all,users,ustage,upres,ugroups,hosts,hgroups,hbac,sudo,zones,certs,ldap,ghosts,bind,msdcs,replica}]]
[-w WARNING] [-c CRITICAL]
Tool to check consistency across FreeIPA servers
Expand All @@ -69,8 +81,9 @@ optional arguments:
--version show program's version number and exit
--help show this help message and exit
--debug debugging mode
--verbose verbose mode
--quiet do not log to console
-l [LOG_FILE], --log-file [LOG_FILE]
log to file (./cipa.log by default)
--no-header disable table header
--no-border disable table border
-n [{,all,users,ustage,upres,ugroups,hosts,hgroups,hbac,sudo,zones,certs,ldap,ghosts,bind,msdcs,replica}]
Expand Down Expand Up @@ -110,18 +123,17 @@ $ cipa -d ipa.example.com -W ********
```
## Debug mode
If you experience any problems with the tool, try running it in the debug mode:

```
$ cipa --debug
2017-12-20 13:39:50,825 [main] DEBUG Namespace(binddn=None, bindpw=None, critical=2, debug=True, disable_border=False, disable_header=False, domain=None, hosts=None, nagios_check=None, quiet=False, verbose=False, warning=1)
2017-12-20 13:39:50,825 [main] DEBUG Initialising...
2017-12-20 13:39:50,825 [main] DEBUG Config file not found at /root/.config/checkipaconsistency
2017-12-20 13:39:50,826 [main] INFO Initial config saved to /root/.config/checkipaconsistency - PLEASE EDIT IT!
2017-12-20 13:39:50,826 [main] CRITICAL IPA domain not set
2017-12-22 20:05:04,494 [main] DEBUG Namespace(binddn=None, bindpw=None, critical=2, debug=True, disable_border=False, disable_header=False, domain=None, hosts=None, log_file=None, nagios_check=None, quiet=False, warning=1)
2017-12-22 20:05:04,494 [main] DEBUG Initialising...
2017-12-22 20:05:04,494 [main] DEBUG Config file not found at /Users/peter/.config/checkipaconsistency
2017-12-22 20:05:04,494 [main] INFO Initial config saved to /Users/peter/.config/checkipaconsistency - PLEASE EDIT IT!
2017-12-22 20:05:04,495 [main] CRITICAL IPA domain not set
```

## Nagios plug-in mode
You can easily transform the tool into a Nagios/Opsview check:
The tool can be easily transformed into a Nagios/Opsview check:
```
$ pip install checkipaconsistency
$ su - nagios
Expand All @@ -142,8 +154,12 @@ OK - Active Users
```

### LDAP Conflicts
Normally conflicting changes between replicas are resolved automatically (the most recent change takes precedence).
However, there are cases where manual intervention is required. If you see LDAP conflicts in the output of this script,
you need to find the conflicting entries and decide which of them should be preserved/deleted.

More information on solving common replication conflicts can be found [here](https://access.redhat.com/documentation/en-us/red_hat_directory_server/10/html/administration_guide/managing_replication-solving_common_replication_conflicts).
Normally conflicting changes between replicas are resolved automatically (the
most recent change takes precedence).
However, there are cases where manual intervention is required. If you see LDAP
conflicts in the output of this script,
you need to find the conflicting entries and decide which of them should be
preserved/deleted.

More information on solving common replication conflicts can be found
[here](https://access.redhat.com/documentation/en-us/red_hat_directory_server/10/html/administration_guide/managing_replication-solving_common_replication_conflicts).
34 changes: 18 additions & 16 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ The tool can be used as a standalone consistency checker as well as a
Nagios/Opsview plug-in (check `Nagios section
below <#nagios-plug-in-mode>`__ for more info).

The script was originally written and developed in BASH (until version
The script was originally written and then developed in BASH (until
version
`v1.3.0 <https://github.com/peterpakos/checkipaconsistency/tree/v1.3.0>`__)
and eventually ported to Python in v2.0.0.

Expand All @@ -25,14 +26,15 @@ Requirements:
`requirements.txt <https://github.com/peterpakos/checkipaconsistency/blob/master/requirements.txt>`__

If you spot any problems or have any improvement ideas then feel free to
open an issue and I will be glad to look at it for you.
open an issue and I will be glad to look into it for you.

Installation
------------

A recommended way of installing the tool is pip install.

Once installed, a command line tool ``cipa`` will be available.
Once installed, a command line tool ``cipa`` should be available in your
system's PATH.

pip install
~~~~~~~~~~~
Expand Down Expand Up @@ -80,12 +82,11 @@ Help
::

$ cipa --help
usage: cipa [-H [HOSTS [HOSTS ...]]] [-d [DOMAIN]]
[-D [BINDDN]] [-W [BINDPW]] [--version] [--help]
[--debug] [--verbose] [--quiet] [--no-header]
[--no-border]
[-n [{,all,users,ustage,upres,ugroups,hosts,hgroups,hbac,sudo,zones,certs,ldap,ghosts,bind,msdcs,replica}]]
[-w WARNING] [-c CRITICAL]
usage: cipa [-H [HOSTS [HOSTS ...]]] [-d [DOMAIN]] [-D [BINDDN]] [-W [BINDPW]]
[--version] [--help] [--debug] [--quiet] [-l [LOG_FILE]]
[--no-header] [--no-border]
[-n [{,all,users,ustage,upres,ugroups,hosts,hgroups,hbac,sudo,zones,certs,ldap,ghosts,bind,msdcs,replica}]]
[-w WARNING] [-c CRITICAL]

Tool to check consistency across FreeIPA servers

Expand All @@ -101,8 +102,9 @@ Help
--version show program's version number and exit
--help show this help message and exit
--debug debugging mode
--verbose verbose mode
--quiet do not log to console
-l [LOG_FILE], --log-file [LOG_FILE]
log to file (./cipa.log by default)
--no-header disable table header
--no-border disable table border
-n [{,all,users,ustage,upres,ugroups,hosts,hgroups,hbac,sudo,zones,certs,ldap,ghosts,bind,msdcs,replica}]
Expand Down Expand Up @@ -150,16 +152,16 @@ debug mode:
::

$ cipa --debug
2017-12-20 13:39:50,825 [main] DEBUG Namespace(binddn=None, bindpw=None, critical=2, debug=True, disable_border=False, disable_header=False, domain=None, hosts=None, nagios_check=None, quiet=False, verbose=False, warning=1)
2017-12-20 13:39:50,825 [main] DEBUG Initialising...
2017-12-20 13:39:50,825 [main] DEBUG Config file not found at /root/.config/checkipaconsistency
2017-12-20 13:39:50,826 [main] INFO Initial config saved to /root/.config/checkipaconsistency - PLEASE EDIT IT!
2017-12-20 13:39:50,826 [main] CRITICAL IPA domain not set
2017-12-22 20:05:04,494 [main] DEBUG Namespace(binddn=None, bindpw=None, critical=2, debug=True, disable_border=False, disable_header=False, domain=None, hosts=None, log_file=None, nagios_check=None, quiet=False, warning=1)
2017-12-22 20:05:04,494 [main] DEBUG Initialising...
2017-12-22 20:05:04,494 [main] DEBUG Config file not found at /Users/peter/.config/checkipaconsistency
2017-12-22 20:05:04,494 [main] INFO Initial config saved to /Users/peter/.config/checkipaconsistency - PLEASE EDIT IT!
2017-12-22 20:05:04,495 [main] CRITICAL IPA domain not set

Nagios plug-in mode
-------------------

You can easily transform the tool into a Nagios/Opsview check:
The tool can be easily transformed into a Nagios/Opsview check:

::

Expand Down
2 changes: 1 addition & 1 deletion checkipaconsistency/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""

VERSION = '2.6.0'
VERSION = '2.6.1'
10 changes: 8 additions & 2 deletions checkipaconsistency/freeipaserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ def __init__(self, fqdn, binddn, bindpw):
self._preserved_user_base = 'cn=deleted users,cn=accounts,cn=provisioning,' + self._base_dn
self._groups_base = 'cn=groups,cn=accounts,' + self._base_dn

ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)

try:
self._conn = ldap.initialize(self._url)
self._conn.set_option(ldap.OPT_NETWORK_TIMEOUT, 3)
Expand All @@ -52,8 +54,12 @@ def __init__(self, fqdn, binddn, bindpw):
ldap.SERVER_DOWN,
ldap.NO_SUCH_OBJECT,
ldap.INVALID_CREDENTIALS
) as err:
self._log.critical('Bind error: %s (%s)' % (err.message['desc'], self.fqdn))
) as e:
if hasattr(e, 'message') and 'desc' in e.message:
msg = e.message['desc']
else:
msg = e.args[0]['desc']
self._log.critical('Bind error: %s (%s)' % (msg, self.fqdn))
exit(1)

self.users = self._count_users(user_base='active')
Expand Down
36 changes: 19 additions & 17 deletions checkipaconsistency/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
import logging


def get_logger(dir_name=None, file_name=None, debug=False, verbose=False, quiet=False, console_level='INFO',
file_level='INFO'):
def get_logger(debug=False, quiet=False, verbose=False, console_level='INFO', file_level=False, log_file=None):
if not verbose:
other_loggers = []
for key in logging.Logger.manager.loggerDict:
Expand All @@ -38,20 +37,10 @@ def get_logger(dir_name=None, file_name=None, debug=False, verbose=False, quiet=
for other_logger in other_loggers:
logging.getLogger(other_logger).propagate = False

if not file_name:
file_name = os.path.splitext(sys.modules['__main__'].__file__)[0] + '.log'

if dir_name:
log_file = '%s/%s' % (dir_name, file_name)
if not os.path.exists(dir_name):
os.makedirs(dir_name)
else:
log_file = file_name

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

if not quiet and console_level:
if console_level and not quiet:
if debug:
console_formatter = logging.Formatter('%(asctime)s [%(module)s] %(levelname)s %(message)s')
else:
Expand All @@ -60,12 +49,25 @@ def get_logger(dir_name=None, file_name=None, debug=False, verbose=False, quiet=
console_handler.setLevel(logging.DEBUG if debug else getattr(logging, console_level.upper()))
console_handler.setFormatter(console_formatter)
logger.addHandler(console_handler)
else:
null_handler = logging.NullHandler()
logger.addHandler(null_handler)

if file_level:
if not log_file:
log_file = os.path.join(
os.path.abspath(os.path.curdir),
os.path.splitext(sys.modules['__main__'].__file__)[0] + '.log'
)

file_formatter = logging.Formatter('%(asctime)s [%(module)s] %(levelname)s %(message)s')
file_handler = logging.FileHandler(log_file, mode='w')
file_handler.setLevel(logging.DEBUG if debug else getattr(logging, file_level.upper()))
file_handler.setFormatter(file_formatter)
logger.addHandler(file_handler)
try:
file_handler = logging.FileHandler(log_file, mode='w')
file_handler.setLevel(logging.DEBUG if debug else getattr(logging, str(file_level).upper()))
file_handler.setFormatter(file_formatter)
logger.addHandler(file_handler)
except (PermissionError, IsADirectoryError, FileNotFoundError) as e:
logger.critical(e)
exit(1)

return logger
Loading

0 comments on commit 343d0b8

Please sign in to comment.