| #!/usr/bin/python |
| |
| # ***************************************************************************** |
| # |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| # |
| # ****************************************************************************** |
| |
| import logging |
| from fabric.api import * |
| import argparse |
| import sys |
| import os |
| from fabric.contrib.files import exists |
| |
| parser = argparse.ArgumentParser() |
| parser.add_argument('--node_type', type=str, default='', required=True, |
| help='Type of the node where Lets Encrypt certificate should be installed. ' |
| 'Available options: ssn_node, edge_node') |
| parser.add_argument('--os_family', type=str, default='', required=True, |
| help='Operating system type. Available options: debian, redhat') |
| parser.add_argument('--domain_name', type=str, default='', required=True, |
| help='Domain names to apply. ' |
| 'For multiple domains enter a comma separated list of domains as a parameter') |
| parser.add_argument('--email', type=str, default='', |
| help='Email that will be entered during certificate obtaining ' |
| 'and can be user for urgent renewal and security notices. ' |
| 'Use comma to register multiple emails, e.g. u1@example.com,u2@example.com.') |
| args = parser.parse_args() |
| |
| os_user = dlab_user |
| |
| def install_certbot(os_family): |
| try: |
| print('Installing Certbot') |
| if os_family == 'debian': |
| local('sudo apt-get -y update') |
| local('sudo apt-get -y install software-properties-common') |
| local('sudo add-apt-repository -y universe') |
| local('sudo add-apt-repository -y ppa:certbot/certbot') |
| local('sudo apt-get -y update') |
| local('sudo apt-get -y install certbot python-certbot-nginx') |
| elif os_family == 'redhat': |
| print('This OS family is not supported yet') |
| except Exception as err: |
| print('Failed Certbot install: ' + str(err)) |
| sys.exit(1) |
| |
| def run_certbot(domain_name, email): |
| try: |
| print('Running Certbot') |
| local('sudo service nginx stop') |
| if email != '': |
| local('sudo certbot certonly --standalone -n -d {} -m {}'.format(domain_name, email)) |
| else: |
| local('sudo certbot certonly --standalone -n -d {} --register-unsafely-without-email'.format(domain_name)) |
| except Exception as err: |
| print('Failed to run Certbot: ' + str(err)) |
| sys.exit(1) |
| |
| def find_replace_line(file_path, searched_str, replacement_line): |
| try: |
| with open(file_path, 'r') as file: |
| lines = file.readlines() |
| for line in lines: |
| if searched_str in line: |
| line = replacement_line |
| with open(file_path, 'w') as file: |
| file.writelines(lines) |
| except Exception as err: |
| print('Failed to replace string: ' + str(err)) |
| sys.exit(1) |
| |
| def configure_nginx(domain_name, node_type): |
| try: |
| server_name_line =' server_name {};'.format(domain_name) |
| cert_path_line = ' ssl_certificate /etc/letsencrypt/live/{}/fullchain.pem;'.format(domain_name) |
| cert_key_line = ' ssl_certificate_key /etc/letsencrypt/live/{}/privkey.pem;'.format(domain_name) |
| certbot_service = 'ExecStart = /usr/bin/certbot -q renew --pre-hook "service nginx stop" --post-hook "service nginx start"' |
| certbot_service_path = '/lib/systemd/system/certbot.service' |
| if node_type == 'ssn_node': |
| nginx_config_path = '/etc/nginx/conf.d/nginx_proxy.conf' |
| else: |
| nginx_config_path = '/etc/nginx/conf.d/proxy.conf' |
| find_replace_line(nginx_config_path,'server_name' ,server_name_line) |
| find_replace_line(nginx_config_path,'ssl_certificate' ,cert_path_line) |
| find_replace_line(nginx_config_path,'ssl_certificate_key' ,cert_key_line) |
| find_replace_line(certbot_service_path, 'ExecStart', certbot_service) |
| local('sudo systemctl restart nginx') |
| except Exception as err: |
| print('Failed to run Certbot: ' + str(err)) |
| sys.exit(1) |
| |
| if __name__ == "__main__": |
| try: |
| if args.node_type != 'ssn_node' and node_type != 'edge_node': |
| print('Valid node type should be specified. Available options: ssn_node, edge_node') |
| raise Exception |
| if args.os_family != 'debian' and args.os_family != 'redhat': |
| print('Valid os family should be specified. Available options: debian, redhat') |
| raise Exception |
| install_certbot(args.os_family) |
| run_certbot(args.domain_name, args.email) |
| configure_nginx(args.domain_name, args.node_type) |
| except Exception as err: |
| print(str(err)) |
| sys.exit(1) |