From e51ef2203af22f780339ff240d224b20b8b47560 Mon Sep 17 00:00:00 2001 From: MacPingu Date: Fri, 17 May 2019 17:10:18 +0200 Subject: [PATCH] initial twitcher support (#76) * initial twitcher support --- Vagrantfile | 4 +- etc/sample-emu-with-twitcher.yml | 24 ++++++ etc/sample-vagrant.yml | 10 ++- group_vars/all | 27 +++--- playbook.yml | 3 +- requirements.yml | 24 +++--- roles/certs/tasks/main.yml | 2 +- roles/common/tasks/main.yml | 18 ++-- roles/pywps/tasks/conda.yml | 4 +- roles/twitcher/handlers/main.yml | 13 +++ roles/twitcher/tasks/conda.yml | 23 +++++ roles/twitcher/tasks/config.yml | 8 ++ roles/twitcher/tasks/db.yml | 8 ++ roles/twitcher/tasks/folders.yml | 9 ++ roles/twitcher/tasks/main.yml | 43 ++++++++++ roles/twitcher/tasks/nginx.yml | 8 ++ roles/twitcher/tasks/source.yml | 12 +++ roles/twitcher/tasks/sqlite.yml | 6 ++ roles/twitcher/tasks/supervisor.yml | 9 ++ roles/twitcher/templates/nginx.conf.j2 | 46 ++++++++++ roles/twitcher/templates/supervisor.conf.j2 | 10 +++ roles/twitcher/templates/twitcher.ini.j2 | 94 +++++++++++++++++++++ vars/main.yml | 31 ++++++- 23 files changed, 391 insertions(+), 45 deletions(-) create mode 100644 etc/sample-emu-with-twitcher.yml create mode 100644 roles/twitcher/handlers/main.yml create mode 100644 roles/twitcher/tasks/conda.yml create mode 100644 roles/twitcher/tasks/config.yml create mode 100644 roles/twitcher/tasks/db.yml create mode 100644 roles/twitcher/tasks/folders.yml create mode 100644 roles/twitcher/tasks/main.yml create mode 100644 roles/twitcher/tasks/nginx.yml create mode 100644 roles/twitcher/tasks/source.yml create mode 100644 roles/twitcher/tasks/sqlite.yml create mode 100644 roles/twitcher/tasks/supervisor.yml create mode 100644 roles/twitcher/templates/nginx.conf.j2 create mode 100644 roles/twitcher/templates/supervisor.conf.j2 create mode 100644 roles/twitcher/templates/twitcher.ini.j2 diff --git a/Vagrantfile b/Vagrantfile index fb02a16..4fbae9a 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -20,8 +20,8 @@ Vagrant.configure("2") do |config| # wps.vm.box = "bento/ubuntu-18.04" # wps.vm.box = "bento/ubuntu-16.04" # wps.vm.box = "bento/debian-9" - # wps.vm.box = "bento/centos-7" - wps.vm.box = "bento/centos-6" + wps.vm.box = "bento/centos-7" + # wps.vm.box = "bento/centos-6" # wps.vm.box = "bento/fedora-27" wps.vm.hostname = "wps.local" wps.vm.network "private_network", ip: "192.168.128.100" diff --git a/etc/sample-emu-with-twitcher.yml b/etc/sample-emu-with-twitcher.yml new file mode 100644 index 0000000..27fe11a --- /dev/null +++ b/etc/sample-emu-with-twitcher.yml @@ -0,0 +1,24 @@ +--- +server_name: 192.168.128.100 +service_enable_https: true +db_install_postgresql: true +db_install_sqlite: false +wps_enable_https: false +# Enable separate Fileserver for WPS outputs +# fs_enabled: false +# fs_host: "{{ server_name }}" +# fs_port: 5001 +# Conda spec +# conda_env_use_spec: false +# Configuration for Emu WPS +wps_services: + - name: emu + hostname: "{{ server_name }}" + fs_hostname: "{{ server_name }}" + port: 5000 + extra_config: | + [data] + cache_path = /tmp/cache +# twitcher +twitcher_enabled: true +twitcher_enable_https: true diff --git a/etc/sample-vagrant.yml b/etc/sample-vagrant.yml index f27604d..2c3b94e 100644 --- a/etc/sample-vagrant.yml +++ b/etc/sample-vagrant.yml @@ -1,8 +1,11 @@ --- server_name: 192.168.128.100 -wps_enable_https: false +service_enable_https: false +#db_install_postgresql: true +#db_install_sqlite: false +# wps_enable_https: false # Enable separate Fileserver for WPS outputs -fs_enabled: false +# fs_enabled: false # fs_host: "{{ server_name }}" # fs_port: 5001 # Conda spec @@ -16,3 +19,6 @@ wps_services: extra_config: | [data] cache_path = /tmp/cache +# twitcher +twitcher_enabled: false +#twitcher_enable_https: false diff --git a/group_vars/all b/group_vars/all index 237cd81..1576cd4 100644 --- a/group_vars/all +++ b/group_vars/all @@ -4,16 +4,22 @@ prefix: /usr/local src_dir: "{{ prefix }}/src" server_name: localhost +service_add_user: true +service_user: wps +# service_uid: 500 +service_group: "{{ service_user }}" +# service_gid: 100 +service_user_home: /var/lib/pywps +# https +service_enable_https: False # postgres db_install_postgresql: true db_install_sqlite: false -db_name: pywps db_host: localhost db_port: 5432 -db_user: pywps -db_password: pywps -db_connect: "postgresql+psycopg2://{{ db_user }}:{{ db_password }}@{{ db_host }}:{{ db_port }}/{{ db_name }}" +db_user: dbuser +db_password: dbuser # nginx fileserver fs_enabled: false @@ -21,14 +27,7 @@ fs_host: localhost fs_port: 6000 # WPS -wps_add_user: true -wps_user: wps -# wps_uid: 1000 -wps_user_home: /var/lib/pywps -wps_group: "{{ wps_user }}" -# wps_gid: 1000 -wps_database: "{{ db_connect }}" -wps_enable_https: false +wps_database: "postgresql+psycopg2://{{ db_user }}:{{ db_password }}@{{ db_host }}:{{ db_port }}/pywps" wps_services: [] # - name: emu # repo: https://github.com/bird-house/emu.git @@ -46,3 +45,7 @@ wps_services: [] # extra_config: | # [data] # cache_path = /tmp + +# twitcher +twitcher_enabled: false +twitcher_database: "postgresql+psycopg2://{{ db_user }}:{{ db_password }}@{{ db_host }}:{{ db_port }}/twitcher" diff --git a/playbook.yml b/playbook.yml index 5a3c309..e5cd850 100644 --- a/playbook.yml +++ b/playbook.yml @@ -26,7 +26,7 @@ - role: jdauphant.ssl-certs tags: nginx - when: wps_enable_https + when: service_enable_https - certs - role: geerlingguy.nginx tags: @@ -36,3 +36,4 @@ tags: db - pywps + - twitcher diff --git a/requirements.yml b/requirements.yml index 4a2510d..d941590 100644 --- a/requirements.yml +++ b/requirements.yml @@ -2,20 +2,20 @@ # miniconda # --------- -# - src: andrewrothstein.miniconda -- src: https://github.com/andrewrothstein/ansible-miniconda/archive/v5.2.1.tar.gz +#- src: andrewrothstein.miniconda +- src: https://github.com/andrewrothstein/ansible-miniconda/archive/v5.2.4.tar.gz name: andrewrothstein.miniconda -# - src: andrewrothstein.bash -- src: https://github.com/andrewrothstein/ansible-bash/archive/v1.1.1.tar.gz +#- src: andrewrothstein.bash +- src: https://github.com/andrewrothstein/ansible-bash/archive/v1.1.2.tar.gz name: andrewrothstein.bash -# - src: andrewrothstein.unarchive-deps -- src: https://github.com/andrewrothstein/ansible-unarchive-deps/archive/v1.0.10.tar.gz +#- src: andrewrothstein.unarchive-deps +- src: https://github.com/andrewrothstein/ansible-unarchive-deps/archive/v1.0.11.tar.gz name: andrewrothstein.unarchive-deps # epel # ---- # Installs the EPEL repository (Extra Packages for Enterprise Linux) for RHEL/CentOS. -# - src: geerlingguy.repo-epel +#- src: geerlingguy.repo-epel - src: https://github.com/geerlingguy/ansible-role-repo-epel/archive/1.2.3.tar.gz name: geerlingguy.repo-epel @@ -27,24 +27,24 @@ # supervisor # ---------- -# - src: geerlingguy.supervisor +#- src: geerlingguy.supervisor - src: https://github.com/geerlingguy/ansible-role-supervisor/archive/2.0.2.tar.gz name: geerlingguy.supervisor # nginx # ----- -# - src: geerlingguy.nginx +#- src: geerlingguy.nginx - src: https://github.com/geerlingguy/ansible-role-nginx/archive/2.6.2.tar.gz name: geerlingguy.nginx # postgresql # ---------- -# - src: ANXS.postgresql +#- src: ANXS.postgresql - src: https://github.com/ANXS/postgresql/archive/v1.10.1.tar.gz name: ANXS.postgresql # ssl-certs # --------- -# - src: jdauphant.ssl-certs -- src: https://github.com/jdauphant/ansible-role-ssl-certs/archive/v1.7.tar.gz +#- src: jdauphant.ssl-certs +- src: https://github.com/jdauphant/ansible-role-ssl-certs/archive/v1.7.1.tar.gz name: jdauphant.ssl-certs diff --git a/roles/certs/tasks/main.yml b/roles/certs/tasks/main.yml index 07b5a4b..964b086 100644 --- a/roles/certs/tasks/main.yml +++ b/roles/certs/tasks/main.yml @@ -5,4 +5,4 @@ mode: 0440 tags: nginx - when: wps_enable_https + when: service_enable_https diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml index e87b97b..6fa73c5 100644 --- a/roles/common/tasks/main.yml +++ b/roles/common/tasks/main.yml @@ -14,19 +14,19 @@ tags: - common -- name: Add WPS group +- name: Add service group group: - name: "{{ wps_group }}" - gid: "{{ wps_gid | default(omit) }}" + name: "{{ service_group }}" + gid: "{{ service_gid | default(omit) }}" state: present -- name: Add WPS user +- name: Add service user user: - name: "{{ wps_user }}" - uid: "{{ wps_uid | default(omit) }}" - groups: "{{ wps_group }}" + name: "{{ service_user }}" + uid: "{{ service_uid | default(omit) }}" + groups: "{{ service_group }}" system: yes shell: /sbin/nologin createhome: no - home: "{{ wps_user_home }}" - when: wps_add_user + home: "{{ service_user_home }}" + when: service_add_user diff --git a/roles/pywps/tasks/conda.yml b/roles/pywps/tasks/conda.yml index bb581a5..902af01 100644 --- a/roles/pywps/tasks/conda.yml +++ b/roles/pywps/tasks/conda.yml @@ -1,6 +1,6 @@ --- - name: Create Conda environment from environment file. - command: "{{ conda_location }}/bin/conda env update -p {{ conda_envs_dir}}/{{ item.name }}" + command: "{{ conda_bin }} env update -p {{ conda_envs_dir}}/{{ item.name }}" args: chdir: "{{ src_dir }}/{{ item.name }}" with_items: "{{ wps_services }}" @@ -11,7 +11,7 @@ - conda - name: Install additional Conda packages. - command: "{{ conda_location }}/bin/conda install -y -p {{ conda_envs_dir}}/{{ item.name }} gunicorn psycopg2" + command: "{{ conda_bin }} install -y -p {{ conda_envs_dir}}/{{ item.name }} gunicorn psycopg2" with_items: "{{ wps_services }}" when: conda_env.changed tags: diff --git a/roles/twitcher/handlers/main.yml b/roles/twitcher/handlers/main.yml new file mode 100644 index 0000000..8ac82d3 --- /dev/null +++ b/roles/twitcher/handlers/main.yml @@ -0,0 +1,13 @@ +--- +- name: restart twitcher + supervisorctl: + name: "twitcher" + state: restarted + # config: "{{ supervisor_config_path}}/supervisord.conf" + username: "{{ supervisor_user }}" + password: "{{ supervisor_password }}" + +- name: restart nginx + service: + name: nginx + state: restarted diff --git a/roles/twitcher/tasks/conda.yml b/roles/twitcher/tasks/conda.yml new file mode 100644 index 0000000..1cc143c --- /dev/null +++ b/roles/twitcher/tasks/conda.yml @@ -0,0 +1,23 @@ +--- +- name: Create Conda environment from environment file. + command: "{{ conda_bin }} env update -p {{ conda_envs_dir}}/twitcher" + args: + chdir: "{{ src_dir }}/twitcher" + register: conda_env_twitcher + tags: + - twitcher + - conda + +- name: Install additional Conda packages. + command: "{{ conda_bin }} install -y -p {{ conda_envs_dir}}/twitcher gunicorn psycopg2" + when: conda_env_twitcher.changed + tags: + - twitcher + - conda + +- name: Install twitcher with pip + command: "{{ conda_envs_dir }}/twitcher/bin/pip install -e {{ src_dir }}/twitcher" + register: conda + tags: + - twitcher + - conda diff --git a/roles/twitcher/tasks/config.yml b/roles/twitcher/tasks/config.yml new file mode 100644 index 0000000..559196a --- /dev/null +++ b/roles/twitcher/tasks/config.yml @@ -0,0 +1,8 @@ +--- +- name: Copy twitcher config + template: + src: ./templates/twitcher.ini.j2 + dest: "{{ twitcher_ini }}" + tags: + - twitcher + - conf diff --git a/roles/twitcher/tasks/db.yml b/roles/twitcher/tasks/db.yml new file mode 100644 index 0000000..e8b1bc1 --- /dev/null +++ b/roles/twitcher/tasks/db.yml @@ -0,0 +1,8 @@ +--- +- name: Migrate database. + command: "{{ conda_envs_dir }}/twitcher/bin/alembic -c {{ twitcher_ini }} upgrade head" + args: + chdir: "{{ src_dir }}/twitcher" + register: twitcher_db + tags: + - twitcher diff --git a/roles/twitcher/tasks/folders.yml b/roles/twitcher/tasks/folders.yml new file mode 100644 index 0000000..4570f14 --- /dev/null +++ b/roles/twitcher/tasks/folders.yml @@ -0,0 +1,9 @@ +--- +- name: Create folders used by twitcher and set owner + file: path={{ item }} state=directory owner={{ twitcher_user }} group={{ twitcher_group }} mode=0755 + with_items: + - /var/lib/twitcher + - /var/run + tags: + - twitcher + - conf diff --git a/roles/twitcher/tasks/main.yml b/roles/twitcher/tasks/main.yml new file mode 100644 index 0000000..b5c1afc --- /dev/null +++ b/roles/twitcher/tasks/main.yml @@ -0,0 +1,43 @@ +--- +- include: source.yml + when: twitcher_enabled + +- include: conda.yml + when: twitcher_enabled + +- include: folders.yml + when: twitcher_enabled + +- include: config.yml + when: twitcher_enabled + +- include: db.yml + when: twitcher_enabled + +- include: sqlite.yml + when: twitcher_enabled and db_install_sqlite + +- include: supervisor.yml + when: twitcher_enabled + +- include: nginx.yml + when: twitcher_enabled + +- name: Assure Twitcher running at end of playbook + command: /bin/true + notify: + - restart twitcher + tags: + - twitcher + - conda + - conf + when: twitcher_enabled + +- name: Assure nginx running at end of playbook + command: /bin/true + notify: + - restart nginx + tags: + - nginx + - conf + when: twitcher_enabled diff --git a/roles/twitcher/tasks/nginx.yml b/roles/twitcher/tasks/nginx.yml new file mode 100644 index 0000000..1a02b1e --- /dev/null +++ b/roles/twitcher/tasks/nginx.yml @@ -0,0 +1,8 @@ +--- +- name: Copy nginx config to remote + template: + src: ./templates/nginx.conf.j2 + dest: "{{ nginx_conf_path }}/twitcher.conf" + tags: + - twitcher + - conf diff --git a/roles/twitcher/tasks/source.yml b/roles/twitcher/tasks/source.yml new file mode 100644 index 0000000..7c547a5 --- /dev/null +++ b/roles/twitcher/tasks/source.yml @@ -0,0 +1,12 @@ +--- +- name: Clone Twitcher. + git: + repo: "https://github.com/bird-house/twitcher" + version: "{{ twitcher_version }}" + dest: "{{ src_dir }}/twitcher" + update: yes + force: yes + register: git + tags: + - twitcher + - git diff --git a/roles/twitcher/tasks/sqlite.yml b/roles/twitcher/tasks/sqlite.yml new file mode 100644 index 0000000..2577fef --- /dev/null +++ b/roles/twitcher/tasks/sqlite.yml @@ -0,0 +1,6 @@ +--- +- name: Update sqlite db file permissions + file: path="/var/lib/twitcher/twitcher.sqlite" state=touch owner={{ twitcher_user }} group={{ twitcher_group }} mode=0644 + tags: + - twitcher + - conf diff --git a/roles/twitcher/tasks/supervisor.yml b/roles/twitcher/tasks/supervisor.yml new file mode 100644 index 0000000..d0d1e33 --- /dev/null +++ b/roles/twitcher/tasks/supervisor.yml @@ -0,0 +1,9 @@ +--- +- name: Copy supervisord job file + template: + src: ./templates/supervisor.conf.j2 + dest: "{{ supervisor_config_path }}/conf.d/twitcher.conf" + owner: root + tags: + - twitcher + - conf diff --git a/roles/twitcher/templates/nginx.conf.j2 b/roles/twitcher/templates/nginx.conf.j2 new file mode 100644 index 0000000..bfb6608 --- /dev/null +++ b/roles/twitcher/templates/nginx.conf.j2 @@ -0,0 +1,46 @@ +# Twitcher: a pyramid app for ows proxy +upstream twitcher { + server unix:/var/run/twitcher.sock fail_timeout=0; +} + +# https server +# http://nginx.org/en/docs/http/configuring_https_servers.html +server +{ + {% if twitcher_enable_https %} + listen {{ twitcher_port }} ssl; + {% else %} + listen {{ twitcher_port }}; + {% endif %} + server_name {{ twitcher_hostname }}; + {% if twitcher_enable_https %} + ssl_certificate {{ ssl_certs_cert_path }}; + ssl_certificate_key {{ ssl_certs_privkey_path }}; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_session_cache shared:SSL:1m; + ssl_session_timeout 1m; + #ssl_crl ca.crl; + ssl_client_certificate {{ ssl_certs_cacert_path }}; + ssl_verify_client {{ ssl_certs_verify_client }}; + ssl_verify_depth 2; + {% endif %} + + # app + location / + { + proxy_pass http://twitcher; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # proxy_set_header X-Forwarded-Proto $scheme; + {% if twitcher_enable_https %} + proxy_set_header X-Forwarded-Ssl on; + #proxy_set_header X-SSL-Client-Cert $ssl_client_cert; + proxy_set_header X-SSL-Client-Verify $ssl_client_verify; + proxy_set_header X-SSL-Client-S-DN $ssl_client_s_dn; + {% endif %} + proxy_redirect off; + } + +} diff --git a/roles/twitcher/templates/supervisor.conf.j2 b/roles/twitcher/templates/supervisor.conf.j2 new file mode 100644 index 0000000..eb3c220 --- /dev/null +++ b/roles/twitcher/templates/supervisor.conf.j2 @@ -0,0 +1,10 @@ +[program:twitcher] +user={{ twitcher_user }} +command={{ conda_envs_dir }}/twitcher/bin/gunicorn --paste {{ twitcher_ini }} +autostart=true +autorestart=true +directory=/var/lib/twitcher +redirect_stderr=true +stdout_logfile=/var/log/supervisor/twitcher.log +killasgroup=false +stopasgroup=false diff --git a/roles/twitcher/templates/twitcher.ini.j2 b/roles/twitcher/templates/twitcher.ini.j2 new file mode 100644 index 0000000..18f202f --- /dev/null +++ b/roles/twitcher/templates/twitcher.ini.j2 @@ -0,0 +1,94 @@ +### +# app configuration +# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:pyramid_twitcher + +pyramid.reload_templates = false +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en + +{% if db_install_sqlite %} +sqlalchemy.url = sqlite:////var/lib/twitcher/twitcher.sqlite +{% else %} +sqlalchemy.url = {{ twitcher_database }} +{% endif %} + +retry.attempts = 3 + +# twitcher +{% if twitcher_enable_https %} +twitcher.url = https://{{ twitcher_hostname }}:{{ twitcher_port }} +{% else %} +twitcher.url = http://{{ twitcher_hostname }}:{{ twitcher_port }} +{% endif %} +twitcher.rcpinterface = true +twitcher.username = +twitcher.password = +twitcher.ows_security = true +twitcher.ows_proxy = true +twitcher.ows_proxy_delegate = false +twitcher.ows_proxy_protected_path = /ows + +### +# wsgi server configuration +### + +[alembic] +# path to migration scripts +script_location = twitcher/alembic +file_template = %%(year)d%%(month).2d%%(day).2d_%%(rev)s +# file_template = %%(rev)s_%%(slug)s + +[server:main] +use = egg:gunicorn#main +bind = unix:/var/run/twitcher.sock +workers = 3 +preload = true +reload = true +accesslog = - +loglevel = warning + +### +# logging configuration +# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, twitcher, sqlalchemy + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_twitcher] +level = DEBUG +handlers = +qualname = twitcher + +[logger_sqlalchemy] +level = WARN +handlers = +qualname = sqlalchemy.engine +# "level = INFO" logs SQL queries. +# "level = DEBUG" logs SQL queries and results. +# "level = WARN" logs neither. (Recommended for production systems.) + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/vars/main.yml b/vars/main.yml index efee9c4..41fcdda 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -3,6 +3,7 @@ miniconda_parent_dir: "{{ prefix }}" miniconda_make_sys_default: False # conda conda_location: "{{ prefix }}/anaconda" +conda_bin: "{{ conda_location }}/bin/conda" conda_envs_dir: "{{ conda_location }}/envs" conda_env_use_spec: false conda_env_spec_file: spec-file.txt @@ -15,11 +16,12 @@ supervisor_unix_http_server_enable: true supervisor_inet_http_server_enable: false supervisor_inet_http_server_port: '*:9001' # nginx -nginx_user: "{{ wps_user }} {{ wps_group }}" +nginx_user: "{{ service_user }} {{ service_group }}" nginx_remove_default_vhost: True # postgres postgresql_databases: - - name: "{{ db_name }}" + - name: "pywps" + - name: "twitcher" postgresql_users: - name: "{{ db_user }}" pass: "{{ db_password }}" @@ -27,8 +29,29 @@ postgresql_listen_addresses: - "{{ db_host }}" postgresql_port: "{{ db_port }}" # ssl-certs -ssl_certs_path_owner: "{{ wps_user }}" -ssl_certs_path_group: "{{ wps_group }}" +ssl_certs_path_owner: "{{ service_user }}" +ssl_certs_path_group: "{{ service_group }}" ssl_certs_cacert_path: "{{ ssl_certs_path }}/cacert.crt" ssl_certs_verify_client: "optional" ssl_certs_cacert_url: "https://github.com/ESGF/esgf-dist/raw/master/installer/certs/esgf-ca-bundle.crt" +# pywps +wps_user: "{{ service_user }}" +wps_group: "{{ service_group }}" +wps_enable_https: "{{ service_enable_https }}" +# twitcher +twitcher_version: "master" +twitcher_user: "{{ service_user }}" +twitcher_group: "{{ service_group }}" +twitcher_hostname: "{{ server_name }}" +twitcher_port: 8000 +twitcher_enable_https: "{{ service_enable_https }}" +twitcher_ini: "/etc/twitcher.ini" +twitcher_rpcinterface: true +twitcher_username: '' +twitcher_password: '' +twitcher_ows_security: true +twitcher_ows_proxy: true +twitcher_ows_proxy_delegate: false +twitcher_ows_proxy_url: true +twitcher_ows_proxy_protected_path: "/ows" +twitcher_ssl_verify_client: "optional"