diff --git a/certbot.py b/certbot.py index f78b3b7..865dfef 100755 --- a/certbot.py +++ b/certbot.py @@ -12,14 +12,15 @@ from subprocess import run import certbot_config as config -# Resolve include directive (non-recursive) +# Resolve 'include' directive (non-recursive) def resolve_include(response, directive): result = [] for index in directive['includes']: + # Join parsed included file to result list result.extend(response['config'][index]['parsed']) return result -# Resolve all include directives (recursive) +# Resolve all 'include' directives (recursive) def resolve_includes(response, directives=None): # Assume resolve of first file in response if not specified if directives is None: @@ -29,10 +30,12 @@ def resolve_includes(response, directives=None): result = [] for directive in directives: if 'includes' in directive: + # Resolve include and recursively resolve includes in included file result.extend(resolve_includes(response, resolve_include(response, directive))) continue if 'block' in directive: + # Recursively traverse block statement directive['block'] = resolve_includes(response, directive['block']) result.append(directive) @@ -45,18 +48,23 @@ def search_directives(directives, fn, recursive=False): for directive in directives: if fn(directive): + # Append directive matched by search function to result list result.append(directive) elif recursive and 'block' in directive: + # Recursively search block statement result.extend(search_directives(directive['block'], fn, True)) return result # Recursive search in directives, steered by matching functions def resolve_path(directives, fns): + # Pick the first search function in the list and perform a flat search results = search_directives(directives, fns[0]) if len(results) > 0 and len(fns) > 1: + # A match for the first path element was found, recurse subtree to find next match return resolve_path(results[0]['block'], fns[1:]) else: + # No further matches were found return results # Get all HTTP server directives @@ -70,24 +78,31 @@ def get_vhosts(directives): servers = get_servers(directives) vhosts = [] for server in servers: + # Retrieve server name directive server_name = search_directives(server['block'], lambda d: ('directive', 'server_name') in d.items()) if len(server_name) == 0: continue for name in server_name[0]['args']: + # Apply server alias to vhosts list vhosts.append(name) return vhosts +# Parse nginx.conf file with Crossplane response = crossplane.parse(config.nginx_config_file) if response['errors']: pprint.pprint(response['errors']) + sys.exit(1) +# Resolve all includes (combine into to one big config tree) directives = resolve_includes(response) +# Retrieve all virtual hostnames vhosts = [ name for name in get_vhosts(directives) if not name in config.ignored_domains ] if config.primary_domain in vhosts: + # Ensure the primary hostname comes first vhosts.remove(config.primary_domain) vhosts.insert(0, config.primary_domain) else: @@ -100,10 +115,11 @@ for name in vhosts: print(' {}'.format(name)) print() +# Build certbot command line cmd = config.certbot_command - for name in vhosts: cmd.extend(['-d', name]) + print('Running', ' '.join(cmd)) print() run(cmd)