Quality of Life changes
+ add help output if script arguments are invalid + add custom exit codes to highlight invalid arguments * update code comments * major README rework
This commit is contained in:
parent
59954bb21b
commit
e245cb68de
79
README.md
79
README.md
|
@ -1,31 +1,74 @@
|
||||||
## Blacklist import script
|
## Blacklist import script
|
||||||
|
|
||||||
### ejabberd config
|
### installation
|
||||||
To use this script properly, a separate `yml` file is necessary, as the script will overwrite the file. To further
|
Python 3 virtual environment
|
||||||
protect the config the `allow_only` sections defines only `acl` rules.
|
```bash
|
||||||
|
virtualenv -p python3
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### usage main.py
|
||||||
|
```
|
||||||
|
usage: main.py [-h] [-o OUTFILE] [-dr]
|
||||||
|
|
||||||
|
optional arguments:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
-o OUTFILE, --outfile OUTFILE
|
||||||
|
set path to output file
|
||||||
|
-dr, --dry-run perform a dry run
|
||||||
|
```
|
||||||
|
|
||||||
|
#### without any arguments
|
||||||
|
Running `main.py` without any arguments, will cause the script to update the local cache and the corresponding `.etag`
|
||||||
|
file. After that the script will output the error and the help message to stderr, before exiting with error code `2`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
no outfile assigned
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
#### dry run
|
||||||
|
If `main.py` is executed with `-dr` or `--dry-run` as argument the output would look like this. The script will check
|
||||||
|
the blacklist repository and output everything to stdout without touching any system file.
|
||||||
|
```bash
|
||||||
|
$ /path/blacklist_import: python main.py --dr
|
||||||
|
outfile selected: None
|
||||||
|
acl:
|
||||||
|
spamblacklist:
|
||||||
|
server:
|
||||||
|
- "a-server.tld"
|
||||||
|
- "b-server.tld"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### --outfile /path/
|
||||||
|
Run without the `--dry-run` argument and a valid outfile, the script will return nothing and do its thing.
|
||||||
|
|
||||||
|
##### *ejabberd reload_config*
|
||||||
|
The ejabberd instance will be reloaded automatically, but only if changes in the `outfile` occured.
|
||||||
|
|
||||||
|
## configuration
|
||||||
|
### ejabberd
|
||||||
|
To use this script properly, you need to add this line to the `ACL` section of your ejabberd instance. Furthermore a
|
||||||
|
separate `yml` file is necessary, as the script will overwrite the file. To further protect the integrity of your
|
||||||
|
config the `allow_only` sections defines only `acl` rules.
|
||||||
```yaml
|
```yaml
|
||||||
"/etc/ejabberd/blacklist.yml":
|
"/etc/ejabberd/blacklist.yml":
|
||||||
allow_only:
|
allow_only:
|
||||||
- acl
|
- acl
|
||||||
```
|
```
|
||||||
|
|
||||||
### script configuration
|
### script itself
|
||||||
|
|
||||||
The script is meant to be used in an automatic fashion.
|
The script is meant to be used in an automatic fashion.
|
||||||
Arguments:
|
|
||||||
|
|
||||||
- -dr , --dry-run : perform a dry run. `blacklist.txt` and `.etag` are written but no yaml file is overwritten.
|
For example the script could be executed every day at 00:01 to automatically add and remove affected servers from the
|
||||||
- -o , --outfile filepath : set path to output file
|
blacklist file.
|
||||||
|
|
||||||
The dry-run argument will output the file path, if set, in addition to the contents of the yaml file which would have be produced.
|
```cron
|
||||||
|
# jabber blacklist update
|
||||||
|
|
||||||
### script workflow
|
# with virtualenv enabled
|
||||||
1. check if `.etag` file is present
|
1 0 * * * /path/blacklist_import/venv/bin/python /path/blacklist_import/main.py -o /etc/ejabberd/config/blacklist.yml
|
||||||
2. HEAD request
|
|
||||||
2.1 requests etag and `.etag` are equal
|
|
||||||
2.1.1 use local `blacklist.txt` file
|
|
||||||
2.2 requests etag and `.etag` are _not_ equal
|
|
||||||
2.2.1 request new `blacklist.txt`
|
|
||||||
2.2.2 save new `.etag` and `blacklist.txt` file
|
|
||||||
3. process `blacklist.txt` and parse output file
|
|
||||||
|
|
||||||
|
# without virtualenv
|
||||||
|
1 0 * * * python3 /path/blacklist_import/main.py -o /etc/ejabberd/config/blacklist.yml
|
||||||
|
```
|
||||||
|
|
26
main.py
26
main.py
|
@ -67,11 +67,11 @@ class BlacklistImporter:
|
||||||
# first check if blacklist is updated
|
# first check if blacklist is updated
|
||||||
self.request()
|
self.request()
|
||||||
|
|
||||||
|
# only output the selected outfile
|
||||||
if self.dryrun:
|
if self.dryrun:
|
||||||
# only output the selected software and outfile
|
|
||||||
print("outfile selected: %s" % self.outfile)
|
print("outfile selected: %s" % self.outfile)
|
||||||
|
|
||||||
# select ejabberd processing
|
# blacklist processing
|
||||||
self.process()
|
self.process()
|
||||||
|
|
||||||
# reload config if changes have been applied
|
# reload config if changes have been applied
|
||||||
|
@ -86,7 +86,7 @@ class BlacklistImporter:
|
||||||
# init new YAML variable
|
# init new YAML variable
|
||||||
local_file = YAML(typ="safe")
|
local_file = YAML(typ="safe")
|
||||||
|
|
||||||
# prevent None errors
|
# None catch
|
||||||
if self.outfile is not None:
|
if self.outfile is not None:
|
||||||
# prevent FileNotFoundError on first run or file missing
|
# prevent FileNotFoundError on first run or file missing
|
||||||
if os.path.isfile(self.outfile):
|
if os.path.isfile(self.outfile):
|
||||||
|
@ -110,15 +110,29 @@ class BlacklistImporter:
|
||||||
yml.indent(offset=2)
|
yml.indent(offset=2)
|
||||||
yml.default_flow_style = False
|
yml.default_flow_style = False
|
||||||
|
|
||||||
|
# if dry-run true print expected content
|
||||||
if self.dryrun:
|
if self.dryrun:
|
||||||
# if dryrun true print expected content
|
|
||||||
yml.dump(remote_file, sys.stdout)
|
yml.dump(remote_file, sys.stdout)
|
||||||
|
|
||||||
elif local_file != remote_file:
|
|
||||||
self.change = True
|
|
||||||
# only if the local_file and remote_file are unequal write new file
|
# only if the local_file and remote_file are unequal write new file
|
||||||
|
elif local_file != remote_file:
|
||||||
|
|
||||||
|
# prevent FileNotFoundError if self.outfile is not assigned
|
||||||
|
if self.outfile is None:
|
||||||
|
print("no outfile assigned", file=sys.stderr)
|
||||||
|
print(parser.format_help(), file=sys.stderr)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
# proceed to update the defined outfile
|
||||||
|
elif self.outfile is not None:
|
||||||
|
self.change = True
|
||||||
yml.dump(remote_file, open(self.outfile, "w"))
|
yml.dump(remote_file, open(self.outfile, "w"))
|
||||||
|
|
||||||
|
# if that's impossible break and display help message
|
||||||
|
else:
|
||||||
|
print(parser.format_help(), file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
|
Loading…
Reference in New Issue