Skip to content
Snippets Groups Projects
Commit d7d064bb authored by Massimiliano Adamo's avatar Massimiliano Adamo
Browse files

add log rotation

parent 5ff74874
No related branches found
No related tags found
No related merge requests found
......@@ -14,6 +14,7 @@ Options:
"""
import os
import time
import datetime
import subprocess as sp
import configparser
from docopt import docopt
......@@ -22,14 +23,22 @@ import requests
BASE_URL = 'https://infoblox.geant.org/wapi/v2.6.1'
def os_exit(verbose=None):
def os_exit():
""" exit """
if verbose:
print('+' + 72*'-' + '+')
print('+' + 72*'-' + '+')
# close logging
end_date = time_log()
print('[{}] Job ended'.format(end_date))
print('+' + 72*'=' + '+')
os.sys.exit()
def get_reference(iblox_domain, iblox_user, iblox_pw, verbose=None):
def time_log():
""" return day and time """
return datetime.datetime.now().strftime("%d %b %Y %H:%M:%S")
def get_reference(iblox_domain, iblox_user, iblox_pw):
""" grab reference for txt object """
ref_obj = requests.get(
'{}/record:txt?name=_acme-challenge.{}&_return_as_object=1'.format(
......@@ -45,35 +54,32 @@ def get_reference(iblox_domain, iblox_user, iblox_pw, verbose=None):
except IndexError:
ref = None
if verbose:
if ref:
print('got reference object: {}'.format(ref))
else:
print('{} empty reference object: no challenge to delete'.format(
iblox_domain))
print('+' + 72*'-' + '+')
if ref:
print('got reference object: {}'.format(ref))
else:
print('{} empty reference object: no challenge to delete'.format(
iblox_domain))
print('+' + 72*'-' + '+')
return ref
def delete_challenge(object_reference, iblox_user, iblox_pw, verbose=None):
def delete_challenge(object_reference, iblox_user, iblox_pw):
""" delete txt record """
del_req = requests.delete(
'{}/{}'.format(BASE_URL, object_reference),
auth=(iblox_user, iblox_pw)
)
if verbose:
print('delete challenge - http code (200 expected): {}'.format(del_req.status_code))
print('+' + 72*'-' + '+')
print('delete challenge - http code (200 expected): {}'.format(del_req.status_code))
print('+' + 72*'-' + '+')
return del_req.status_code
def create_challenge(iblox_domain, acme_token, iblox_user, iblox_pw, verbose=None):
def create_challenge(iblox_domain, acme_token, iblox_user, iblox_pw):
""" upload txt record """
if verbose:
print('+' + 72*'-' + '+')
print('creating challenge _acme-challenge.{}'.format(iblox_domain))
print('+' + 72*'-' + '+')
print('creating challenge _acme-challenge.{}'.format(iblox_domain))
post_req = requests.post(
'{}/record:txt'.format(BASE_URL),
......@@ -85,15 +91,14 @@ def create_challenge(iblox_domain, acme_token, iblox_user, iblox_pw, verbose=Non
"view": "External"
}
)
if verbose:
print('create challenge - http code (201 expected): {} {}'.format(
post_req.status_code, post_req.reason))
print('+' + 72*'-' + '+')
print('create challenge - http code (201 expected): {} {}'.format(
post_req.status_code, post_req.reason))
print('+' + 72*'-' + '+')
return post_req.status_code
def run_certbot(cbot_domain, wild_card=None, verbose=None):
def run_certbot(cbot_domain, wild_card=None):
""" get certificate from letsencrypt """
if wild_card:
domain_list = '*.{}'.format(cbot_domain)
......@@ -104,9 +109,7 @@ def run_certbot(cbot_domain, wild_card=None, verbose=None):
+ ' --manual-auth-hook=/root/bin/infoblox_hook.py' \
+ ' --cert-name {} -d {}'.format(cbot_domain[0], domain_list)
if verbose:
print('+' + 72*'-' + '+')
print('running: {}'.format(cbot_cmd))
print('running: {}'.format(cbot_cmd))
cbot_child = sp.Popen(cbot_cmd, stdout=sp.PIPE, stderr=sp.PIPE, shell=True)
cbot_out, cbot_err = cbot_child.communicate()
......@@ -116,8 +119,7 @@ def run_certbot(cbot_domain, wild_card=None, verbose=None):
decoded_msg = cbot_out.decode("utf-8")
msg = decoded_msg[:decoded_msg.rfind('\n')]
if verbose:
print('\n{}'.format(msg))
print('\n{}'.format(msg))
return msg
......@@ -130,6 +132,14 @@ if __name__ == "__main__":
CLIENTS = ARGS['--client']
WILDCARD = ARGS['--wildcard']
VERBOSE = ARGS['--verbose']
if not VERBOSE:
os.sys.stdout = open('/var/log/acme/acme.log', 'a')
# start logging
START_DATE = time_log()
CMD_LINE = ' '.join(os.sys.argv)
print('+' + 72*'=' + '+')
print('[{}] Jost started: {}'.format(START_DATE, CMD_LINE))
CONFIG = configparser.RawConfigParser()
CONFIG.read_file(open('/root/.geant_acme.ini'))
......@@ -141,47 +151,44 @@ if __name__ == "__main__":
else:
REAL_DOMAIN = 'host {}'.format(DOMAIN[0])
if VERBOSE:
print('+' + 72*'-' + '+')
print('+' + 72*'-' + '+')
# Maybe there is an Acme challenge left over. We try to delete it first.
for domain_item in DOMAIN:
REF_OBJ = get_reference(domain_item, IBLOX_USER, IBLOX_PASS, VERBOSE)
REF_OBJ = get_reference(domain_item, IBLOX_USER, IBLOX_PASS)
if REF_OBJ == 'error':
print('error retrieving reference object')
os_exit(VERBOSE)
os_exit()
if REF_OBJ:
DEL_STATUS = delete_challenge(
REF_OBJ, IBLOX_USER, IBLOX_PASS, VERBOSE)
REF_OBJ, IBLOX_USER, IBLOX_PASS)
if DEL_STATUS != 200:
print('{}: {} error deleting challenge on Infoblox'.format(
domain_item, DEL_STATUS))
os_exit(VERBOSE)
os_exit()
# run certbot
run_certbot(DOMAIN, WILDCARD, VERBOSE)
if VERBOSE:
print('sleep 10 seconds to wait for DNS to settle down')
print('+' + 72*'-' + '+')
run_certbot(DOMAIN, WILDCARD)
print('sleep 10 seconds to wait for DNS to settle down')
print('+' + 72*'-' + '+')
time.sleep(10)
# remove the Acme challenges from Infoblox
for domain_item in DOMAIN:
REF_OBJ = get_reference(domain_item, IBLOX_USER, IBLOX_PASS, VERBOSE)
REF_OBJ = get_reference(domain_item, IBLOX_USER, IBLOX_PASS)
if REF_OBJ == 'error':
print('error retrieving reference object')
os_exit(VERBOSE)
os_exit()
if REF_OBJ:
DEL_STATUS = delete_challenge(
REF_OBJ, IBLOX_USER, IBLOX_PASS, VERBOSE)
REF_OBJ, IBLOX_USER, IBLOX_PASS)
if DEL_STATUS != 200:
print('{}: {} error deleting challenge on Infoblox'.format(
domain_item, DEL_STATUS))
os_exit(VERBOSE)
os_exit()
os.sys.exit()
# if we are here, everything went fine and we can upload the certificates
os.sys.stdout.flush()
if WILDCARD:
UPLOADER = '/root/bin/upload_wildcards.py'
if VERBOSE:
......@@ -195,4 +202,4 @@ if __name__ == "__main__":
UPLOADER += ' -v'
os.system(UPLOADER)
os_exit(VERBOSE)
os_exit()
......@@ -76,6 +76,8 @@ if __name__ == "__main__":
DOMAIN = ARGS['--domain']
CLIENT = ARGS['--client']
VERBOSE = ARGS['--verbose']
if not VERBOSE:
os.sys.stdout = open('/var/log/geant_acme.log', 'a')
BASEDIR = '/etc/letsencrypt/live'
......@@ -89,8 +91,7 @@ if __name__ == "__main__":
redis_full_path = '{}:redis_{}_{}'.format(
CLIENT, domain_underscored, certname_renamed)
if VERBOSE:
print('uploading to Redis: {}'.format(redis_full_path))
print('uploading to Redis: {}'.format(redis_full_path))
redis_upload(REDIS_HOST, REDIS_TOKEN, redis_full_path, certdata)
with open(os.path.join(BASEDIR, DOMAIN, 'privkey.pem'), 'r') as keyfile:
......@@ -99,8 +100,8 @@ if __name__ == "__main__":
VAULT_FULL_PATH = 'puppet/{}/vault_wildcard_{}.key'.format(
CLIENT, DOMAIN_UNDERSCORED)
if VERBOSE:
print('uploading to Vault: {}'.format(VAULT_FULL_PATH))
print('uploading to Vault: {}'.format(VAULT_FULL_PATH))
vault_upload(VAULT_HOST, VAULT_TOKEN, VAULT_FULL_PATH, KEYDATA)
redis_save(REDIS_HOST, REDIS_TOKEN)
os.sys.stdout.flush()
# ACME log rotation
#
/var/log/acme/acme.log {
create 660 root root
notifempty
daily
rotate 10
missingok
compress
endscript
}
......@@ -83,8 +83,7 @@ if __name__ == "__main__":
keyname_underscored = keyname.replace('.', '_')
redis_full_path = 'common:redis_{}_{}'.format(
domain_underscored, keyname_underscored)
if VERBOSE:
print('uploading to Redis: {}'.format(redis_full_path))
print('uploading to Redis: {}'.format(redis_full_path))
redis_upload(REDIS_HOST, REDIS_TOKEN, redis_full_path, keydata)
with open(os.path.join(BASEDIR, domain, 'privkey.pem'), 'r') as keyfile:
keydata = keyfile.read()
......@@ -92,8 +91,7 @@ if __name__ == "__main__":
keyname_underscored = 'privkey.pem'.replace('.', '_')
vault_full_path = 'puppet/common/vault_wildcard_{}_{}'.format(
domain_underscored, keyname_underscored)
if VERBOSE:
print('uploading to Vault: {}'.format(vault_full_path))
print('uploading to Vault: {}'.format(vault_full_path))
vault_upload(VAULT_HOST, VAULT_TOKEN, vault_full_path, keydata)
redis_save(REDIS_HOST, REDIS_TOKEN)
......@@ -34,6 +34,8 @@ class geant_acme::files (
source => "puppet:///modules/${module_name}/geant_acme_uploader.py";
'/root/bin/upload_wildcards.py':
source => "puppet:///modules/${module_name}/upload_wildcards.py";
'/root/bin/infoblox_hook.py':
source => "puppet:///modules/${module_name}/infoblox_hook.py";
'/etc/letsencrypt/cli.ini':
mode => '0644',
require => File['/etc/letsencrypt'],
......@@ -41,6 +43,11 @@ class geant_acme::files (
'/root/.geant_acme.ini':
mode => '0640',
content => Sensitive(template("${module_name}/geant_acme.ini.erb"));
'/var/log/acme':
ensure => directory;
'/etc/logrotate.d/acme':
mode => '0644',
source => "puppet:///modules/${module_name}/logrotate_acme";
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment