From 445b23b941c8a7460edd00baef2843f2a7ce0554 Mon Sep 17 00:00:00 2001 From: Andrea Dell'Amico Date: Wed, 22 Apr 2020 19:26:33 +0200 Subject: [PATCH] powerdns-admin: use gunicorn instead of flask. Fix the paths, they changed in newer releases. --- .../roles/powerdns-admin/defaults/main.yml | 4 ++ .../roles/powerdns-admin/handlers/main.yml | 2 +- library/roles/powerdns-admin/tasks/main.yml | 59 ++++++++++++---- .../templates/{config.py => config.py.j2} | 69 ++++++++++--------- .../templates/powerdns-admin.service | 14 ---- .../templates/powerdns-admin.service.j2 | 18 +++++ .../templates/powerdns-admin.socket.j2 | 8 +++ .../templates/tmpfiles-powerdns-run.j2 | 1 + library/roles/powerdns-admin/vars/main.yml | 8 ++- 9 files changed, 117 insertions(+), 66 deletions(-) rename library/roles/powerdns-admin/templates/{config.py => config.py.j2} (65%) delete mode 100644 library/roles/powerdns-admin/templates/powerdns-admin.service create mode 100644 library/roles/powerdns-admin/templates/powerdns-admin.service.j2 create mode 100644 library/roles/powerdns-admin/templates/powerdns-admin.socket.j2 create mode 100644 library/roles/powerdns-admin/templates/tmpfiles-powerdns-run.j2 diff --git a/library/roles/powerdns-admin/defaults/main.yml b/library/roles/powerdns-admin/defaults/main.yml index 0b1b4fe3..f26f2abc 100644 --- a/library/roles/powerdns-admin/defaults/main.yml +++ b/library/roles/powerdns-admin/defaults/main.yml @@ -1,5 +1,7 @@ --- pdns_admin_install: True +# Set it manually from the command line when you want to upgrade +pdns_admin_upgrade: False pdns_admin_dir: 'pdns_admin-{{ pdns_admin_version }}.linux-amd64' pdns_admin_git_repo_url: 'https://github.com/ngoduykhanh/PowerDNS-Admin.git' pdns_admin_user: pdnsadmin @@ -7,10 +9,12 @@ pdns_admin_home: /opt/pdnsadmin pdns_admin_cmd: '{{ pdns_admin_dist_dir }}/{{ pdns_admin_dir }}/pdns_admin' pdns_admin_http_port: 9393 pdns_admin_opts: '' +pdns_admin_title: "PowerDNS Admin" pdns_admin_loglevel: 'WARN' pdns_admin_logdir: '/var/log/pdnsadmin' pdns_admin_logfile: '{{ pdns_admin_logdir }}/pdnsadmin.log' pdns_admin_local_pgsql: False +pdns_admin_app_dir: powerdnsadmin pdns_admin_prereqs: - git diff --git a/library/roles/powerdns-admin/handlers/main.yml b/library/roles/powerdns-admin/handlers/main.yml index b2850d61..305509a0 100644 --- a/library/roles/powerdns-admin/handlers/main.yml +++ b/library/roles/powerdns-admin/handlers/main.yml @@ -1,4 +1,4 @@ --- - name: Restart pdns_admin - service: name=powerdns-admin state=restarted + service: name=powerdns-admin.socket state=restarted diff --git a/library/roles/powerdns-admin/tasks/main.yml b/library/roles/powerdns-admin/tasks/main.yml index 84b5175b..2c33008e 100644 --- a/library/roles/powerdns-admin/tasks/main.yml +++ b/library/roles/powerdns-admin/tasks/main.yml @@ -17,14 +17,26 @@ apt: pkg={{ pdns_admin_prereqs }} state=present update_cache=yes cache_valid_time=1800 - name: Clone pdns_admin - git: repo={{ pdns_admin_git_repo_url }} dest={{ pdns_admin_home }} + git: repo={{ pdns_admin_git_repo_url }} dest={{ pdns_admin_home }} update=no + + - name: Force the clone and upgrade pdns_admin when updating + git: repo={{ pdns_admin_git_repo_url }} dest={{ pdns_admin_home }} update=yes force=yes + when: pdns_admin_upgrade | bool + + - name: Remove the files that we use to skip the initialisation commands + file: dest={{ item }} state=absent + with_items: + - '{{ pdns_admin_logdir }}/.db_initialised' + - '{{ pdns_admin_home }}/app/static/generated/login.js' + when: pdns_admin_upgrade | bool - name: Make the upload directory writeable by the pdnsadmin user file: dest={{ pdns_admin_home }}/upload recurse=yes owner={{ pdns_admin_user }} group={{ pdns_admin_user }} - name: Install the pdns_admin configuration - template: src=config.py dest={{ pdns_admin_home }}/config.py owner=root group={{ pdns_admin_user }} mode=0640 + template: src=config.py.j2 dest={{ pdns_admin_home }}/{{ pdns_admin_app_dir }}/default_config.py owner=root group={{ pdns_admin_user }} mode=0640 notify: Restart pdns_admin + tags: [ 'pdns_admin', 'pdns_admin_config' ] - name: Create a python3 virtualenv shell: cd {{ pdns_admin_home }} ; virtualenv -p python3 flask @@ -41,7 +53,7 @@ notify: Restart pdns_admin - name: Initialise the database - shell: cd {{ pdns_admin_home }}; . {{ pdns_admin_home }}/flask/bin/activate ; export FLASK_APP=app/__init__.py ; flask db upgrade && touch {{ pdns_admin_logdir }}/.db_initialised + shell: cd {{ pdns_admin_home }}; . {{ pdns_admin_home }}/flask/bin/activate ; export FLASK_APP={{ pdns_admin_app_dir }}/__init__.py ; flask db upgrade && touch {{ pdns_admin_logdir }}/.db_initialised args: creates: '{{ pdns_admin_logdir }}/.db_initialised' @@ -53,26 +65,43 @@ - name: Some directories must be writeable by the pdnsadmin user file: dest={{ item }} recurse=yes owner={{ pdns_admin_user }} group={{ pdns_admin_user }} with_items: - - '{{ pdns_admin_home }}/app/static/custom' - - '{{ pdns_admin_home }}/app/static/.webassets-cache' - - - name: Install the pdns_admin server systemd unit - template: src=powerdns-admin.service dest=/etc/systemd/system/powerdns-admin.service mode=0644 owner=root group=root - when: ansible_service_mgr == 'systemd' - notify: systemd reload - - - name: Ensure that pdns_admin is started and enabled - service: name=powerdns-admin state=started enabled=yes + - '{{ pdns_admin_home }}/{{ pdns_admin_app_dir }}/static/custom' + - '{{ pdns_admin_home }}/{{ pdns_admin_app_dir }}/static/.webassets-cache' tags: pdns_admin when: pdns_admin_install +- block: + - name: Install the tmpfile configuration + template: src=tmpfiles-powerdns-run.j2 dest=/usr/lib/tmpfiles.d/powerdns-admin.conf owner=root group=root + + - name: Install the pdns_admin server systemd units + template: src={{ item }}.j2 dest=/etc/systemd/system/{{ item }} mode=0644 owner=root group=root + with_items: + - 'powerdns-admin.service' + - 'powerdns-admin.socket' + register: pdns_unit + notify: Restart pdns_admin + + - name: Reload the systemd configuration + systemd: daemon_reload=yes + when: pdns_unit is changed + + - name: Ensure that pdns_admin is started and enabled + service: name=powerdns-admin.socket state=started enabled=yes + + tags: [ 'pdns_admin', 'pdns_admin_service', 'pdns_admin_config' ] + when: pdns_admin_install + - block: - name: Ensure that pdns_admin is stopped and disabled service: name=powerdns-admin state=stopped enabled=no - - name: Remove the pdns_admin init script - file: dest=/etc/systemd/system/powerdns-admin.service state=absent + - name: Remove the pdns_admin init scripts + file: dest=/etc/systemd/system/powerdns-admin.{{ item }} state=absent + with_items: + - 'service' + - 'socket' - name: Remove all the pdns_admin files file: dest={{ item }} state=absent diff --git a/library/roles/powerdns-admin/templates/config.py b/library/roles/powerdns-admin/templates/config.py.j2 similarity index 65% rename from library/roles/powerdns-admin/templates/config.py rename to library/roles/powerdns-admin/templates/config.py.j2 index 301ff1fb..96320fbe 100644 --- a/library/roles/powerdns-admin/templates/config.py +++ b/library/roles/powerdns-admin/templates/config.py.j2 @@ -6,12 +6,13 @@ WTF_CSRF_ENABLED = True SECRET_KEY = '{{ pdns_admin_secret_key }}' BIND_ADDRESS = '127.0.0.1' PORT = {{ pdns_admin_http_port }} -LOGIN_TITLE = "PowerDNS Admin" +LOGIN_TITLE = "{{ pdns_admin_title }}" # TIMEOUT - for large zones TIMEOUT = 60 # LOG CONFIG +LOGLEVEL = '{{ pdns_admin_loglevel }}' LOG_LEVEL = '{{ pdns_admin_loglevel }}' LOG_FILE = '{{ pdns_admin_logfile }}' @@ -28,16 +29,16 @@ LDAP_TYPE = 'ldap' LDAP_URI = 'ldaps://your-ldap-server:636' # with LDAP_BIND_TYPE you can specify 'direct' or 'search' to use user credentials # for binding or a predefined LDAP_USERNAME and LDAP_PASSWORD, binding with non-DN only works with AD -LDAP_BIND_TYPE= 'direct' # direct or search -LDAP_USERNAME = 'cn=dnsuser,ou=users,ou=services,dc=duykhanh,dc=me' -LDAP_PASSWORD = 'dnsuser' -LDAP_SEARCH_BASE = 'ou=System Admins,ou=People,dc=duykhanh,dc=me' -LDAP_GROUP_SECURITY = False -LDAP_ADMIN_GROUP = 'CN=PowerDNS-Admin Admin,OU=Custom,DC=ivan,DC=local' -LDAP_USER_GROUP = 'CN=PowerDNS-Admin User,OU=Custom,DC=ivan,DC=local' +# LDAP_BIND_TYPE= 'direct' # direct or search +# LDAP_USERNAME = 'cn=dnsuser,ou=users,ou=services,dc=duykhanh,dc=me' +# LDAP_PASSWORD = 'dnsuser' +# LDAP_SEARCH_BASE = 'ou=System Admins,ou=People,dc=duykhanh,dc=me' +# LDAP_GROUP_SECURITY = False +# LDAP_ADMIN_GROUP = 'CN=PowerDNS-Admin Admin,OU=Custom,DC=ivan,DC=local' +# LDAP_USER_GROUP = 'CN=PowerDNS-Admin User,OU=Custom,DC=ivan,DC=local' # Additional options only if LDAP_TYPE=ldap -LDAP_USERNAMEFIELD = 'uid' -LDAP_FILTER = '(objectClass=inetorgperson)' +# LDAP_USERNAMEFIELD = 'uid' +# LDAP_FILTER = '(objectClass=inetorgperson)' # enable LDAP_GROUP_SECURITY to allow Admin and User roles based on LDAP groups #LDAP_GROUP_SECURITY = True # True or False #LDAP_ADMIN_GROUP = 'CN=DnsAdmins,CN=Users,DC=example,DC=me' @@ -56,40 +57,40 @@ LDAP_FILTER = '(objectClass=inetorgperson)' # Github Oauth GITHUB_OAUTH_ENABLE = False -GITHUB_OAUTH_KEY = '' -GITHUB_OAUTH_SECRET = '' -GITHUB_OAUTH_SCOPE = 'email' -GITHUB_OAUTH_URL = 'http://127.0.0.1:9191/api/v3/' -GITHUB_OAUTH_TOKEN = 'http://127.0.0.1:9191/oauth/token' -GITHUB_OAUTH_AUTHORIZE = 'http://127.0.0.1:9191/oauth/authorize' +# GITHUB_OAUTH_KEY = '' +# GITHUB_OAUTH_SECRET = '' +# GITHUB_OAUTH_SCOPE = 'email' +# GITHUB_OAUTH_URL = 'http://127.0.0.1:9191/api/v3/' +# GITHUB_OAUTH_TOKEN = 'http://127.0.0.1:9191/oauth/token' +# GITHUB_OAUTH_AUTHORIZE = 'http://127.0.0.1:9191/oauth/authorize' # Google OAuth GOOGLE_OAUTH_ENABLE = False -GOOGLE_OAUTH_CLIENT_ID = ' ' -GOOGLE_OAUTH_CLIENT_SECRET = ' ' -GOOGLE_REDIRECT_URI = '/user/authorized' -GOOGLE_TOKEN_URL = 'https://accounts.google.com/o/oauth2/token' -GOOGLE_TOKEN_PARAMS = { - 'scope': 'email profile' -} -GOOGLE_AUTHORIZE_URL='https://accounts.google.com/o/oauth2/auth' -GOOGLE_BASE_URL='https://www.googleapis.com/oauth2/v1/' +# GOOGLE_OAUTH_CLIENT_ID = ' ' +# GOOGLE_OAUTH_CLIENT_SECRET = ' ' +# GOOGLE_REDIRECT_URI = '/user/authorized' +# GOOGLE_TOKEN_URL = 'https://accounts.google.com/o/oauth2/token' +# GOOGLE_TOKEN_PARAMS = { + # 'scope': 'email profile' +# } +# GOOGLE_AUTHORIZE_URL='https://accounts.google.com/o/oauth2/auth' +# GOOGLE_BASE_URL='https://www.googleapis.com/oauth2/v1/' # SAML Authnetication SAML_ENABLED = False -SAML_DEBUG = True -SAML_PATH = os.path.join(os.path.dirname(__file__), 'saml') +# SAML_DEBUG = True +# SAML_PATH = os.path.join(os.path.dirname(__file__), 'saml') ##Example for ADFS Metadata-URL -SAML_METADATA_URL = 'https:///FederationMetadata/2007-06/FederationMetadata.xml' +# SAML_METADATA_URL = 'https:///FederationMetadata/2007-06/FederationMetadata.xml' #Cache Lifetime in Seconds -SAML_METADATA_CACHE_LIFETIME = 1 -SAML_SP_ENTITY_ID = 'http://' -SAML_SP_CONTACT_NAME = '' -SAML_SP_CONTACT_MAIL = '' +# SAML_METADATA_CACHE_LIFETIME = 1 +# SAML_SP_ENTITY_ID = 'http://' +# SAML_SP_CONTACT_NAME = '' +# SAML_SP_CONTACT_MAIL = '' #Cofigures if SAML tokens should be encrypted. #If enabled a new app certificate will be generated on restart -SAML_SIGN_REQUEST = False +# SAML_SIGN_REQUEST = False #Use SAML standard logout mechanism retreived from idp metadata #If configured false don't care about SAML session on logout. #Logout from PowerDNS-Admin only and keep SAML session authenticated. @@ -100,7 +101,7 @@ SAML_LOGOUT = False #Default Auth BASIC_ENABLED = True -SIGNUP_ENABLED = True +SIGNUP_ENABLED = False # POWERDNS CONFIG PDNS_STATS_URL = 'http://{{ pdns_master_host }}:8081/' diff --git a/library/roles/powerdns-admin/templates/powerdns-admin.service b/library/roles/powerdns-admin/templates/powerdns-admin.service deleted file mode 100644 index d85c4479..00000000 --- a/library/roles/powerdns-admin/templates/powerdns-admin.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=PowerDNS-Admin -After=network.target - -[Service] -Type=simple -User={{ pdns_admin_user }} -Group={{ pdns_admin_user }} -ExecStart={{ pdns_admin_home }}/flask/bin/python ./run.py -WorkingDirectory={{ pdns_admin_home }} -Restart=always - -[Install] -WantedBy=multi-user.target diff --git a/library/roles/powerdns-admin/templates/powerdns-admin.service.j2 b/library/roles/powerdns-admin/templates/powerdns-admin.service.j2 new file mode 100644 index 00000000..f1541c8c --- /dev/null +++ b/library/roles/powerdns-admin/templates/powerdns-admin.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=PowerDNS-Admin +Requires=powerdns-admin.socket +After=network.target + +[Service] +PIDFile=/run/powerdns-admin/pid +User={{ pdns_admin_user }} +Group={{ pdns_admin_user }} +WorkingDirectory={{ pdns_admin_home }} +ExecStart={{ pdns_admin_home }}/flask/bin/gunicorn --pid /run/powerdns-admin/pid --bind unix:/run/powerdns-admin/socket 'powerdnsadmin:create_app()' +ExecReload=/bin/kill -s HUP $MAINPID +ExecStop=/bin/kill -s TERM $MAINPID +PrivateTmp=true +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/library/roles/powerdns-admin/templates/powerdns-admin.socket.j2 b/library/roles/powerdns-admin/templates/powerdns-admin.socket.j2 new file mode 100644 index 00000000..5eb01ff4 --- /dev/null +++ b/library/roles/powerdns-admin/templates/powerdns-admin.socket.j2 @@ -0,0 +1,8 @@ +[Unit] +Description=PowerDNS-Admin socket + +[Socket] +ListenStream=/run/powerdns-admin/socket + +[Install] +WantedBy=sockets.target diff --git a/library/roles/powerdns-admin/templates/tmpfiles-powerdns-run.j2 b/library/roles/powerdns-admin/templates/tmpfiles-powerdns-run.j2 new file mode 100644 index 00000000..47fbef39 --- /dev/null +++ b/library/roles/powerdns-admin/templates/tmpfiles-powerdns-run.j2 @@ -0,0 +1 @@ +d /run/powerdns-admin 0755 {{ pdns_admin_user }} {{ pdns_admin_user }} - diff --git a/library/roles/powerdns-admin/vars/main.yml b/library/roles/powerdns-admin/vars/main.yml index c92b81ea..0a67536f 100644 --- a/library/roles/powerdns-admin/vars/main.yml +++ b/library/roles/powerdns-admin/vars/main.yml @@ -16,11 +16,15 @@ nginx_virthosts: ssl_enabled: True ssl_only: True ssl_letsencrypt_certs: '{{ nginx_letsencrypt_managed }}' - root: '{{ nginx_webroot }}' + root: '{{ pdns_admin_home }}' server_tokens: 'off' proxy_standard_setup: True locations: + - location: ~ ^/static + other_opts: + - include /etc/nginx/mime.types + - root {{ pdns_admin_home }}/powerdnsadmin - location: / - target: http://localhost:{{ pdns_admin_http_port }} + target: http://unix:/run/powerdns-admin/socket