`_ server runs on kedifa partition.
Each `caddy-frontend-N` partition downloads certificates from the kedifa server.
Caucase (exposed by ``kedifa-caucase-url`` in master partition parameters) is used to handle certificates for authentication to kedifa server.
If ``automatic-internal-kedifa-caucase-csr`` is enabled (by default it is) there are scripts running on master partition to simulate human to sign certificates for each caddy-frontend-N node.
Support for X-Real-Ip and X-Forwarded-For
-----------------------------------------
X-Forwarded-For and X-Real-Ip are transmitted to the backend, but only for IPv4 access to the frontend. In case of IPv6 access, the provided IP will be wrong, because of using 6tunnel.
Automatic Internal Caucase CSR
------------------------------
Cluster is composed on many instances, which are landing on separate partitions, so some way is needed to bootstrap trust between the partitions.
There are two ways to achieve it:
* use default, Automatic Internal Caucase CSR used to replace human to sign CSRs against internal CAUCASEs automatic bootstrap, which leads to some issues, described later
* switch to manual bootstrap, which requires human to create and manage user certificate (with caucase-updater) and then sign new frontend nodes appearing in the system
The issues during automatic bootstrap are:
* rouge or hacked SlapOS Master can result with adding rouge frontend nodes to the cluster, which will be trusted, so it will be possible to fetch all certificates and keys from Kedifa or to login to backends
* when new node is added there is short window, when rouge person is able to trick automatic signing, and have it's own node added
In both cases promises will fail on node which is not able to get signed, but in case of Kedifa the damage already happened (certificates and keys are compromised). So in case if cluster administrator wants to stay on the safe side, both automatic bootstraps shall be turned off.
How the automatic signing works
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Having in mind such structure:
* instance with caucase: ``caucase-instance``
* N instances which want to get their CSR signed: ``csr-instance``
In ``caucase-instance`` CAUCASE user is created by automatically signing one user certificate, which allows to sign service certificates.
The ``csr-instance`` creates CSR, extracts the ID of the CSR, exposes it via HTTP and ask caucase on ``caucase-instance`` to sign it. The ``caucase-instance`` checks that exposed CSR id matches the one send to caucase and by using created user to signs it.
buildout.hash.cfg 0000664 0000000 0000000 00000010042 13723117434 0034651 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend # THIS IS NOT A BUILDOUT FILE, despite purposedly using a compatible syntax.
# The only allowed lines here are (regexes):
# - "^#" comments, copied verbatim
# - "^[" section beginings, copied verbatim
# - lines containing an "=" sign which must fit in the following categorie.
# - "^\s*filename\s*=\s*path\s*$" where "path" is relative to this file
# Copied verbatim.
# - "^\s*hashtype\s*=.*" where "hashtype" is one of the values supported
# by the re-generation script.
# Re-generated.
# - other lines are copied verbatim
# Substitution (${...:...}), extension ([buildout] extends = ...) and
# section inheritance (< = ...) are NOT supported (but you should really
# not need these here).
[template]
filename = instance.cfg.in
md5sum = dae3bf6daf851b5610a1a6bd83057b29
[template-common]
filename = instance-common.cfg.in
md5sum = 5784bea3bd608913769ff9a8afcccb68
[template-apache-frontend]
filename = instance-apache-frontend.cfg.in
md5sum = 43b3763d4086283e9c7c886e3b89e54b
[template-caddy-replicate]
filename = instance-apache-replicate.cfg.in
md5sum = 19debfbc27c464f451b1eb5bb5ce3c84
[template-slave-list]
_update_hash_filename_ = templates/apache-custom-slave-list.cfg.in
md5sum = 8f518a7b543126ce91fe218255fb201c
[template-replicate-publish-slave-information]
_update_hash_filename_ = templates/replicate-publish-slave-information.cfg.in
md5sum = 7e3ee70c447f8203273d78f66ab519c3
[template-caddy-frontend-configuration]
_update_hash_filename_ = templates/Caddyfile.in
md5sum = 2503056e35463e045db3329bb8b6fae8
[caddy-backend-url-validator]
filename = templates/caddy-backend-url-validator.in
md5sum = 0979a03476e86bf038516c9565dadc17
[template-not-found-html]
_update_hash_filename_ = templates/notfound.html
md5sum = f20d6c3d2d94fb685f8d26dfca1e822b
[template-default-slave-virtualhost]
_update_hash_filename_ = templates/default-virtualhost.conf.in
md5sum = 266f175dbdfc588af7a86b0b1884fe73
[template-backend-haproxy-configuration]
_update_hash_filename_ = templates/backend-haproxy.cfg.in
md5sum = 68a7758ca8f8b544ba9bc756824be3d3
[template-log-access]
_update_hash_filename_ = templates/template-log-access.conf.in
md5sum = f8068179333ce19e95df561c70073857
[template-empty]
_update_hash_filename_ = templates/empty.in
md5sum = 7155b18edfe128825b8d1f48071454a6
[template-wrapper]
_update_hash_filename_ = templates/wrapper.in
md5sum = 975177dedf677d24e14cede5d13187ce
[template-trafficserver-records-config]
_update_hash_filename_ = templates/trafficserver/records.config.jinja2
md5sum = f3f31188de56bb35383335b3219537f4
[template-trafficserver-storage-config]
_update_hash_filename_ = templates/trafficserver/storage.config.jinja2
md5sum = baf7b89cc9ab5506100b0c900808c1ea
[template-trafficserver-logging-config]
_update_hash_filename_ = templates/trafficserver/logging.config.jinja2
md5sum = 6aed31174dc262ced02f31624321df41
[template-nginx-eventsource-slave-virtualhost]
_update_hash_filename_ = templates/nginx-eventsource-slave.conf.in
md5sum = 217a6c801b8330b0b825f7b8b4c77184
[template-caddy-lazy-script-call]
_update_hash_filename_ = templates/apache-lazy-script-call.sh.in
md5sum = 77d60840591de67b64ab3572e46273a0
[template-graceful-script]
_update_hash_filename_ = templates/graceful-script.sh.in
md5sum = 061cc244558fd3af2b6bacf17cae5555
[template-validate-script]
_update_hash_filename_ = templates/validate-script.sh.in
md5sum = 53e5d7ba2827bff003051f74f24ffe4f
[template-configuration-state-script]
_update_hash_filename_ = templates/configuration-state-script.sh.in
md5sum = 4d2537d2698d32a7e909989f8778d144
[template-rotate-script]
_update_hash_filename_ = templates/rotate-script.sh.in
md5sum = 8c150e1e6c993708d31936742f3a7302
[caddyprofiledeps-setup]
filename = setup.py
md5sum = d9b6476bb0b36cf463fddb00d41dfbaa
[caddyprofiledeps-dummy]
filename = caddyprofiledummy.py
md5sum = 38792c2dceae38ab411592ec36fff6a8
[template-kedifa]
filename = instance-kedifa.cfg.in
md5sum = f77744e52f9d028c39f99cfbf31eadaf
[template-backend-haproxy-rsyslogd-conf]
_update_hash_filename_ = templates/backend-haproxy-rsyslogd.conf.in
md5sum = be899b04e1aa652ed510f20d4ea523dd
caddyprofiledummy.py 0000664 0000000 0000000 00000000231 13723117434 0035511 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend class Recipe(object):
def __init__(self, *args, **kwargs):
pass
def install(self):
return []
def update(self):
return self.install()
common.cfg 0000664 0000000 0000000 00000015404 13723117434 0033377 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend [buildout]
extends =
buildout.hash.cfg
../../stack/slapos.cfg
../../component/dash/buildout.cfg
../../component/caddy/buildout.cfg
../../component/gzip/buildout.cfg
../../component/logrotate/buildout.cfg
../../component/rdiff-backup/buildout.cfg
../../component/trafficserver/buildout.cfg
../../component/6tunnel/buildout.cfg
../../component/xz-utils/buildout.cfg
../../component/rsyslogd/buildout.cfg
../../component/haproxy/buildout.cfg
../../stack/caucase/buildout.cfg
# Monitoring stack (keep on bottom)
../../stack/monitor/buildout.cfg
parts +=
caucase-eggs
template
template-caddy-frontend
template-caddy-replicate
caddy
logrotate
rdiff-backup
caddyprofiledeps
kedifa-develop
kedifa
[kedifa-repository]
recipe = slapos.recipe.build:gitclone
repository = https://lab.nexedi.com/nexedi/kedifa.git
git-executable = ${git:location}/bin/git
revision = d6bbd7db215e12871c1536f22a8fbf994227270c
[kedifa-develop]
recipe = zc.recipe.egg:develop
setup = ${kedifa-repository:location}
[kedifa]
recipe = zc.recipe.egg
eggs =
${python-cryptography:egg}
kedifa
[caddyprofiledeps-setup]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/setup.py
[caddyprofiledeps-dummy]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/caddyprofiledummy.py
[caddyprofiledeps-prepare]
recipe = plone.recipe.command
stop-on-error = True
location = ${buildout:parts-directory}/${:_buildout_section_name_}
update-command = ${:command}
command =
rm -fr ${:location} &&
mkdir -p ${:location} &&
cp ${caddyprofiledeps-setup:target} ${:location}/ &&
cp ${caddyprofiledeps-dummy:target} ${:location}/
[caddyprofiledeps-develop]
recipe = zc.recipe.egg:develop
setup = ${caddyprofiledeps-prepare:location}
[caddyprofiledeps]
depends = ${caddyprofiledeps-develop:recipe}
recipe = zc.recipe.egg
eggs =
caddyprofiledeps
websockify
collective.recipe.shelloutput
[template-common]
recipe = slapos.recipe.template:jinja2
template = ${:_profile_base_location_}/instance-common.cfg.in
rendered = ${buildout:directory}/instance-common.cfg
mode = 0644
context =
key develop_eggs_directory buildout:develop-eggs-directory
key eggs_directory buildout:eggs-directory
[template-frontend-parameter-section]
common_profile = ${template-common:rendered}
logrotate_base_instance = ${template-logrotate-base:rendered}
bin_directory = ${buildout:bin-directory}
sixtunnel = ${6tunnel:location}
caddy = ${caddy:output}
caddy_location = ${caddy:location}
haproxy_executable = ${haproxy:location}/sbin/haproxy
rsyslogd_executable = ${rsyslogd:location}/sbin/rsyslogd
curl = ${curl:location}
dash = ${dash:location}
gzip = ${gzip:location}
logrotate = ${logrotate:location}
openssl = ${openssl:location}/bin/openssl
openssl_cnf = ${openssl:location}/etc/ssl/openssl.cnf
trafficserver = ${trafficserver:location}
sha256sum = ${coreutils:location}/bin/sha256sum
kedifa = ${:bin_directory}/kedifa
kedifa-updater = ${:bin_directory}/kedifa-updater
kedifa-csr = ${:bin_directory}/kedifa-csr
xz_location = ${xz-utils:location}
monitor_template = ${monitor-template:output}
template_backend_haproxy_configuration = ${template-backend-haproxy-configuration:target}
template_backend_haproxy_rsyslogd_conf = ${template-backend-haproxy-rsyslogd-conf:target}
template_caddy_frontend_configuration = ${template-caddy-frontend-configuration:target}
template_graceful_script = ${template-graceful-script:target}
template_validate_script = ${template-validate-script:target}
template_rotate_script = ${template-rotate-script:target}
template_configuration_state_script = ${template-configuration-state-script:target}
template_caddy_lazy_script_call = ${template-caddy-lazy-script-call:target}
template_default_slave_virtualhost = ${template-default-slave-virtualhost:target}
template_empty = ${template-empty:target}
template_log_access = ${template-log-access:target}
template_not_found_html = ${template-not-found-html:target}
template_slave_list = ${template-slave-list:target}
template_trafficserver_records_config = ${template-trafficserver-records-config:target}
template_trafficserver_storage_config = ${template-trafficserver-storage-config:target}
template_trafficserver_logging_config = ${template-trafficserver-logging-config:target}
template_wrapper = ${template-wrapper:output}
[template]
recipe = slapos.recipe.template:jinja2
template = ${:_profile_base_location_}/instance.cfg.in
rendered = ${buildout:directory}/template.cfg
mode = 0644
context =
key common_profile template-common:rendered
key monitor2_template monitor2-template:rendered
key template_caddy_frontend template-caddy-frontend:target
key template_caddy_replicate template-caddy-replicate:target
key template_kedifa template-kedifa:target
key template_replicate_publish_slave_information template-replicate-publish-slave-information:target
key caddy_backend_url_validator caddy-backend-url-validator:output
section template_frontend_parameter_dict template-frontend-parameter-section
key caucase_jinja2_library caucase-jinja2-library:target
[template-caddy-frontend]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/instance-apache-frontend.cfg.in
mode = 0644
[caddy-backend-url-validator]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/caddy-backend-url-validator
mode = 0750
[template-caddy-replicate]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/instance-apache-replicate.cfg.in
mode = 0644
[template-kedifa]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/instance-kedifa.cfg.in
mode = 0644
[download-template]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:_update_hash_filename_}
mode = 640
[template-slave-list]
<=download-template
[template-replicate-publish-slave-information]
<=download-template
[template-caddy-frontend-configuration]
<=download-template
[template-not-found-html]
<=download-template
[template-default-slave-virtualhost]
<=download-template
[template-backend-haproxy-configuration]
<=download-template
[template-log-access]
<=download-template
[template-empty]
<=download-template
[template-wrapper]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/templates/wrapper.in
output = ${buildout:directory}/template-wrapper.cfg
mode = 0644
[template-trafficserver-records-config]
<=download-template
[template-trafficserver-storage-config]
<=download-template
[template-trafficserver-logging-config]
<=download-template
[template-rotate-script]
<=download-template
[template-caddy-lazy-script-call]
<=download-template
[template-graceful-script]
<=download-template
[template-validate-script]
<=download-template
[template-configuration-state-script]
<=download-template
[template-backend-haproxy-rsyslogd-conf]
<=download-template
development.cfg 0000664 0000000 0000000 00000001022 13723117434 0034420 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend # Development profile of caddy-frontend.
# Exactly the same as software.cfg, but fetch the slapos.cookbook
# from git repository instead of fetching stable version,
# allowing to play with bleeding edge environment.
# You'll need to run buildout twice for this profile.
[buildout]
extends =
# Extend in this order, otherwise "parts" will be taken from git profile
common.cfg
parts +=
slapos.toolbox-dev
[slapos.toolbox-dev]
recipe = zc.recipe.egg:develop
egg = slapos.toolbox
setup = ${slapos.toolbox-repository:location}
instance-apache-frontend.cfg.in 0000664 0000000 0000000 00000103752 13723117434 0037360 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend {%- if slap_software_type == software_type -%}
{% import "caucase" as caucase with context %}
{%- set TRUE_VALUES = ['y', 'yes', '1', 'true'] -%}
[buildout]
extends =
{{ parameter_dict['common_profile'] }}
{{ parameter_dict['monitor_template'] }}
{{ parameter_dict['logrotate_base_instance'] }}
parts =
directory
logrotate-entry-caddy
caddy-frontend
switch-caddy-softwaretype
caucase-updater
caucase-updater-promise
backend-client-caucase-updater
backend-client-caucase-updater-promise
frontend-caddy-graceful
port-redirection
promise-frontend-caddy-configuration
promise-caddy-frontend-v4-https
promise-caddy-frontend-v4-http
promise-caddy-frontend-v6-https
promise-caddy-frontend-v6-http
trafficserver-launcher
trafficserver-reload
trafficserver-configuration-directory
trafficserver-records-config
trafficserver-remap-config
trafficserver-plugin-config
trafficserver-storage-config
trafficserver-ip-allow-config
trafficserver-logging-config
trafficserver-promise-listen-port
trafficserver-promise-cache-availability
cron-entry-logrotate-trafficserver
## Monitor for Caddy
monitor-base
monitor-ats-cache-stats-wrapper
monitor-traffic-summary-last-stats-wrapper
monitor-caddy-server-status-wrapper
monitor-verify-re6st-connectivity
backend-haproxy-rsyslogd-configuration
backend-haproxy-rsyslogd
logrotate-entry-backend-haproxy
backend-haproxy
backend-haproxy-graceful
promise-backend-haproxy-http
promise-backend-haproxy-https
promise-backend-haproxy-configuration
# Create all needed directories
[directory]
recipe = slapos.cookbook:mkdirectory
bin = ${buildout:directory}/bin/
etc = ${buildout:directory}/etc/
srv = ${buildout:directory}/srv/
var = ${buildout:directory}/var/
tmp = ${:var}/tmp
template = ${buildout:directory}/template/
backup = ${:srv}/backup
log = ${:var}/log
run = ${:var}/run
backend-haproxy-rsyslogd-spool = ${:run}/backend-haproxy-rsyslogd-spool
service = ${:etc}/service
etc-run = ${:etc}/run
ca-dir = ${:srv}/ssl
backend-client-dir = ${:srv}/backend-client
# BBB: SlapOS Master non-zero knowledge BEGIN
bbb-ssl-dir = ${:srv}/bbb-ssl
# BBB: SlapOS Master non-zero knowledge END
frontend_cluster = ${:var}/frontend_cluster
# csr_id publication
csr_id = ${:srv}/csr_id
caddy-csr_id = ${:etc}/caddy-csr_id
caddy-csr_id-log = ${:log}/httpd-csr_id
[switch-caddy-softwaretype]
recipe = slapos.cookbook:softwaretype
single-default = ${dynamic-custom-personal-template-slave-list:rendered}
single-custom-personal = ${dynamic-custom-personal-template-slave-list:rendered}
[frontend-configuration]
template-log-access = {{ parameter_dict['template_log_access'] }}
log-access-configuration = ${directory:etc}/log-access.conf
ip-access-certificate = ${self-signed-ip-access:certificate}
caddy-directory = {{ parameter_dict['caddy_location'] }}
caddy-ipv6 = {{ instance_parameter['ipv6-random'] }}
caddy-https-port = ${configuration:port}
[self-signed-ip-access]
# Self Signed certificate for HTTPS IP accesses to the frontend
recipe = plone.recipe.command
update-command = ${:command}
ipv6 = ${slap-network-information:global-ipv6}
ipv4 = {{instance_parameter['ipv4-random']}}
certificate = ${caddy-directory:master-autocert-dir}/ip-access-${:ipv6}-${:ipv4}.crt
stop-on-error = True
command =
[ -f ${:certificate} ] && exit 0
rm -f ${:certificate}
/bin/bash -c ' \
{{ parameter_dict['openssl'] }} req \
-new -newkey rsa:2048 -sha256 \
-nodes -x509 -days 36500 \
-keyout ${:certificate} \
-subj "/CN=Self Signed IP Access" \
-reqexts SAN \
-extensions SAN \
-config <(cat {{ parameter_dict['openssl_cnf'] }} \
<(printf "\n[SAN]\nsubjectAltName=IP:${:ipv6},IP:${:ipv4}")) \
-out ${:certificate}'
[self-signed-fallback-access]
# Self Signed certificate for HTTPS access to the frontend with fallback certificate
recipe = plone.recipe.command
update-command = ${:command}
ipv6 = ${slap-network-information:global-ipv6}
ipv4 = {{instance_parameter['ipv4-random']}}
certificate = ${caddy-directory:master-autocert-dir}/fallback-access.crt
stop-on-error = True
command =
[ -f ${:certificate} ] && exit 0
rm -f ${:certificate}
/bin/bash -c ' \
{{ parameter_dict['openssl'] }} req \
-new -newkey rsa:2048 -sha256 \
-nodes -x509 -days 36500 \
-keyout ${:certificate} \
-subj "/CN=Fallback certificate/OU={{ instance_parameter['configuration.frontend-name'] }}" \
-out ${:certificate}'
[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
rendered = ${buildout:directory}/${:filename}
extensions = jinja2.ext.do
extra-context =
slapparameter_dict = {{ dumps(instance_parameter['configuration']) }}
slap_software_type = {{ dumps(instance_parameter['slap-software-type']) }}
context =
import json_module json
raw common_profile {{ parameter_dict['common_profile'] }}
raw logrotate_base_instance {{ parameter_dict['logrotate_base_instance'] }}
raw monitor_template {{ parameter_dict['monitor_template'] }}
key slap_software_type :slap_software_type
key slapparameter_dict :slapparameter_dict
section directory directory
${:extra-context}
[software-release-path]
template-empty = {{ parameter_dict['template_empty'] }}
template-default-slave-virtualhost = {{ parameter_dict['template_default_slave_virtualhost'] }}
template-backend-haproxy-configuration = {{ parameter_dict['template_backend_haproxy_configuration'] }}
template-backend-haproxy-rsyslogd-conf = {{ parameter_dict['template_backend_haproxy_rsyslogd_conf'] }}
caddy-location = {{ parameter_dict['caddy_location'] }}
[kedifa-login-config]
d = ${directory:ca-dir}
template-csr = ${:d}/kedifa-login-template-csr.pem
key = ${:d}/kedifa-login-certificate.pem
certificate = ${:key}
ca-certificate = ${:d}/kedifa-caucase-ca.pem
cas-ca-certificate = ${:d}/kedifa-cas-caucase-ca.pem
crl = ${:d}/kedifa-login-crl.pem
[kedifa-login-csr]
recipe = plone.recipe.command
organization = {{ slapparameter_dict['cluster-identification'] }}
organizational_unit = {{ instance_parameter['configuration.frontend-name'] }}
command =
{% if slapparameter_dict['kedifa-caucase-url'] %}
if [ ! -f ${:template-csr} ] && [ ! -f ${:key} ] ; then
{{ parameter_dict['openssl'] }} req -new -sha256 \
-newkey rsa:2048 -nodes -keyout ${:key} \
-subj "/O=${:organization}/OU=${:organizational_unit}" \
-out ${:template-csr}
fi
{% endif %}
test -f ${:key} && test -f ${:template-csr}
update-command = ${:command}
template-csr = ${kedifa-login-config:template-csr}
key = ${kedifa-login-config:key}
stop-on-error = True
{{ caucase.updater(
prefix='caucase-updater',
buildout_bin_directory=parameter_dict['bin_directory'],
updater_path='${directory:service}/kedifa-login-certificate-caucase-updater',
url=slapparameter_dict['kedifa-caucase-url'],
data_dir='${directory:srv}/caucase-updater',
crt_path='${kedifa-login-config:certificate}',
ca_path='${kedifa-login-config:ca-certificate}',
crl_path='${kedifa-login-config:crl}',
key_path='${kedifa-login-csr:key}',
template_csr='${kedifa-login-csr:template-csr}'
)}}
[kedifa-configuration]
caucase-url = {{ slapparameter_dict['kedifa-caucase-url'] }}
ca-certificate = ${kedifa-login-config:ca-certificate}
certificate = ${kedifa-login-config:certificate}
cas-ca-certificate = ${kedifa-login-config:cas-ca-certificate}
csr = ${caucase-updater-csr:csr}
crl = ${kedifa-login-config:crl}
kedifa-updater = {{ parameter_dict['kedifa-updater'] }}
kedifa-updater-mapping-file = ${directory:etc}/kedifa_updater_mapping.txt
kedifa-updater-state-file = ${directory:srv}/kedifa_updater_state.json
slave_kedifa_information = {{ dumps(slapparameter_dict['slave-kedifa-information']) }}
[backend-client-login-config]
d = ${directory:backend-client-dir}
template-csr = ${:d}/csr.pem
key = ${:d}/certificate.pem
certificate = ${:key}
ca-certificate = ${:d}/ca.pem
cas-ca-certificate = ${:d}/cas-ca.pem
crl = ${:d}/crl.pem
[backend-client-login-csr]
recipe = plone.recipe.command
organization = {{ slapparameter_dict['cluster-identification'] }}
organizational_unit = {{ instance_parameter['configuration.frontend-name'] }}
command =
{% if slapparameter_dict['backend-client-caucase-url'] %}
if [ ! -f ${:template-csr} ] && [ ! -f ${:key} ] ; then
{{ parameter_dict['openssl'] }} req -new -sha256 \
-newkey rsa:2048 -nodes -keyout ${:key} \
-subj "/O=${:organization}/OU=${:organizational_unit}" \
-out ${:template-csr}
fi
{% endif %}
test -f ${:key} && test -f ${:template-csr}
update-command = ${:command}
template-csr = ${backend-client-login-config:template-csr}
key = ${backend-client-login-config:key}
stop-on-error = True
{{ caucase.updater(
prefix='backend-client-caucase-updater',
buildout_bin_directory=parameter_dict['bin_directory'],
updater_path='${directory:service}/backend-client-login-certificate-caucase-updater',
url=slapparameter_dict['backend-client-caucase-url'],
data_dir='${directory:srv}/backend-client-caucase-updater',
crt_path='${backend-client-login-config:certificate}',
ca_path='${backend-client-login-config:ca-certificate}',
crl_path='${backend-client-login-config:crl}',
key_path='${backend-client-login-csr:key}',
template_csr='${backend-client-login-csr:template-csr}'
)}}
[dynamic-custom-personal-template-slave-list]
< = jinja2-template-base
template = {{ parameter_dict['template_slave_list'] }}
filename = custom-personal-instance-slave-list.cfg
slave_instance_list = {{ dumps(instance_parameter['slave-instance-list']) }}
extra_slave_instance_list = {{ dumps(instance_parameter.get('configuration.extra_slave_instance_list')) }}
master_key_download_url = {{ dumps(slapparameter_dict['master-key-download-url']) }}
local_ipv4 = {{ dumps(instance_parameter['ipv4-random']) }}
local_ipv6 = {{ dumps(instance_parameter['ipv6-random']) }}
software_type = single-custom-personal
bin_directory = {{ parameter_dict['bin_directory'] }}
caddy_executable = {{ parameter_dict['caddy'] }}
sixtunnel_executable = {{ parameter_dict['sixtunnel'] }}/bin/6tunnel
organization = {{ slapparameter_dict['cluster-identification'] }}
organizational-unit = {{ instance_parameter['configuration.frontend-name'] }}
backend-client-caucase-url = {{ slapparameter_dict['backend-client-caucase-url'] }}
extra-context =
key caddy_configuration_directory caddy-directory:slave-configuration
key backend_client_caucase_url :backend-client-caucase-url
import urlparse_module urlparse
key caddy_executable :caddy_executable
key http_port configuration:plain_http_port
key https_port configuration:port
key public_ipv4 configuration:public-ipv4
key slave_instance_list :slave_instance_list
key extra_slave_instance_list :extra_slave_instance_list
key master_key_download_url :master_key_download_url
key autocert caddy-directory:autocert
key master_certificate caddy-configuration:master-certificate
key caddy_log_directory caddy-directory:slave-log
key expose_csr_id_organization :organization
key expose_csr_id_organizational_unit :organizational-unit
key local_ipv4 :local_ipv4
key local_ipv6 :local_ipv6
key global_ipv6 slap-network-information:global-ipv6
key empty_template software-release-path:template-empty
key template_default_slave_configuration software-release-path:template-default-slave-virtualhost
key software_type :software_type
key frontend_lazy_graceful_reload frontend-caddy-lazy-graceful:rendered
key frontend_graceful_reload caddy-configuration:frontend-graceful-command
section frontend_configuration frontend-configuration
section caddy_configuration caddy-configuration
key monitor_base_url monitor-instance-parameter:monitor-base-url
key bin_directory :bin_directory
key enable_http2_by_default configuration:enable-http2-by-default
key global_disable_http2 configuration:global-disable-http2
key ciphers configuration:ciphers
key access_log caddy-configuration:access-log
key error_log caddy-configuration:error-log
key sixtunnel_executable :sixtunnel_executable
key not_found_file caddy-configuration:not-found-file
key custom_ssl_directory caddy-directory:custom-ssl-directory
section kedifa_configuration kedifa-configuration
# BBB: SlapOS Master non-zero knowledge BEGIN
key apache_certificate apache-certificate:rendered
# BBB: SlapOS Master non-zero knowledge END
## backend haproxy
key template_backend_haproxy_configuration software-release-path:template-backend-haproxy-configuration
section backend_haproxy_configuration backend-haproxy-configuration
## full configuration
section configuration configuration
# Deploy Caddy Frontend with Jinja power
[dynamic-caddy-frontend-template]
< = jinja2-template-base
template = {{ parameter_dict['template_caddy_frontend_configuration'] }}
rendered = ${caddy-configuration:frontend-configuration}
local_ipv4 = {{ dumps(instance_parameter['ipv4-random']) }}
extra-context =
key httpd_home software-release-path:caddy-location
key httpd_mod_ssl_cache_directory caddy-directory:mod-ssl
key instance_home buildout:directory
key master_certificate caddy-configuration:master-certificate
key access_log caddy-configuration:access-log
key slave_configuration_directory caddy-directory:slave-configuration
section frontend_configuration frontend-configuration
key http_port configuration:plain_http_port
key https_port configuration:port
key local_ipv4 :local_ipv4
key global_ipv6 slap-network-information:global-ipv6
key error_log caddy-configuration:error-log
key not_found_file caddy-configuration:not-found-file
key username monitor-instance-parameter:username
key password monitor-htpasswd:passwd
# BBB: SlapOS Master non-zero knowledge BEGIN
key apache_certificate apache-certificate:rendered
# BBB: SlapOS Master non-zero knowledge END
[caddy-wrapper]
recipe = slapos.recipe.template:jinja2
template = inline:
#!/bin/sh
export CADDYPATH=${directory:frontend_cluster}
ulimit -n $(ulimit -Hn)
exec {{ parameter_dict['caddy'] }} \
-conf ${dynamic-caddy-frontend-template:rendered} \
-log ${caddy-configuration:error-log} \
-log-roll-mb 0 \
{% if instance_parameter['configuration.global-disable-http2'].lower() in TRUE_VALUES %}
-http2=false \
{% else %}
-http2=true \
{% endif %}
-grace {{ instance_parameter['configuration.mpm-graceful-shutdown-timeout'] }}s \
-disable-http-challenge \
-disable-tls-alpn-challenge \
"$@"
rendered = ${directory:bin}/caddy-wrapper
mode = 0755
[caddy-frontend]
recipe = slapos.cookbook:wrapper
command-line = ${caddy-wrapper:rendered} -pidfile ${caddy-configuration:pid-file}
wrapper-path = ${directory:service}/frontend_caddy
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
hash-files = ${caddy-wrapper:rendered}
[not-found-html]
recipe = plone.recipe.command
update-command = ${:command}
filename = notfound.html
command = ln -sf {{ parameter_dict['template_not_found_html'] }} ${caddy-directory:document-root}/${:filename}
[caddy-directory]
recipe = slapos.cookbook:mkdirectory
document-root = ${directory:srv}/htdocs
slave-configuration = ${directory:etc}/caddy-slave-conf.d/
cache = ${directory:var}/cache
mod-ssl = ${:cache}/httpd_mod_ssl
slave-log = ${directory:log}/httpd
autocert = ${directory:srv}/autocert
master-autocert-dir = ${:autocert}/master-autocert
custom-ssl-directory = ${:slave-configuration}/ssl
[caddy-configuration]
frontend-configuration = ${directory:etc}/Caddyfile
access-log = ${directory:log}/frontend-access.log
error-log = ${directory:log}/frontend-error.log
pid-file = ${directory:run}/httpd.pid
frontend-graceful-command = ${frontend-caddy-validate:rendered} && kill -USR1 $(cat ${:pid-file})
not-found-file = ${caddy-directory:document-root}/${not-found-html:filename}
master-certificate = ${caddy-directory:master-autocert-dir}/master.pem
# Communication with ATS
cache-port = ${trafficserver-variable:input-port}
# BBB: SlapOS Master non-zero knowledge BEGIN
[get-self-signed-fallback-access]
recipe = collective.recipe.shelloutput
commands =
certificate = cat ${self-signed-fallback-access:certificate}
[apache-certificate]
recipe = slapos.recipe.template:jinja2
template = inline:
{% raw %}
{{ certificate or fallback_certificate }}
{{ key or '' }}
{% endraw %}
context =
key certificate configuration:apache-certificate
key key configuration:apache-key
key fallback_certificate get-self-signed-fallback-access:certificate
rendered = ${directory:bbb-ssl-dir}/frontend.crt
# BBB: SlapOS Master non-zero knowledge END
[logrotate-entry-caddy]
<= logrotate-entry-base
name = caddy
log = ${caddy-configuration:error-log} ${caddy-configuration:access-log}
rotate-num = ${configuration:rotate-num}
# Note: Slaves do not define their own reload, as this would be repeated,
# because sharedscripts work per entry, and each slave needs its own
# olddir
# Here we trust that there will be something to be rotated with error
# or access log, and that this will trigger postrotate script.
post = ${frontend-caddy-lazy-graceful:rendered} &
#################
# Trafficserver
#################
[trafficserver-directory]
recipe = slapos.cookbook:mkdirectory
configuration = ${directory:etc}/trafficserver
local-state = ${directory:var}/trafficserver
bin_path = {{ parameter_dict['trafficserver'] }}/bin
log = ${directory:log}/trafficserver
cache-path = ${directory:srv}/ats_cache
logrotate-backup = ${logrotate-directory:logrotate-backup}/trafficserver
[trafficserver-variable]
wrapper-path = ${directory:service}/trafficserver
reload-path = ${directory:etc-run}/trafficserver-reload
local-ip = {{ instance_parameter['ipv4-random'] }}
input-port = 23432
hostname = ${configuration:frontend-name}
plugin-config =
ip-allow-config = src_ip=0.0.0.0-255.255.255.255 action=ip_allow
cache-path = ${trafficserver-directory:cache-path}
disk-cache-size = ${configuration:disk-cache-size}
synthetic-port = ${configuration:trafficserver-synthetic-port}
mgmt-port = ${configuration:trafficserver-mgmt-port}
ram-cache-size = ${configuration:ram-cache-size}
templates-dir = {{ parameter_dict['trafficserver'] }}/etc/trafficserver/body_factory
request-timeout = ${configuration:request-timeout}
[trafficserver-configuration-directory]
recipe = plone.recipe.command
command = cp -rn {{ parameter_dict['trafficserver'] }}/etc/trafficserver/* ${:target}
target = ${trafficserver-directory:configuration}
[trafficserver-launcher]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['trafficserver'] }}/bin/traffic_cop
wrapper-path = ${trafficserver-variable:wrapper-path}
environment = TS_ROOT=${buildout:directory}
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
[trafficserver-reload]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['trafficserver'] }}/bin/traffic_ctl config reload
wrapper-path = ${trafficserver-variable:reload-path}
environment = TS_ROOT=${buildout:directory}
# XXX Dedicated Jinja Section without slapparameter
[trafficserver-jinja2-template-base]
recipe = slapos.recipe.template:jinja2
rendered = ${trafficserver-directory:configuration}/${:filename}
extra-context =
mode = 600
context =
section ats_directory trafficserver-directory
section ats_configuration trafficserver-variable
${:extra-context}
[trafficserver-records-config]
< = trafficserver-jinja2-template-base
template = {{ parameter_dict['template_trafficserver_records_config'] }}
filename = records.config
extra-context =
import os_module os
[trafficserver-storage-config]
< = trafficserver-jinja2-template-base
template = {{ parameter_dict['template_trafficserver_storage_config'] }}
filename = storage.config
[trafficserver-logging-config]
< = trafficserver-jinja2-template-base
template = {{ parameter_dict['template_trafficserver_logging_config'] }}
filename = logging.config
[trafficserver-remap-config]
<= trafficserver-jinja2-template-base
{%- raw %}
template = inline:
map /HTTPS/ http://{{ ipv4 }}:{{ https_port }}
map / http://{{ ipv4 }}:{{ http_port }}
{%- endraw %}
extra-context =
raw ipv4 {{ instance_parameter['ipv4-random'] }}
key https_port backend-haproxy-configuration:https-port
key http_port backend-haproxy-configuration:http-port
filename = remap.config
[trafficserver-plugin-config]
< = trafficserver-jinja2-template-base
template = {{ parameter_dict['template_empty'] }}
filename = plugin.config
context =
key content trafficserver-variable:plugin-config
[trafficserver-ip-allow-config]
< = trafficserver-jinja2-template-base
template = {{ parameter_dict['template_empty'] }}
filename = ip_allow.config
context =
key content trafficserver-variable:ip-allow-config
[trafficserver-promise-listen-port]
<= monitor-promise-base
module = check_port_listening
name = trafficserver-port-listening.py
config-hostname = ${trafficserver-variable:local-ip}
config-port = ${trafficserver-variable:input-port}
[trafficserver-ctl]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['trafficserver'] }}/bin/traffic_ctl
wrapper-path = ${directory:bin}/traffic_ctl
environment = TS_ROOT=${buildout:directory}
[trafficserver-promise-cache-availability]
<= monitor-promise-base
module = trafficserver_cache_availability
name = trafficserver-cache-availability.py
config-wrapper-path = ${trafficserver-ctl:wrapper-path}
[trafficserver-rotate-script]
< = jinja2-template-base
template = {{ parameter_dict['template_rotate_script'] }}
rendered = ${directory:bin}/trafficserver-rotate
mode = 0700
xz_binary = {{ parameter_dict['xz_location'] ~ '/bin/xz' }}
pattern = *.old
# days to keep log files
keep_days = 365
extra-context =
key log_dir trafficserver-directory:log
key rotate_dir trafficserver-directory:logrotate-backup
key xz_binary :xz_binary
key keep_days :keep_days
key pattern :pattern
[cron-entry-logrotate-trafficserver]
recipe = slapos.cookbook:cron.d
cron-entries = ${directory:etc}/cron.d
name = trafficserver-logrotate
frequency = 0 0 * * *
command = ${trafficserver-rotate-script:rendered}
### End of ATS sections
### Caddy Graceful and promises
[frontend-caddy-configuration-state]
< = jinja2-template-base
template = {{ parameter_dict['template_configuration_state_script'] }}
rendered = ${directory:bin}/${:_buildout_section_name_}
mode = 0700
path_list = ${caddy-configuration:frontend-configuration} ${frontend-configuration:log-access-configuration} ${caddy-directory:slave-configuration}/*.conf ${caddy-directory:master-autocert-dir}/*.key ${caddy-directory:master-autocert-dir}/*.crt ${caddy-directory:master-autocert-dir}/*.pem ${caddy-directory:autocert}/*.pem ${caddy-directory:custom-ssl-directory}/*.proxy_ca_crt ${directory:bbb-ssl-dir}/*.crt
sha256sum = {{ parameter_dict['sha256sum'] }}
extra-context =
key path_list :path_list
key sha256sum :sha256sum
key signature_file :signature_file
[frontend-caddy-configuration-state-graceful]
< = frontend-caddy-configuration-state
signature_file = ${directory:run}/graceful_configuration_state_signature
[frontend-caddy-configuration-state-validate]
< = frontend-caddy-configuration-state
signature_file = ${directory:run}/validate_configuration_state_signature
[frontend-caddy-graceful]
< = jinja2-template-base
template = {{ parameter_dict['template_graceful_script'] }}
rendered = ${directory:etc-run}/frontend-caddy-safe-graceful
mode = 0700
extra-context =
key graceful_reload_command caddy-configuration:frontend-graceful-command
key caddy_configuration_state frontend-caddy-configuration-state-graceful:rendered
[frontend-caddy-validate]
< = jinja2-template-base
template = {{ parameter_dict['template_validate_script'] }}
rendered = ${directory:bin}/frontend-caddy-validate
mode = 0700
last_state_file = ${directory:run}/caddy_configuration_last_state
validate_command = ${caddy-wrapper:rendered} -validate
extra-context =
key validate_command :validate_command
key configuration_state_command frontend-caddy-configuration-state-validate:rendered
key last_state_file :last_state_file
[frontend-caddy-lazy-graceful]
< = jinja2-template-base
template = {{ parameter_dict['template_caddy_lazy_script_call'] }}
rendered = ${directory:bin}/frontend-caddy-lazy-graceful
mode = 0700
pid-file = ${directory:run}/lazy-graceful.pid
wait_time = 60
extra-context =
key pid_file :pid-file
key wait_time :wait_time
key lazy_command caddy-configuration:frontend-graceful-command
# Promises checking configuration:
[promise-helper-last-configuration-state]
< = jinja2-template-base
template = {{ parameter_dict['template_empty'] }}
rendered = ${directory:bin}/frontend-read-last-configuration-state
mode = 0700
content =
#!/bin/sh
exit `cat ${frontend-caddy-validate:last_state_file}`
context =
key content :content
[promise-frontend-caddy-configuration]
<= monitor-promise-base
module = validate_frontend_configuration
name = frontend-caddy-configuration-promise.py
config-verification-script = ${promise-helper-last-configuration-state:rendered}
[promise-caddy-frontend-v4-https]
<= monitor-promise-base
module = check_port_listening
name = caddy_frontend_ipv4_https.py
config-hostname = {{ instance_parameter['ipv4-random'] }}
config-port = ${configuration:port}
[promise-caddy-frontend-v4-http]
<= monitor-promise-base
module = check_port_listening
name = caddy_frontend_ipv4_http.py
config-hostname = {{ instance_parameter['ipv4-random'] }}
config-port = ${configuration:plain_http_port}
[promise-caddy-frontend-v6-https]
<= monitor-promise-base
module = check_port_listening
name = caddy_frontend_ipv6_https.py
config-hostname = {{ instance_parameter['ipv6-random'] }}
config-port = ${configuration:port}
[promise-caddy-frontend-v6-http]
<= monitor-promise-base
module = check_port_listening
name = caddy_frontend_ipv6_http.py
config-hostname = {{ instance_parameter['ipv6-random'] }}
config-port = ${configuration:plain_http_port}
[promise-backend-haproxy-http]
<= monitor-promise-base
module = check_port_listening
name = backend_haproxy_http.py
config-hostname = {{ instance_parameter['ipv4-random'] }}
config-port = ${backend-haproxy-configuration:http-port}
[promise-backend-haproxy-https]
<= monitor-promise-base
module = check_port_listening
name = backend_haproxy_https.py
config-hostname = {{ instance_parameter['ipv4-random'] }}
config-port = ${backend-haproxy-configuration:https-port}
[backend-haproxy-configuration]
file = ${directory:etc}/backend-haproxy.cfg
pid-file = ${directory:run}/backend-haproxy.pid
log-socket = ${backend-haproxy-rsyslogd-config:log-socket}
graceful-command = ${backend-haproxy-validate:rendered} && kill -USR2 $(cat ${:pid-file})
http-port = ${configuration:backend-haproxy-http-port}
https-port = ${configuration:backend-haproxy-https-port}
# Caucase related configuration
caucase-url = {{ slapparameter_dict['backend-client-caucase-url'] }}
ca-certificate = ${backend-client-login-config:ca-certificate}
certificate = ${backend-client-login-config:certificate}
cas-ca-certificate = ${backend-client-login-config:cas-ca-certificate}
csr = ${backend-client-caucase-updater-csr:csr}
crl = ${backend-client-login-config:crl}
[backend-haproxy]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['haproxy_executable'] }} -f ${backend-haproxy-configuration:file}
wrapper-path = ${directory:service}/backend-haproxy
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
[backend-haproxy-rsyslogd-lazy-graceful]
< = jinja2-template-base
template = {{ parameter_dict['template_caddy_lazy_script_call'] }}
rendered = ${directory:bin}/backend-haproxy-rsyslogd-lazy-graceful
mode = 0700
pid-file = ${directory:run}/backend-haproxy-rsyslogd-lazy-graceful.pid
wait_time = 60
extra-context =
key pid_file :pid-file
key wait_time :wait_time
key lazy_command backend-haproxy-rsyslogd-config:graceful-command
[logrotate-entry-backend-haproxy]
<= logrotate-entry-base
name = backend-haproxy
log = ${backend-haproxy-rsyslogd-config:log-file}
rotate-num = ${configuration:rotate-num}
# Note: Slaves do not define their own reload, as this would be repeated,
# because sharedscripts work per entry, and each slave needs its own
# olddir
# Here we trust that there will be something to be rotated with error
# or access log, and that this will trigger postrotate script.
post = ${backend-haproxy-rsyslogd-lazy-graceful:rendered} &
[backend-haproxy-configuration-state]
<= jinja2-template-base
template = {{ parameter_dict['template_configuration_state_script'] }}
rendered = ${directory:bin}/${:_buildout_section_name_}
mode = 0700
path_list = ${backend-haproxy-configuration:file} ${backend-client-login-config:certificate}
sha256sum = {{ parameter_dict['sha256sum'] }}
extra-context =
key path_list :path_list
key sha256sum :sha256sum
key signature_file :signature_file
[backend-haproxy-configuration-state-graceful]
<= backend-haproxy-configuration-state
signature_file = ${directory:run}/backend_haproxy_graceful_configuration_state_signature
[backend-haproxy-configuration-state-validate]
<= backend-haproxy-configuration-state
signature_file = ${directory:run}/backend_haproxy_validate_configuration_state_signature
[backend-haproxy-graceful]
< = jinja2-template-base
template = {{ parameter_dict['template_graceful_script'] }}
rendered = ${directory:etc-run}/backend-haproxy-safe-graceful
mode = 0700
extra-context =
key graceful_reload_command backend-haproxy-configuration:graceful-command
key caddy_configuration_state backend-haproxy-configuration-state-graceful:rendered
[backend-haproxy-validate]
<= jinja2-template-base
template = {{ parameter_dict['template_validate_script'] }}
rendered = ${directory:bin}/backend-haproxy-validate
mode = 0700
last_state_file = ${directory:run}/backend_haproxy_configuration_last_state
validate_command = {{ parameter_dict['haproxy_executable'] }} -f ${backend-haproxy-configuration:file} -c
extra-context =
key validate_command :validate_command
key configuration_state_command backend-haproxy-configuration-state-validate:rendered
key last_state_file :last_state_file
[promise-backend-haproxy-configuration]
<= monitor-promise-base
module = validate_frontend_configuration
name = backend-haproxy-configuration.py
config-verification-script = ${promise-backend-haproxy-configuration-helper:rendered}
[promise-backend-haproxy-configuration-helper]
< = jinja2-template-base
template = {{ parameter_dict['template_empty'] }}
rendered = ${directory:bin}/backend-haproxy-read-last-configuration-state
mode = 0700
content =
#!/bin/sh
exit `cat ${backend-haproxy-validate:last_state_file}`
context =
key content :content
[backend-haproxy-rsyslogd-config]
log-socket = ${directory:run}/bhlog.sck
log-file = ${directory:log}/backend-haproxy.log
pid-file = ${directory:run}/backend-haproxy-rsyslogd.pid
spool-directory = ${directory:backend-haproxy-rsyslogd-spool}
graceful-command = kill -HUP $(cat ${:pid-file})
caddy-log-directory = ${caddy-directory:slave-log}
[backend-haproxy-rsyslogd-configuration]
<= jinja2-template-base
template = ${software-release-path:template-backend-haproxy-rsyslogd-conf}
rendered = ${directory:etc}/backend-haproxy-rsyslogd.conf
extra-context =
section configuration backend-haproxy-rsyslogd-config
[backend-haproxy-rsyslogd]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['rsyslogd_executable'] }} -i ${backend-haproxy-rsyslogd-config:pid-file} -n -f ${backend-haproxy-rsyslogd-configuration:rendered}
wrapper-path = ${directory:service}/backend-haproxy-rsyslogd
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
#######
# Monitoring sections
#
[monitor-instance-parameter]
# Note: Workaround for monitor stack, which uses monitor-httpd-port parameter
# directly, and in our case it can come from the network, thus resulting
# with need to strip !py!'u'
monitor-httpd-port = {{ instance_parameter['configuration.monitor-httpd-port'] | int }}
password = {{ instance_parameter['configuration.monitor-password'] | string }}
[monitor-conf-parameters]
private-path-list +=
${logrotate-directory:logrotate-backup}
[monitor-traffic-summary-last-stats-wrapper]
< = jinja2-template-base
template = {{ parameter_dict['template_wrapper'] }}
rendered = ${directory:bin}/traffic-summary-last-stats_every_1_hour
mode = 0700
command = export TS_ROOT=${buildout:directory} && echo "$({{ parameter_dict['trafficserver'] }}/bin/traffic_logstats -f ${trafficserver-directory:log}/squid.blog)
"
extra-context =
key content monitor-traffic-summary-last-stats-wrapper:command
# Produce ATS Cache stats
[monitor-ats-cache-stats-wrapper]
< = jinja2-template-base
template = {{ parameter_dict['template_wrapper'] }}
rendered = ${directory:bin}/ats-cache-stats_every_1_hour
mode = 0700
command = export TS_ROOT=${buildout:directory} && echo "$({{ parameter_dict['trafficserver'] }}/bin/traffic_shell ${monitor-ats-cache-stats-config:rendered})
"
extra-context =
key content monitor-ats-cache-stats-wrapper:command
[monitor-caddy-server-status-wrapper]
< = jinja2-template-base
template = {{ parameter_dict['template_wrapper'] }}
rendered = ${directory:bin}/monitor-caddy-server-status-wrapper
mode = 0700
command = {{ parameter_dict['curl'] }}/bin/curl -s http://{{ instance_parameter['ipv4-random'] }}:${configuration:plain_http_port}/server-status -u ${monitor-instance-parameter:username}:${monitor-htpasswd:passwd} 2>&1
extra-context =
key content monitor-caddy-server-status-wrapper:command
[monitor-ats-cache-stats-config]
< = jinja2-template-base
template = {{ parameter_dict['template_empty'] }}
rendered = ${trafficserver-configuration-directory:target}/cache-config.stats
mode = 644
context =
raw content show:cache-stats
[monitor-verify-re6st-connectivity]
<= monitor-promise-base
module = check_url_available
name = re6st-connectivity.py
config-url = ${configuration:re6st-verification-url}
[port-redirection]
<= jinja2-template-base
template = inline:
[{"srcPort": 80, "destPort": {{ '{{' }} http_port {{ '}}' }}}, {"srcPort": 443, "destPort": {{ '{{' }} https_port {{ '}}' }}}]
rendered = ${buildout:directory}/.slapos-port-redirect
mode = 0644
extra-context =
key http_port configuration:plain_http_port
key https_port configuration:port
[configuration]
{%- for key, value in instance_parameter.iteritems() -%}
{%- if key.startswith('configuration.') %}
{{ key.replace('configuration.', '') }} = {{ dumps(value) }}
{%- endif -%}
{%- endfor -%}
{%- endif -%} {# if slap_software_type == software_type #}
instance-apache-replicate.cfg.in 0000664 0000000 0000000 00000076674 13723117434 0037525 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend {% if slap_software_type in software_type %}
{% set aibcc_enabled = True %}
{% import "caucase" as caucase with context %}
{#- SERVER_POLLUTED_KEY_LIST is a list of keys which comes from various SlapOS Master implementations, which mix request and publish keys on each slave information -#}
{%- set SERVER_POLLUTED_KEY_LIST = ['connection-parameter-hash', 'timestamp', 'slave_title', 'slap_software_type'] -%}
{%- set TRUE_VALUES = ['y', 'yes', '1', 'true'] -%}
{%- set GOOD_CIPHER_LIST = ['ECDHE-ECDSA-AES256-GCM-SHA384', 'ECDHE-RSA-AES256-GCM-SHA384', 'ECDHE-ECDSA-AES128-GCM-SHA256', 'ECDHE-RSA-AES128-GCM-SHA256', 'ECDHE-ECDSA-WITH-CHACHA20-POLY1305', 'ECDHE-RSA-WITH-CHACHA20-POLY1305', 'ECDHE-RSA-AES256-CBC-SHA', 'ECDHE-RSA-AES128-CBC-SHA', 'ECDHE-ECDSA-AES256-CBC-SHA', 'ECDHE-ECDSA-AES128-CBC-SHA', 'RSA-AES256-CBC-SHA', 'RSA-AES128-CBC-SHA', 'ECDHE-RSA-3DES-EDE-CBC-SHA', 'RSA-3DES-EDE-CBC-SHA'] %}
{% set aikc_enabled = slapparameter_dict.get('automatic-internal-kedifa-caucase-csr', 'true').lower() in TRUE_VALUES %}
{% set aibcc_enabled = slapparameter_dict.get('automatic-internal-backend-client-caucase-csr', 'true').lower() in TRUE_VALUES %}
{# Ports 8401, 8402 and 8410+1..N are reserved for monitor ports on various partitions #}
{% set master_partition_monitor_monitor_httpd_port = 8401 %}
{% set kedifa_partition_monitor_httpd_port = 8402 %}
{% set frontend_monitor_httpd_base_port = 8410 %}
{% set caucase_host = '[' ~ instance_parameter['ipv6-random'] ~ ']' %}
{% set caucase_netloc = caucase_host ~ ':' ~ instance_parameter['configuration.caucase_backend_client_port'] %}
{% set caucase_url = 'http://' ~ caucase_netloc %}
[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
rendered = ${buildout:directory}/${:filename}
extra-context =
context =
import json_module json
raw common_profile {{ common_profile }}
${:extra-context}
{% set popen = functools_module.partial(subprocess_module.Popen, stdout=subprocess_module.PIPE, stderr=subprocess_module.STDOUT, stdin=subprocess_module.PIPE) %}
{% set part_list = [] %}
{% set single_type_key = 'single-' %}
{% if slap_software_type == "replicate" %}
{% set frontend_type = slapparameter_dict.pop('-frontend-type', 'single-default') %}
{% elif slap_software_type in ['default', 'RootSoftwareInstance'] %}
{% set frontend_type = "%s%s" % (single_type_key, 'custom-personal') %}
{% else %}
{% set frontend_type = "%s%s" % (single_type_key, slap_software_type) %}
{% endif %}
{% set frontend_quantity = slapparameter_dict.pop('-frontend-quantity', '1') | int %}
{% set slave_list_name = 'extra_slave_instance_list' %}
{% set frontend_list = [] %}
{% set frontend_section_list = [] %}
{% set request_dict = {} %}
{% set namebase = 'caddy-frontend' %}
# XXX Dirty hack, not possible to define default value before
{% set sla_computer_caddy_1_key = '-sla-1-computer_guid' %}
{% if not sla_computer_caddy_1_key in slapparameter_dict %}
{% do slapparameter_dict.__setitem__(sla_computer_caddy_1_key, '${slap-connection:computer-id}') %}
{% endif %}
{% set sla_computer_kedifa_key = '-sla-kedifa-computer_guid' %}
{% if not sla_computer_kedifa_key in slapparameter_dict %}
{% do slapparameter_dict.__setitem__(sla_computer_kedifa_key, '${slap-connection:computer-id}') %}
{% endif %}
# Here we request individually each frontend.
# The presence of sla parameters is checked and added if found
{% for i in range(1, frontend_quantity + 1) %}
{% set frontend_name = "%s-%s" % (namebase, i) %}
{% set request_section_title = 'request-%s' % frontend_name %}
{% set sla_key = "-sla-%s-" % i %}
{% set sla_key_length = sla_key | length %}
{% set sla_dict = {} %}
{% set config_key = "-frontend-config-%s-" % i %}
{% set config_key_length = config_key | length %}
{% set config_dict = {} %}
{% for key in slapparameter_dict.keys() %}
{% if key.startswith(sla_key) %}
{% do sla_dict.__setitem__(key[sla_key_length:], slapparameter_dict.pop(key)) %}
# We check for specific configuration regarding the frontend
{% elif key.startswith(config_key) %}
{% do config_dict.__setitem__(key[config_key_length:], slapparameter_dict.pop(key)) %}
{% endif %}
{% endfor %}
{% do config_dict.__setitem__('monitor-httpd-port', frontend_monitor_httpd_base_port + i) %}
{% do config_dict.__setitem__('backend-client-caucase-url', caucase_url) %}
{% do frontend_list.append(frontend_name) %}
{% do frontend_section_list.append(request_section_title) %}
{% do part_list.append(request_section_title) %}
# Filling request dict for slave
{% set state_key = "-frontend-%s-state" % i %}
{% do request_dict.__setitem__(request_section_title,
{
'config': config_dict,
'name': frontend_name,
'sla': sla_dict,
'state': slapparameter_dict.pop(state_key, None)
}) %}
{% endfor %}
{% set authorized_slave_string_list = [] %}
{% set authorized_slave_list = [] %}
{% set rejected_slave_dict = {} %}
{% set rejected_slave_title_dict = {} %}
{% set warning_slave_dict = {} %}
{% set used_host_list = [] %}
{% for slave in sorted(slave_instance_list) %}
{% set slave_error_list = [] %}
{% set slave_warning_list = [] %}
{% set slave_server_alias_unclashed = [] %}
{% set slave_type = slave.get('type') %}
{% if slave_type == 'eventsource' %}
{% do slave_error_list.append('type:eventsource is not implemented') %}
{% elif slave_type not in [None, '', 'default', 'zope', 'redirect', 'notebook', 'websocket'] %}
{% do slave_error_list.append('type:%s is not supported' % (slave_type,)) %}
{% endif %}
{# Check ciphers #}
{% set slave_cipher_list = slave.get('ciphers', '').strip().split() %}
{% if slave_cipher_list %}
{% for cipher in slave_cipher_list %}
{% if cipher not in GOOD_CIPHER_LIST %}
{% do slave_error_list.append('Cipher %r is not supported.' % (cipher,)) %}
{% endif %}
{% endfor %}
{% endif %}
{% set custom_domain = slave.get('custom_domain') %}
{% if custom_domain and custom_domain in used_host_list %}
{% do slave_error_list.append('custom_domain %r clashes' % (custom_domain,)) %}
{% else %}
{% do used_host_list.append(custom_domain) %}
{% endif %}
{% if slave.get('server-alias') %}
{% for slave_alias in ('' ~ slave['server-alias']).split() %}
{% if slave_alias.startswith('*.') %}
{% set clean_slave_alias = slave_alias[2:] %}
{% else %}
{% set clean_slave_alias = slave_alias %}
{% endif %}
{% if not validators.domain(clean_slave_alias) %}
{% do slave_error_list.append('server-alias \'%s\' not valid' % (slave_alias,)) %}
{% else %}
{% if slave_alias in slave_server_alias_unclashed or slave_alias == custom_domain %}
{# optionally do something about reporting back that server-alias has been unclashed #}
{% elif slave_alias in used_host_list %}
{% do slave_error_list.append('server-alias \'%s\' clashes' % (slave_alias,)) %}
{% else %}
{% do slave_server_alias_unclashed.append(slave_alias) %}
{% do used_host_list.append(slave_alias) %}
{% endif %}
{% endif %}
{% endfor %}
{% do slave.__setitem__('server-alias', ' '.join(slave_server_alias_unclashed)) %}
{% endif %}
{% for url_key in ['url', 'https-url'] %}
{% if url_key in slave %}
{% set url = (slave[url_key] or '').strip() %}
{% if subprocess_module.call([caddy_backend_url_validator, url]) == 1 or not validators.url(url) %}
{% do slave_error_list.append('slave %s %r invalid' % (url_key, url)) %}
{% elif url != slave[url_key] %}
{% do slave_warning_list.append('slave %s %r has been converted to %r' % (url_key, slave[url_key], url)) %}
{% endif %}
{% endif %}
{% endfor %}
{% if 'ssl_proxy_ca_crt' in slave %}
{% set ssl_proxy_ca_crt = slave.get('ssl_proxy_ca_crt', '') %}
{% set check_popen = popen([parameter_dict['openssl'], 'x509', '-noout']) %}
{% do check_popen.communicate(ssl_proxy_ca_crt) %}
{% if check_popen.returncode != 0 %}
{% do slave_error_list.append('ssl_proxy_ca_crt is invalid') %}
{% endif %}
{% endif %}
{# BBB: SlapOS Master non-zero knowledge BEGIN #}
{% for key in ['ssl_key', 'ssl_crt', 'ssl_ca_crt'] %}
{% if key in slave %}
{% do slave_warning_list.append('%s is obsolete, please use key-upload-url' % (key,)) %}
{% endif %}
{% endfor %}
{% if slave.get('ssl_ca_crt') and not (slave.get('ssl_crt') and slave.get('ssl_key')) %}
{% do slave_error_list.append('ssl_ca_crt is present, so ssl_crt and ssl_key are required') %}
{% endif %}
{% if slave.get('ssl_key') and slave.get('ssl_crt') %}
{% set key_popen = popen([parameter_dict['openssl'], 'rsa', '-noout', '-modulus']) %}
{% set crt_popen = popen([parameter_dict['openssl'], 'x509', '-noout', '-modulus']) %}
{% set key_modulus = key_popen.communicate(slave['ssl_key'])[0] | trim %}
{% set crt_modulus = crt_popen.communicate(slave['ssl_crt'])[0] | trim %}
{% if not key_modulus or key_modulus != crt_modulus %}
{% do slave_error_list.append('slave ssl_key and ssl_crt does not match') %}
{% endif %}
{% endif %}
{# BBB: SlapOS Master non-zero knowledge END #}
{% if slave.get('custom_domain') %}
{% set slave_custom_domain = '' ~ slave['custom_domain'] %}
{% if slave_custom_domain.startswith('*.') %}
{% set clean_custom_domain = slave_custom_domain[2:] %}
{% else %}
{% set clean_custom_domain = slave_custom_domain %}
{% endif %}
{% if not validators.domain(clean_custom_domain) %}
{% do slave_error_list.append('custom_domain %r invalid' % (slave['custom_domain'],)) %}
{% endif %}
{% endif %}
{% if len(slave_error_list) == 0 %}
{# Cleanup slave from not needed keys which come from implementation of SlapOS Master #}
{% set authorized_slave = slave.copy() %}
{% for key in SERVER_POLLUTED_KEY_LIST %}
{% do authorized_slave.pop(key, None) %}
{% endfor %}
{% do authorized_slave_list.append(authorized_slave) %}
{% else %}
{% do rejected_slave_dict.__setitem__(slave.get('slave_reference'), slave_error_list) %}
{% do rejected_slave_title_dict.__setitem__(slave.get('slave_title'), slave_error_list) %}
{% endif %}
{% if len(slave_warning_list) > 0 %}
{% do warning_slave_dict.__setitem__(slave.get('slave_reference'), slave_warning_list) %}
{% endif %}
{% endfor %}
{% do authorized_slave_list.sort() %}
[monitor-instance-parameter]
monitor-httpd-port = {{ master_partition_monitor_monitor_httpd_port }}
[replicate]
<= slap-connection
recipe = slapos.cookbook:requestoptional.serialised
config-monitor-cors-domains = {{ slapparameter_dict.get('monitor-cors-domains', 'monitor.app.officejs.com') }}
config-monitor-username = ${monitor-instance-parameter:username}
config-monitor-password = ${monitor-htpasswd:passwd}
{% set frontend_software_url_key = "-frontend-software-release-url" %}
{% if slapparameter_dict.has_key(frontend_software_url_key) %}
software-url = {{ slapparameter_dict.pop(frontend_software_url_key) }}
{% else %}
software-url = ${slap-connection:software-release-url}
{% endif %}
software-type = {{frontend_type}}
return = private-ipv4 public-ipv4 slave-instance-information-list monitor-base-url backend-client-csr_id-url csr_id-url csr_id-certificate
{% for section, frontend_request in request_dict.iteritems() %}
{% set state = frontend_request.get('state', '') %}
[{{section}}]
<= replicate
name = {{ frontend_request.get('name') }}
{% if state %}
state = {{ state }}
{% endif %}
config-slave-kedifa-information = ${request-kedifa:connection-slave-kedifa-information}
config-kedifa-caucase-url = ${request-kedifa:connection-caucase-url}
config-backend-client-caucase-url = {{ caucase_url }}
config-master-key-download-url = ${request-kedifa:connection-master-key-download-url}
config-cluster-identification = {{ cluster_identification }}
{# Do not send additional parameters for destroyed nodes #}
{% if state != 'destroyed' %}
{% set slave_configuration_dict = slapparameter_dict %}
{% do slave_configuration_dict.update(frontend_request.get('config')) %}
{# sort_keys are important in order to avoid shuffling parameters on each run #}
{% do slave_configuration_dict.__setitem__(slave_list_name, json_module.dumps(authorized_slave_list, sort_keys=True)) %}
{% do slave_configuration_dict.__setitem__("frontend-name", frontend_request.get('name')) %}
{%- for config_key, config_value in slave_configuration_dict.iteritems() %}
config-{{ config_key }} = {{ dumps(config_value) }}
{% endfor -%}
{% endif %}
{% if frontend_request.get('sla') %}
{% for parameter, value in frontend_request.get('sla').iteritems() %}
sla-{{ parameter }} = {{ value }}
{% endfor %}
{% endif %}
{% endfor %}
{% set warning_list = [] %}
{% for key in ['apache-certificate', 'apache-key'] %}
{% if key in slapparameter_dict %}
{% do warning_list.append('%s is obsolete, please use master-key-upload-url' % (key, )) %}
{% endif %}
{% endfor %}
[publish-information]
<= monitor-publish
recipe = slapos.cookbook:publish
domain = {{ slapparameter_dict.get('domain') }}
slave-amount = {{ slave_instance_list | length }}
accepted-slave-amount = {{ authorized_slave_list | length }}
rejected-slave-amount = {{ rejected_slave_dict | length }}
backend-client-caucase-url = {{ caucase_url }}
{# sort_keys are important in order to avoid shuffling parameters on each run #}
rejected-slave-dict = {{ dumps(json_module.dumps(rejected_slave_title_dict, sort_keys=True)) }}
rejected-slave-promise-url = ${rejected-slave-promise:config-url}
master-key-upload-url = ${request-kedifa:connection-master-key-upload-url}
master-key-generate-auth-url = ${request-kedifa:connection-master-key-generate-auth-url}
kedifa-caucase-url = ${request-kedifa:connection-caucase-url}
{% if len(warning_list) > 0 %}
{# sort_keys are important in order to avoid shuffling parameters on each run #}
warning-list = {{ dumps(json_module.dumps(warning_list, sort_keys=True)) }}
{% endif %}
{% if len(warning_slave_dict) > 0 %}
{# sort_keys are important in order to avoid shuffling parameters on each run #}
warning-slave-dict = {{ dumps(json_module.dumps(warning_slave_dict, sort_keys=True)) }}
{% endif %}
{% if not aikc_enabled or not aibcc_enabled %}
{% for frontend in frontend_list %}
{% set section_part = '${request-' + frontend %}
{{ frontend }}-csr_id-certificate = {{ section_part }}:connection-csr_id-certificate}
{% endfor %}
{% endif %}
{% if not aikc_enabled %}
kedifa-csr_id-url = ${request-kedifa:connection-csr_id-url}
kedifa-csr_id-certificate = ${request-kedifa:connection-csr_id-certificate}
{% for frontend in frontend_list %}
{% set section_part = '${request-' + frontend %}
{{ frontend }}-csr_id-url = {{ section_part }}:connection-csr_id-url}
{% endfor %}
{% endif %}
{% if not aibcc_enabled %}
{% for frontend in frontend_list %}
{% set section_part = '${request-' + frontend %}
{{ frontend }}-backend-client-csr_id-url = {{ section_part }}:connection-backend-client-csr_id-url}
{% endfor %}
{% endif %}
#----------------------------
#--
#-- Publish slave information
[publish-slave-information]
recipe = slapos.cookbook:softwaretype
default = ${dynamic-publish-slave-information:rendered}
RootSoftwareInstance = ${dynamic-publish-slave-information:rendered}
replicate = ${dynamic-publish-slave-information:rendered}
custom-personal = ${dynamic-publish-slave-information:rendered}
custom-group = ${dynamic-publish-slave-information:rendered}
[request-kedifa]
<= slap-connection
recipe = slapos.cookbook:requestoptional.serialised
config-monitor-cors-domains = {{ slapparameter_dict.get('monitor-cors-domains', 'monitor.app.officejs.com') }}
config-monitor-username = ${monitor-instance-parameter:username}
config-monitor-password = ${monitor-htpasswd:passwd}
config-monitor-httpd-port = {{ kedifa_partition_monitor_httpd_port }}
{% for key in ['kedifa_port', 'caucase_port'] -%}
{%- if key in slapparameter_dict %}
config-{{ key }} = {{ dumps(slapparameter_dict[key]) }}
{%- endif %}
{%- endfor %}
config-slave-list = {{ dumps(authorized_slave_list) }}
config-cluster-identification = {{ cluster_identification }}
{% set frontend_software_url_key = "-frontend-software-release-url" %}
{% if slapparameter_dict.has_key(frontend_software_url_key) %}
software-url = {{ slapparameter_dict.pop(frontend_software_url_key) }}
{% else %}
software-url = ${slap-connection:software-release-url}
{% endif %}
software-type = kedifa
name = kedifa
return = slave-kedifa-information master-key-generate-auth-url master-key-upload-url master-key-download-url caucase-url csr_id-url csr_id-certificate monitor-base-url
{% set sla_kedifa_key = "-sla-kedifa-" %}
{% set sla_kedifa_key_length = sla_kedifa_key | length %}
{% for key in slapparameter_dict.keys() %}
{% if key.startswith(sla_kedifa_key) %}
sla-{{ key[sla_kedifa_key_length:] }} = {{ slapparameter_dict.pop(key) }}
{% endif %}
{% endfor %}
[rejected-slave-information]
{% for slave_id, rejected_list in rejected_slave_dict.iteritems() %}
{# sort_keys are important in order to avoid shuffling parameters on each run #}
{{ slave_id }} = {{ dumps(json_module.dumps(rejected_list, sort_keys=True)) }}
{% endfor %}
[warning-slave-information]
{% for slave_id, warning_list in warning_slave_dict.iteritems() %}
{# sort_keys are important in order to avoid shuffling parameters on each run #}
{{ slave_id }} = {{ dumps(json_module.dumps(warning_list, sort_keys=True)) }}
{% endfor %}
[slave-information]
{% for frontend_section in frontend_section_list %}
{{ frontend_section }} = {{ "${%s:connection-slave-instance-information-list}" % frontend_section }}
{% endfor %}
[active-slave-instance]
{% set active_slave_instance_list = [] %}
{% for slave_instance in slave_instance_list %}
{# Provide a list of slave titles send by master, in order to filter out already destroyed slaves #}
{# Note: This functionality is not yet covered by tests, please modify with care #}
{% do active_slave_instance_list.append(slave_instance['slave_reference']) %}
{% endfor %}
{# sort_keys are important in order to avoid shuffling parameters on each run #}
active-slave-instance-list = {{ json_module.dumps(active_slave_instance_list, sort_keys=True) }}
[dynamic-publish-slave-information]
< = jinja2-template-base
template = {{ template_publish_slave_information }}
filename = dynamic-publish-slave-information.cfg
extensions = jinja2.ext.do
extra-context =
section slave_information slave-information
section rejected_slave_information rejected-slave-information
section active_slave_instance_dict active-slave-instance
section warning_slave_information warning-slave-information
key slave_kedifa_information request-kedifa:connection-slave-kedifa-information
[monitor-base-url-dict]
kedifa = ${request-kedifa:connection-monitor-base-url}
{% for frontend in frontend_section_list %}
{{ frontend }} = {{ '${' + frontend + ':connection-monitor-base-url}' }}
{% endfor %}
[directory]
recipe = slapos.cookbook:mkdirectory
bin = ${buildout:directory}/bin/
srv = ${buildout:directory}/srv/
backup = ${:srv}/backup
# CAUCASE directories
caucased = ${:srv}/caucased
backup-caucased = ${:backup}/caucased
{% if aikc_enabled %}
[directory]
aikc = ${:srv}/aikc
[aikc-config]
caucase-url = ${request-kedifa:connection-caucase-url}
csr = ${directory:aikc}/csr.pem
key = ${directory:aikc}/key.pem
ca-certificate = ${directory:aikc}/cas-ca-certificate.pem
crl = ${directory:aikc}/crl.pem
user-ca-certificate = ${directory:aikc}/user-ca-certificate.pem
user-crl = ${directory:aikc}/user-crl.pem
user-created = ${directory:aikc}/user-created
csr_id = ${directory:aikc}/csr_id
[aikc-user-csr]
recipe = plone.recipe.command
organization = {{ cluster_identification }}
organizational_unit = Automatic Internal Kedifa Caucase CSR
command =
if [ ! -f ${:csr} ] && [ ! -f ${:key} ] ; then
{{ parameter_dict['openssl'] }} req -new -sha256 \
-newkey rsa:2048 -nodes -keyout ${:key} \
-subj "/O=${:organization}/OU=${:organizational_unit}" \
-out ${:csr}
fi
update-command = ${:command}
csr = ${aikc-config:csr}
key = ${aikc-config:key}
stop-on-error = True
[aikc-caucase-wrapper]
{# jinja2 instead of wrapper is used with context to remove py'u' #}
recipe = slapos.recipe.template:jinja2
context =
key caucase_url aikc-config:caucase-url
template = inline:#!{{ parameter_dict['dash'] }}/bin/dash
exec {{ parameter_dict['bin_directory'] }}/caucase \
{# raw block to use context #}
{% raw %}
--ca-url {{ caucase_url }} \
{% endraw %}
--ca-crt ${aikc-config:ca-certificate} \
--user-ca-crt ${aikc-config:user-ca-certificate} \
--user-crl ${aikc-config:user-crl} \
--crl ${aikc-config:crl} \
"$@"
rendered = ${directory:bin}/aikc-caucase-wrapper
mode = 0700
{% do part_list.append('aikc-create-user') %}
[aikc-create-user]
recipe = plone.recipe.command
stop-on-error = True
update-command = ${:command}
command =
if ! [ -f ${aikc-config:user-created} ] ; then
${aikc-caucase-wrapper:rendered} --mode user --send-csr ${aikc-user-csr:csr} > ${aikc-config:csr_id} || exit 1
cut -d ' ' -f 1 ${aikc-config:csr_id} || exit 1
csr_id=`cut -d ' ' -f 1 ${aikc-config:csr_id}`
sleep 1
${aikc-caucase-wrapper:rendered} --mode user --get-crt $csr_id ${aikc-config:key} || exit 1
touch ${aikc-config:user-created}
fi
{% do part_list.append('aikc-user-caucase-updater') %}
{% do part_list.append('aikc-user-caucase-updater-promise') %}
{{ caucase.updater(
prefix='aikc-user-caucase-updater',
buildout_bin_directory=parameter_dict['bin_directory'],
updater_path='${directory:service}/aikc-user-caucase-updater',
url='${aikc-config:caucase-url}',
data_dir='${directory:srv}/caucase-updater',
crt_path='${aikc-config:key}',
ca_path='${aikc-config:user-ca-certificate}',
crl_path='${aikc-config:user-crl}',
key_path='${aikc-config:key}',
mode='user',
)}}
[aikc-check-certificate]
recipe = slapos.recipe.template:jinja2
rendered = ${directory:bin}/aikc-check-certificate
template = inline:
import sys
import ssl
import urlparse
certificate = sys.argv[2]
parsed = urlparse.urlparse(sys.argv[1])
got_certificate = ssl.get_server_certificate((parsed.hostname, parsed.port))
sys.exit(0) if certificate.strip() == got_certificate.strip() else sys.exit(1)
{% for csr in frontend_list + ['kedifa'] %}
[aikc-{{ csr }}-wrapper]
{# jinja2 instead of wrapper is used with context to remove py'u' #}
recipe = slapos.recipe.template:jinja2
context =
key csr_id_url request-{{ csr }}:connection-csr_id-url
key csr_id_certificate request-{{ csr }}:connection-csr_id-certificate
template = inline:#!{{ parameter_dict['dash'] }}/bin/dash
test -f ${directory:aikc}/{{ csr }}-done && exit 0
${buildout:executable} ${aikc-check-certificate:rendered} \
{# raw block to use context #}
{% raw %}
{{ csr_id_url }} \
"""{{ csr_id_certificate }}"""
{% endraw %}
if [ $? = 0 ]; then
csr_id=`{{ parameter_dict['curl'] }}/bin/curl -s -k -g \
{% raw %}
{{ csr_id_url }} \
{% endraw %}
` || exit 1
${aikc-caucase-wrapper:rendered} --user-key ${aikc-config:key} --sign-csr $csr_id && touch ${directory:aikc}/{{ csr }}-done
fi
rendered = ${directory:bin}/aikc-{{ csr }}-wrapper
mode = 0700
{% do part_list.append('aikc-%s' % (csr,)) %}
[aikc-{{ csr }}]
recipe = plone.recipe.command
stop-on-error = True
command =
${aikc-{{ csr }}-wrapper:rendered}
update-command = ${:command}
{% endfor %}
{% endif %} {# if aikc_enabled #}
{% if aibcc_enabled %}
[directory]
aibcc = ${:srv}/aibcc
[aibcc-config]
caucase-url = {{ caucase_url }}
csr = ${directory:aibcc}/csr.pem
key = ${directory:aibcc}/key.pem
ca-certificate = ${directory:aibcc}/cas-ca-certificate.pem
crl = ${directory:aibcc}/crl.pem
user-ca-certificate = ${directory:aibcc}/user-ca-certificate.pem
user-crl = ${directory:aibcc}/user-crl.pem
user-created = ${directory:aibcc}/user-created
csr_id = ${directory:aibcc}/csr_id
[aibcc-user-csr]
recipe = plone.recipe.command
organization = {{ cluster_identification }}
organizational_unit = Automatic Sign Backend Client Caucase CSR
command =
if [ ! -f ${:csr} ] && [ ! -f ${:key} ] ; then
{{ parameter_dict['openssl'] }} req -new -sha256 \
-newkey rsa:2048 -nodes -keyout ${:key} \
-subj "/O=${:organization}/OU=${:organizational_unit}" \
-out ${:csr}
fi
update-command = ${:command}
csr = ${aibcc-config:csr}
key = ${aibcc-config:key}
stop-on-error = True
[aibcc-caucase-wrapper]
{# jinja2 instead of wrapper is used with context to remove py'u' #}
recipe = slapos.recipe.template:jinja2
context =
key caucase_url aibcc-config:caucase-url
template = inline:#!{{ parameter_dict['dash'] }}/bin/dash
exec {{ parameter_dict['bin_directory'] }}/caucase \
{# raw block to use context #}
{% raw %}
--ca-url {{ caucase_url }} \
{% endraw %}
--ca-crt ${aibcc-config:ca-certificate} \
--user-ca-crt ${aibcc-config:user-ca-certificate} \
--user-crl ${aibcc-config:user-crl} \
--crl ${aibcc-config:crl} \
"$@"
rendered = ${directory:bin}/aibcc-caucase-wrapper
mode = 0700
{% do part_list.append('aibcc-create-user') %}
[aibcc-create-user]
recipe = plone.recipe.command
# the caucase for this part is provided in this profile, so we can't fail
# as otherwise caucase will never be started...
stop-on-error = False
update-command = ${:command}
command =
if ! [ -f ${aibcc-config:user-created} ] ; then
${aibcc-caucase-wrapper:rendered} --mode user --send-csr ${aibcc-user-csr:csr} > ${aibcc-config:csr_id} || exit 1
cut -d ' ' -f 1 ${aibcc-config:csr_id} || exit 1
csr_id=`cut -d ' ' -f 1 ${aibcc-config:csr_id}`
sleep 1
${aibcc-caucase-wrapper:rendered} --mode user --get-crt $csr_id ${aibcc-config:key} || exit 1
touch ${aibcc-config:user-created}
fi
{% do part_list.append('aibcc-user-caucase-updater') %}
{% do part_list.append('aibcc-user-caucase-updater-promise') %}
{{ caucase.updater(
prefix='aibcc-user-caucase-updater',
buildout_bin_directory=parameter_dict['bin_directory'],
updater_path='${directory:service}/aibcc-user-caucase-updater',
url='${aibcc-config:caucase-url}',
data_dir='${directory:srv}/caucase-updater',
crt_path='${aibcc-config:key}',
ca_path='${aibcc-config:user-ca-certificate}',
crl_path='${aibcc-config:user-crl}',
key_path='${aibcc-config:key}',
mode='user',
)}}
[aibcc-check-certificate]
recipe = slapos.recipe.template:jinja2
rendered = ${directory:bin}/aibcc-check-certificate
template = inline:
import sys
import ssl
import urlparse
certificate = sys.argv[2]
parsed = urlparse.urlparse(sys.argv[1])
got_certificate = ssl.get_server_certificate((parsed.hostname, parsed.port))
sys.exit(0) if certificate.strip() == got_certificate.strip() else sys.exit(1)
{% for csr in frontend_list %}
[aibcc-{{ csr }}-wrapper]
{# jinja2 instead of wrapper is used with context to remove py'u' #}
recipe = slapos.recipe.template:jinja2
context =
key csr_id_url request-{{ csr }}:connection-backend-client-csr_id-url
key csr_id_certificate request-{{ csr }}:connection-csr_id-certificate
template = inline:#!{{ parameter_dict['dash'] }}/bin/dash
test -f ${directory:aibcc}/{{ csr }}-done && exit 0
${buildout:executable} ${aibcc-check-certificate:rendered} \
{# raw block to use context #}
{% raw %}
{{ csr_id_url }} \
"""{{ csr_id_certificate }}"""
{% endraw %}
if [ $? = 0 ]; then
csr_id=`{{ parameter_dict['curl'] }}/bin/curl -s -k -g \
{% raw %}
{{ csr_id_url }} \
{% endraw %}
` || exit 1
${aibcc-caucase-wrapper:rendered} --user-key ${aibcc-config:key} --sign-csr $csr_id && touch ${directory:aibcc}/{{ csr }}-done
fi
rendered = ${directory:bin}/aibcc-{{ csr }}-wrapper
mode = 0700
{% do part_list.append('aibcc-%s' % (csr,)) %}
[aibcc-{{ csr }}]
recipe = plone.recipe.command
stop-on-error = True
command =
${aibcc-{{ csr }}-wrapper:rendered}
update-command = ${:command}
{% endfor %}
{% endif %} {# if aibcc_enabled #}
[rejected-slave-json]
recipe = slapos.recipe.template:jinja2
filename = rejected-slave.json
directory = ${directory:promise-output}
rendered = ${:directory}/${:filename}
template = {{ parameter_dict['template_empty'] }}
{% if rejected_slave_title_dict %}
{# sort_keys are important in order to avoid shuffling parameters on each run #}
content = {{ dumps(json_module.dumps(rejected_slave_title_dict, indent=2, sort_keys=True)) }}
{% else %}
content =
{% endif %}
context =
key content :content
[directory]
service = ${:etc}/service
promise-output = ${:srv}/promise-output
[rejected-slave-publish-configuration]
ip = {{ instance_parameter['ipv6-random'] }}
port = 14455
[rejected-slave-publish]
directory = ${rejected-slave-json:directory}
url = https://${rejected-slave-password:user}:${rejected-slave-password:passwd}@[${rejected-slave-publish-configuration:ip}]:${rejected-slave-publish-configuration:port}/${rejected-slave-json:filename}
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['caddy'] }}
-conf ${rejected-slave-template:rendered}
-log stderr
-http2=true
-disable-http-challenge
-disable-tls-alpn-challenge
-root ${:directory}
wrapper-path = ${directory:service}/rejected-slave-publish
hash-existing-files =
${buildout:directory}/software_release/buildout.cfg
hash-files =
${rejected-slave-template:rendered}
${rejected-slave-certificate:certificate}
[rejected-slave-certificate]
recipe = plone.recipe.command
certificate = ${directory:etc}/rejected-slave.pem
key = ${:certificate}
stop-on-error = True
update-command = ${:command}
command =
[ -f ${:certificate} ] && find ${:certificate} -type f -mtime +3 -delete
if ! [ -f ${:certificate} ] ; then
openssl req -new -newkey rsa:2048 -sha256 -subj \
"/CN=${rejected-slave-publish-configuration:ip}" \
-days 5 -nodes -x509 -keyout ${:certificate} -out ${:certificate}
fi
[rejected-slave-password]
recipe = slapos.cookbook:generate.password
storage-path = ${directory:etc}/.rejected-slave.passwd
bytes = 8
user = admin
[rejected-slave-template]
recipe = slapos.recipe.template:jinja2
template = inline:
https://:${rejected-slave-publish-configuration:port}/ {
basicauth / ${rejected-slave-password:user} ${rejected-slave-password:passwd}
tls ${rejected-slave-certificate:certificate} ${rejected-slave-certificate:key}
bind ${rejected-slave-publish-configuration:ip}
log stderr
errors stderr
}
rendered = ${directory:etc}/Caddyfile-rejected-slave
[promise-rejected-slave-publish-ip-port]
<= monitor-promise-base
module = check_port_listening
name = rejected-slave-publish-ip-port-listening.py
config-hostname = ${rejected-slave-publish-configuration:ip}
config-port = ${rejected-slave-publish-configuration:port}
[rejected-slave-promise]
<= monitor-promise-base
module = check_port_listening
module = check_file_state
name = rejected-slave.py
config-filename = ${rejected-slave-json:rendered}
config-state = empty
config-url = ${rejected-slave-publish:url}
[caucased-backend-client]
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
{{ caucase.caucased(
prefix='caucased-backend-client',
buildout_bin_directory=parameter_dict['bin_directory'],
caucased_path='${directory:service}/caucased-backend-client',
backup_dir='${directory:backup-caucased}',
data_dir='${directory:caucased}',
netloc=caucase_netloc,
service_auto_approve_count=0,
user_auto_approve_count=1,
key_len=2048,
)}}
[buildout]
extends =
{{ common_profile }}
{{ template_monitor }}
parts =
monitor-base
publish-slave-information
publish-information
request-kedifa
rejected-slave-promise
promise-rejected-slave-publish-ip-port
caucased-backend-client
caucased-backend-client-promise
{% for part in part_list %}
{{ ' %s' % part }}
{% endfor %}
# publish-information
{% endif %}
instance-caddy-input-schema.json 0000664 0000000 0000000 00000011501 13723117434 0037574 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend {
"$schema": "http://json-schema.org/draft-04/schema",
"properties": {
"-frontend-quantity": {
"description": "Quantity of Frontends Replicate.",
"title": "Frontend Replication Quantity",
"type": "integer"
},
"apache-certificate": {
"description": "SSL Certificate used by the server. By appending to it CA certificate it is possible to use this field to replace not implemented apache-ca-certificate. Deprecated, please use master-key-upload-url.",
"textarea": true,
"title": "[DEPRECATED] SSL Certificate, with optional CA certificate",
"type": "string"
},
"apache-key": {
"description": "SSL Key used by the server. Deprecated, please use master-key-upload-url.",
"textarea": true,
"title": "[DEPRECATED] SSL Key",
"type": "string"
},
"domain": {
"description": "Base Domain for create subdomains (ie.: example.com).",
"pattern": "^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}$",
"title": "Domain",
"type": "string"
},
"enable-http2-by-default": {
"default": "true",
"description": "Use HTTP2 as default Protocol",
"enum": [
"true",
"false"
],
"title": "Enable HTTP2 by Default",
"type": "string"
},
"global-disable-http2": {
"default": "false",
"description": "Disables globally HTTP2 in Caddy, thus enable-http2-by-default here and enable-http2 have no effect. Rational is that in some loaded environments it is better to run Caddy without any HTTP2 capabilities. Warning: Changing the parameter will result in restarting Caddy process.",
"enum": [
"true",
"false"
],
"title": "Globally disable HTTP2",
"type": "string"
},
"mpm-graceful-shutdown-timeout": {
"default": 5,
"description": "Value passed to -grace parameter of Caddy, see https://caddyserver.com/docs/cli .",
"title": "Duration of the graceful shutdown period. Warning: Changing the parameter will result in restarting Caddy process.",
"type": "integer"
},
"nginx-domain": {
"description": "Base Domain for create subdomains (ie.: example2.com) for websocket, notebook and eventsource.",
"pattern": "^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}$",
"title": "[NOT IMPLEMENTED] Nginx Domain",
"type": "string"
},
"public-ipv4": {
"description": "Public ipv4 of the frontend (the one Caddy will be indirectly listening to).",
"title": "Public IPv4",
"type": "string"
},
"re6st-verification-url": {
"description": "Url to verify if the internet and/or re6stnet is working.",
"title": "Test Verification URL",
"type": "string"
},
"backend-connect-timeout": {
"default": 5,
"description": "Time in seconds for establishing connection to the backend.",
"title": "Timeout for backend connection (seconds)",
"type": "integer"
},
"backend-connect-retries": {
"default": 3,
"description": "Amount of retries to connect to the backend. The amount of backend-connect-timeout*backend-connect-retries seconds will be spent to connect to the backend.",
"title": "Amount of retries to connect to the backend.",
"type": "integer"
},
"automatic-internal-kedifa-caucase-csr": {
"default": "true",
"description": "Automatically signs CSRs sent to KeDiFa's caucase, based on csr_id and matching certificate.",
"enum": [
"true",
"false"
],
"title": "Automatic Internal KeDiFa's Caucase CSR",
"type": "string"
},
"automatic-internal-backend-client-caucase-csr": {
"default": "true",
"description": "Automatically signs CSRs sent to Backend Client's caucase, based on csr_id and matching certificate.",
"enum": [
"true",
"false"
],
"title": "Automatic Internal Backend Client's Caucase CSR",
"type": "string"
},
"ciphers": {
"description": "List of ciphers. Empty defaults to Caddy list of ciphers. See https://caddyserver.com/docs/tls for more information.",
"title": "Ordered space separated list of ciphers",
"type": "string"
},
"request-timeout": {
"default": 600,
"description": "Timeout for HTTP requests.",
"title": "HTTP Request timeout in seconds",
"type": "integer"
},
"authenticate-to-backend": {
"default": "false",
"description": "If set to true the frontend certificate will be used as authentication certificate to the backend. Note: backend might have to know the frontend CA, available with 'backend-client-caucase-url'.",
"enum": [
"false",
"true"
],
"title": "Authenticate to backend",
"type": "string"
}
},
"title": "Input Parameters",
"type": "object"
}
instance-common.cfg.in 0000664 0000000 0000000 00000000701 13723117434 0035600 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend [buildout]
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
[slap_connection]
# Kept for backward compatibility
computer_id = ${slap-connection:computer-id}
partition_id = ${slap-connection:partition-id}
server_url = ${slap-connection:server-url}
software_release_url = ${slap-connection:software-release-url}
key_file = ${slap-connection:key-file}
cert_file = ${slap-connection:cert-file}
instance-kedifa.cfg.in 0000664 0000000 0000000 00000025704 13723117434 0035545 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend {%- if slap_software_type == software_type -%}
{% import "caucase" as caucase with context %}
# KeDiFa instance profile
[buildout]
extends =
{{ parameter_dict['common_profile'] }}
{{ parameter_dict['monitor_template'] }}
{{ parameter_dict['logrotate_base_instance'] }}
parts =
monitor-base
directory
kedifa
logrotate-entry-kedifa
promise-kedifa-http-reply
slave-kedifa-information
caucased
caucased-promise
caucase-updater
expose-csr_id
promise-expose-csr_id-ip-port
[monitor-instance-parameter]
# Note: Workaround for monitor stack, which uses monitor-httpd-port parameter
# directly, and in our case it can come from the network, thus resulting
# with need to strip !py!'u'
monitor-httpd-port = {{ instance_parameter['configuration.monitor-httpd-port'] | int }}
password = {{ instance_parameter['configuration.monitor-password'] | string }}
[caucased]
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
{% set caucase_host = '[' ~ instance_parameter['ipv6-random'] ~ ']' %}
{% set caucase_netloc = caucase_host ~ ':' ~ instance_parameter['configuration.caucase_port'] -%}
{% set caucase_url = 'http://' ~ caucase_netloc -%}
{{ caucase.caucased(
prefix='caucased',
buildout_bin_directory=parameter_dict['bin_directory'],
caucased_path='${directory:service}/caucased',
backup_dir='${directory:backup-caucased}',
data_dir='${directory:caucased}',
netloc=caucase_netloc,
service_auto_approve_count=0,
user_auto_approve_count=1,
key_len=2048,
)}}
# Create all needed directories
[directory]
recipe = slapos.cookbook:mkdirectory
bin = ${buildout:directory}/bin/
etc = ${buildout:directory}/etc/
srv = ${buildout:directory}/srv/
var = ${buildout:directory}/var/
tmp = ${buildout:directory}/tmp/
backup = ${:srv}/backup
log = ${:var}/log
run = ${:var}/run
service = ${:etc}/service
etc-run = ${:etc}/run
# KeDiFa directories
kedifa = ${:srv}/kedifa
etc-kedifa = ${:etc}/kedifa
# CAUCASE directories
caucased = ${:srv}/caucased
backup-caucased = ${:backup}/caucased
# reservation
reservation = ${:srv}/reservation
# csr_id publication
csr_id = ${:srv}/csr_id
caddy-csr_id = ${:etc}/caddy-csr_id
[kedifa-csr]
recipe = plone.recipe.command
organization = {{ slapparameter_dict['cluster-identification'] }}
organizational_unit = Kedifa Partition
command =
if [ ! -f ${:template-csr} ] && [ ! -f ${:key} ] ; then
/bin/bash -c '{{ parameter_dict['openssl'] }} req -new -sha256 \
-newkey rsa:2048 -nodes -keyout ${:key} \
-subj "/O=${:organization}/OU=${:organizational_unit}" \
-reqexts SAN \
-config <(cat {{ parameter_dict['openssl_cnf'] }} \
<(printf "\n[SAN]\nsubjectAltName=IP:${kedifa-config:ip}")) \
-out ${:template-csr}'
fi
update-command = ${:command}
template-csr = ${kedifa-config:template-csr}
key = ${kedifa-config:key}
stop-on-error = True
{{ caucase.updater(
prefix='caucase-updater',
buildout_bin_directory=parameter_dict['bin_directory'],
updater_path='${directory:service}/caucase-updater',
url=caucase_url,
data_dir='${directory:srv}/caucase-updater',
crt_path='${kedifa-config:certificate}',
ca_path='${kedifa-config:ca-certificate}',
crl_path='${kedifa-config:crl}',
key_path='${kedifa-csr:key}',
on_renew='${kedifa-reloader:wrapper-path}',
template_csr='${kedifa-csr:template-csr}'
)}}
[store-csr_id]
recipe = plone.recipe.command
csr_id_path = ${directory:csr_id}/csr_id.txt
csr_work_path = ${directory:tmp}/${:_buildout_section_name_}
stop-on-error = False
update-command = ${:command}
command =
{{ parameter_dict['bin_directory'] }}/caucase \
--ca-url {{ caucase_url }} \
--ca-crt ${kedifa-config:ca-certificate} \
--crl ${kedifa-config:crl} \
--mode service \
{#- XXX: Need to use caucase-updater-csr:csr, as there is no way to obatin csr_id from caucase-updater -#}
{#- XXX: nor directly path to the generated CSR #}
--send-csr ${caucase-updater-csr:csr} > ${:csr_work_path} && \
cut -d ' ' -f 1 ${:csr_work_path} > ${:csr_id_path}
[certificate-csr_id]
recipe = plone.recipe.command
certificate = ${directory:caddy-csr_id}/certificate.pem
key = ${directory:caddy-csr_id}/key.pem
stop-on-error = True
update-command = ${:command}
command =
if ! [ -f ${:key} ] && ! [ -f ${:certificate} ] ; then
{{ parameter_dict['openssl'] }} req -new -newkey rsa:2048 -sha256 -subj \
"/O=${kedifa-csr:organization}/OU=${kedifa-csr:organizational_unit}/CN={{ instance_parameter['ipv6-random'] }}" \
-days 5 -nodes -x509 -keyout ${:key} -out ${:certificate}
fi
[expose-csr_id-configuration]
ip = {{ instance_parameter['ipv6-random'] }}
port = 17000
key = ${certificate-csr_id:key}
certificate = ${certificate-csr_id:certificate}
error-log = ${directory:log}/expose-csr_id.log
[expose-csr_id-template]
recipe = slapos.recipe.template:jinja2
template = inline:
https://:${expose-csr_id-configuration:port}/ {
bind ${expose-csr_id-configuration:ip}
tls ${expose-csr_id-configuration:certificate} ${expose-csr_id-configuration:key}
log ${expose-csr_id-configuration:error-log}
}
rendered = ${directory:caddy-csr_id}/Caddyfile
[promise-expose-csr_id-ip-port]
<= monitor-promise-base
module = check_port_listening
name = expose-csr_id-ip-port-listening.py
config-hostname = ${expose-csr_id-configuration:ip}
config-port = ${expose-csr_id-configuration:port}
[expose-csr_id]
depends = ${store-csr_id:command}
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['caddy'] }}
-conf ${expose-csr_id-template:rendered}
-log ${expose-csr_id-configuration:error-log}
-http2=true
-disable-http-challenge
-disable-tls-alpn-challenge
-root ${directory:csr_id}
wrapper-path = ${directory:service}/expose-csr_id
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
[get-csr_id-certificate]
recipe = collective.recipe.shelloutput
commands =
certificate = cat ${certificate-csr_id:certificate}
[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
rendered = ${buildout:directory}/${:filename}
extra-context =
slapparameter_dict = {{ dumps(instance_parameter['configuration']) }}
slap_software_type = {{ dumps(instance_parameter['slap-software-type']) }}
context =
import json_module json
raw common_profile {{ parameter_dict['common_profile'] }}
key slap_software_type :slap_software_type
key slapparameter_dict :slapparameter_dict
section directory directory
${:extra-context}
[kedifa-config]
ip = {{ instance_parameter['ipv6-random'] }}
port = {{ instance_parameter['configuration.kedifa_port'] }}
db = ${directory:kedifa}/kedifa.sqlite
certificate = ${directory:etc-kedifa}/certificate.pem
key = ${:certificate}
ca-certificate = ${directory:etc-kedifa}/ca-certificate.pem
crl = ${directory:etc-kedifa}/crl.pem
template-csr = ${directory:etc-kedifa}/template-csr.pem
pidfile = ${directory:run}/kedifa.pid
logfile = ${directory:log}/kedifa.log
[kedifa-reloader]
recipe = slapos.cookbook:wrapper
command-line = kill -SIGHUP `cat ${kedifa-config:pidfile}`
wrapper-path = ${directory:etc-run}/kedifa-reloader
[promise-kedifa-http-reply]
<= monitor-promise-base
module = check_url_available
name = kedifa-http-reply.py
# Kedifa replies 400 on /, so use it to be sure that Kedifa replied
config-http_code = 400
config-url = https://[${kedifa-config:ip}]:${kedifa-config:port}
config-ca-cert-file = ${kedifa-config:ca-certificate}
[logrotate-entry-kedifa]
<= logrotate-entry-base
name = kedifa
log = ${kedifa-config:logfile}
rotate-num = {{ instance_parameter['configuration.rotate-num'] | int }}
[kedifa]
recipe = slapos.cookbook:wrapper
command-line = {{ parameter_dict['kedifa'] }}
--ip ${kedifa-config:ip}
--port ${kedifa-config:port}
--db ${kedifa-config:db}
--certificate ${kedifa-config:certificate}
--ca-certificate ${kedifa-config:ca-certificate}
--crl ${kedifa-config:crl}
--pidfile ${kedifa-config:pidfile}
--logfile ${kedifa-config:logfile}
wrapper-path = ${directory:service}/kedifa
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
# Publish KeDiFa configuration for upload and download for each slave
{%- set slave_kedifa_information = {} -%}
{%- for slave in slapparameter_dict['slave-list'] -%}
{%- set slave_reference = slave['slave_reference'] -%}
{%- set slave_dict = {} -%}
{%- do slave_dict.__setitem__('key-generate-auth-url', 'https://[${kedifa-config:ip}]:${kedifa-config:port}/${%s-auth-random:passwd}/generateauth' % (slave_reference,)) -%}
{%- do slave_dict.__setitem__('key-upload-url', 'https://[${kedifa-config:ip}]:${kedifa-config:port}/${%s-auth-random:passwd}?auth=' % (slave_reference,)) -%}
{%- do slave_dict.__setitem__('key-download-url', 'https://[${kedifa-config:ip}]:${kedifa-config:port}/${%s-auth-random:passwd}' % (slave_reference,)) -%}
{%- do slave_dict.__setitem__('kedifa-caucase-url', caucase_url ) -%}
{%- do slave_kedifa_information.__setitem__(slave_reference, slave_dict) %}
[{{ slave_reference }}-auth-random-generate]
recipe = plone.recipe.command
file = ${directory:reservation}/${:_buildout_section_name_}
command =
[ ! -f ${:file} ] && {{ parameter_dict['curl'] }}/bin/curl -s -g -X POST https://[${kedifa-config:ip}]:${kedifa-config:port}/reserve-id --cert ${kedifa-config:certificate} --cacert ${kedifa-config:ca-certificate} > ${:file}.tmp && mv ${:file}.tmp ${:file}
update-command = ${:command}
[{{ slave_reference }}-auth-random]
recipe = collective.recipe.shelloutput
file = {{ '${' + slave_reference }}-auth-random-generate:file}
commands =
passwd = cat ${:file} 2>/dev/null || echo "NotReadyYet"
{% endfor %}
[master-auth-random-generate]
recipe = plone.recipe.command
file = ${directory:reservation}/${:_buildout_section_name_}
command =
[ ! -f ${:file} ] && {{ parameter_dict['curl'] }}/bin/curl -s -g -X POST https://[${kedifa-config:ip}]:${kedifa-config:port}/reserve-id --cert ${kedifa-config:certificate} --cacert ${kedifa-config:ca-certificate} > ${:file}.tmp && mv ${:file}.tmp ${:file}
update-command = ${:command}
[master-auth-random]
recipe = collective.recipe.shelloutput
file = ${master-auth-random-generate:file}
commands =
passwd = cat ${:file} 2>/dev/null || echo "NotReadyYet"
[slave-kedifa-information]
recipe = slapos.cookbook:publish.serialised
{# sort_keys are important in order to avoid shuffling parameters on each run #}
slave-kedifa-information = {{ json_module.dumps(slave_kedifa_information, sort_keys=True) }}
caucase-url = {{ caucase_url }}
master-key-generate-auth-url = https://[${kedifa-config:ip}]:${kedifa-config:port}/${master-auth-random:passwd}/generateauth
master-key-upload-url = https://[${kedifa-config:ip}]:${kedifa-config:port}/${master-auth-random:passwd}?auth=
master-key-download-url = https://[${kedifa-config:ip}]:${kedifa-config:port}/${master-auth-random:passwd}
csr_id-url = https://[${expose-csr_id-configuration:ip}]:${expose-csr_id-configuration:port}/csr_id.txt
csr_id-certificate = ${get-csr_id-certificate:certificate}
monitor-base-url = ${monitor-instance-parameter:monitor-base-url}
{%- endif -%} {# if slap_software_type in software_type #}
instance-output-schema.json 0000664 0000000 0000000 00000005314 13723117434 0036720 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend {
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Values returned by Caddy Frontend instanciation",
"properties": {
"accepted-slave-amount": {
"description": "Amount of Slaves allocated to the Instance which are deployed",
"type": "integer"
},
"domain": {
"description": "Base domain used by the instance",
"type": "string"
},
"master-key-generate-auth-url": {
"description": "URL to GET once auth for master-key-upload-url",
"type": "string"
},
"master-key-upload-url": {
"description": "URL to PUT PEM bundle of main certificate and key",
"type": "string"
},
"monitor-base-url": {
"description": "Base url for monitor",
"type": "string"
},
"monitor-password": {
"description": "Password to access the monitor",
"type": "string"
},
"monitor-url": {
"description": "Url of Monitor (opml)",
"type": "string"
},
"monitor-user": {
"description": "User to access the monitor",
"type": "string"
},
"rejected-slave-amount": {
"description": "Rejected Amount of Slaves allocated to the Instance which are not deployed",
"type": "integer"
},
"rejected-slave-dict": {
"description": "Dict of slaves which were rejected. Keys are slave references, values are lists of errors on slaves.",
"type": "array"
},
"slave-amount": {
"description": "Total amount of Slaves allocated to the Instance (include blocked ones)",
"type": "integer"
},
"kedifa-csr_id-url": {
"description": "URL on which KeDiFa publishes its csr_id sent to caucase.",
"type": "string"
},
"kedifa-csr_id-certificate": {
"description": "Certificate used to serve data on kedifa-csr_id-url.",
"type": "string"
},
"kedifa-caucase-url": {
"description": "Url to caucase used by KeDiFa.",
"type": "string"
},
"caddy-frontend-N-csr_id-url": {
"description": "URL on which frontend node number N publishes its csr_id sent to caucase.",
"type": "string"
},
"caddy-frontend-N-csr_id-certificate": {
"description": "Certificate used to serve data on caddy-frontend-N-csr_id-url.",
"type": "string"
},
"warning-slave-dict": {
"description": "Dict of slaves which got warnings. Keys are slave references, values are lists of warnings on slaves.",
"type": "array"
},
"warning-list": {
"description": "List of warning found during the request.",
"type": "array"
},
"backend-client-caucase-url": {
"description": "URL to caucase used by authentication to the backend.",
"type": "string"
}
},
"type": "object"
}
instance-slave-caddy-input-schema.json 0000664 0000000 0000000 00000020314 13723117434 0040706 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend {
"$schema": "http://json-schema.org/draft-04/schema",
"properties": {
"custom_domain": {
"description": "Custom Domain to use for the website",
"pattern": "^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}$",
"title": "Custom Domain",
"type": "string"
},
"url": {
"description": "Url of the backend",
"pattern": "^(http|https|ftp)://",
"title": "Backend URL",
"type": "string"
},
"type": {
"default": "",
"description": "Type of slave. If redirect, the slave will redirect to the given url. If zope, the rewrite rules will be compatible with Virtual Host Monster. Implemented are default, zope, redirect, notebook and websocket, not implemneted is eventsource.",
"enum": [
"",
"zope",
"redirect",
"notebook",
"websocket",
"eventsource"
],
"title": "Backend Type",
"type": "string"
},
"path": {
"default": "",
"description": "Path to proxy to in the backend",
"title": "type:zope Backend Path",
"type": "string"
},
"enable_cache": {
"default": "false",
"description": "If set to true, http caching server (Apache Traffic Server) will be used between frontend Caddy and backend",
"enum": [
"false",
"true"
],
"title": "Enable Cache",
"type": "string"
},
"https-only": {
"default": "true",
"description": "If set to true, http requests will be redirected to https",
"enum": [
"false",
"true"
],
"title": "HTTPS Only",
"type": "string"
},
"default-path": {
"default": "",
"description": "Provide default path to redirect user to when user access / (the site root)",
"title": "type:zope Default Path",
"type": "string"
},
"disable-no-cache-request": {
"default": "false",
"description": "If set to true, Cache-Control and Pragma requests headers will not be sent to cache and backend servers. This prevents clients from bypassing cache when enable_cache is true",
"enum": [
"false",
"true"
],
"title": "enable_cache: Disable 'no-cache' requests",
"type": "string"
},
"disable-via-header": {
"default": "false",
"description": "If set to true, Via response headers will not be sent to client",
"enum": [
"false",
"true"
],
"title": "enable_cache: Disable 'Via' headers from cache",
"type": "string"
},
"disabled-cookie-list": {
"default": "",
"description": "List of Cookies separated by space that will not be sent to cache and backend servers. This is especially useful to discard analytics tracking cookies when using Vary: Cookie cache headers",
"title": "Disabled Cookies",
"type": "string"
},
"enable-http2": {
"default": "true",
"description": "Use HTTP2 Protocol for the site",
"enum": [
"true",
"false"
],
"title": "Enable HTTP2 Protocol",
"type": "string"
},
"https-url": {
"description": "HTTPS Url of the backend if it is diferent from url parameter",
"pattern": "^(http|https|ftp)://",
"title": "HTTPS Backend URL",
"type": "string"
},
"monitor-ipv4-test": {
"default": "",
"description": "IPv4 Address for the frontend keep monitoring with ping",
"title": "IPv4 Address to Monitor Packet Lost",
"type": "string"
},
"monitor-ipv6-test": {
"default": "",
"description": "IPv6 Address for the frontend keep monitoring with ping6 (without brackets)",
"title": "IPv6 Address to Monitor Packet Lost",
"type": "string"
},
"websocket-path-list": {
"default": "",
"description": "Space separated list of path to the websocket application. If not set the whole slave will be websocket, if set then / will be HTTP, and / will be WSS. In order to have ' ' in the space use '%20'",
"title": "type:websocket Websocket Application Path List",
"type": "string"
},
"websocket-transparent": {
"default": "true",
"description": "If set to false, websocket slave will be without Caddy's transparent proxy mode. Depending on the application the setting shall be false or true. Defaults to true for transparent proxying.",
"enum": [
"false",
"true"
],
"title": "type:websocket Transparent proxy",
"type": "string"
},
"prefer-gzip-encoding-to-backend": {
"default": "false",
"description": "If set to true, frontend will rewrite Accept-Encoding request header to simply 'gzip' for all variants of Accept-Encoding containing 'gzip', in order to maximize cache hits for resources cached with Vary: Accept-Encoding when enable_cache is used",
"enum": [
"false",
"true"
],
"title": "Prefer gzip Encoding for Backend",
"type": "string"
},
"server-alias": {
"default": "",
"description": "Server Alias List separated by space",
"title": "Server Alias",
"type": "string"
},
"ssl-proxy-verify": {
"default": "false",
"description": "If set to true, Backend SSL Certificates will be checked and frontend will refuse to proxy if certificate is invalid",
"enum": [
"false",
"true"
],
"title": "Verify Backend Certificates",
"type": "string"
},
"ssl_crt": {
"default": "",
"description": "Content of the SSL Certificate file. Deprecated, please use key-upload-url.",
"textarea": true,
"title": "[DEPRECATED] SSL Certificate",
"type": "string"
},
"ssl_key": {
"default": "",
"description": "Content of the SSL Key file. Deprecated, please use key-upload-url.",
"textarea": true,
"title": "[DEPRECATED] SSL Key",
"type": "string"
},
"ssl_ca_crt": {
"default": "",
"description": "Content of the CA certificate file. Deprecated, please use key-upload-url.",
"textarea": true,
"title": "[DEPRECATED] SSL Certificate Authority's Certificate",
"type": "string"
},
"ssl_proxy_ca_crt": {
"default": "",
"description": "Content of the SSL Certificate Authority file of the backend (to be used with ssl-proxy-verify)",
"textarea": true,
"title": "SSL Backend Authority's Certificate",
"type": "string"
},
"virtualhostroot-http-port": {
"default": 80,
"description": "Port where http requests to frontend will be redirected.",
"title": "type:zope virtualhostroot-http-port",
"type": "integer"
},
"virtualhostroot-https-port": {
"default": 443,
"description": "Port where https requests to frontend will be redirected.",
"title": "type:zope virtualhostroot-https-port",
"type": "integer"
},
"backend-connect-timeout": {
"description": "Time in seconds for establishing connection to the backend.",
"title": "Timeout for backend connection (seconds)",
"type": "integer"
},
"backend-connect-retries": {
"description": "Amount of retries to connect to the backend. The amount of backend-connect-timeout*backend-connect-retries seconds will be spent to connect to the backend.",
"title": "Amount of retries to connect to the backend.",
"type": "integer"
},
"request-timeout": {
"description": "Timeout for HTTP requests.",
"title": "HTTP Request timeout in seconds",
"type": "integer"
},
"ciphers": {
"description": "List of ciphers. Empty defaults to cluster list of ciphers, which by default are Caddy list of ciphers. See https://caddyserver.com/docs/tls for more information.",
"title": "Ordered space separated list of ciphers",
"type": "string"
},
"authenticate-to-backend": {
"description": "If set to true the frontend certificate will be used as authentication certificate to the backend. Note: backend might have to know the frontend CA, available with 'backend-client-caucase-url'.",
"enum": [
"false",
"true"
],
"title": "Authenticate to backend",
"type": "string"
}
},
"title": "Input Parameters",
"type": "object"
}
instance-slave-caddy-simplified-input-schema.json 0000664 0000000 0000000 00000006677 13723117434 0043051 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend {
"$schema": "http://json-schema.org/draft-04/schema",
"properties": {
"url": {
"description": "Url of the backend",
"pattern": "^(http|https|ftp)://",
"title": "Backend URL",
"type": "string"
},
"type": {
"default": "",
"description": "Type of slave. If redirect, the slave will redirect to the given url. If zope, the rewrite rules will be compatible with Virtual Host Monster. Implemented are default, zope, redirect, notebook and websocket, not implemneted is eventsource.",
"enum": [
"",
"zope"
],
"title": "Backend Type",
"type": "string"
},
"custom_domain": {
"description": "Custom Domain to use for the website",
"pattern": "^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}$",
"title": "Custom Domain",
"type": "string"
},
"server-alias": {
"default": "",
"description": "Server Alias List separated by space",
"title": "Server Alias",
"type": "string"
},
"default-path": {
"default": "",
"description": "Provide default path to redirect user to when user access / (the site root)",
"title": "type:zope Default Path",
"type": "string"
},
"disable-no-cache-request": {
"default": "false",
"description": "If set to true, Cache-Control and Pragma requests headers will not be sent to cache and backend servers. This prevents clients from bypassing cache when enable_cache is true",
"enum": [
"false",
"true"
],
"title": "enable_cache: Disable 'no-cache' requests",
"type": "string"
},
"disable-via-header": {
"default": "false",
"description": "If set to true, Via response headers will not be sent to client",
"enum": [
"false",
"true"
],
"title": "enable_cache: Disable 'Via' headers from cache",
"type": "string"
},
"disabled-cookie-list": {
"default": "",
"description": "List of Cookies separated by space that will not be sent to cache and backend servers. This is especially useful to discard analytics tracking cookies when using Vary: Cookie cache headers",
"title": "Disabled Cookies",
"type": "string"
},
"enable_cache": {
"default": "false",
"description": "If set to true, http caching server (Apache Traffic Server) will be used between frontend Caddy and backend",
"enum": [
"false",
"true"
],
"title": "Enable Cache",
"type": "string"
},
"https-only": {
"default": "true",
"description": "If set to true, http requests will be redirected to https",
"enum": [
"false",
"true"
],
"title": "HTTPS Only",
"type": "string"
},
"path": {
"default": "",
"description": "Path to proxy to in the backend",
"title": "type:zope Backend Path",
"type": "string"
},
"prefer-gzip-encoding-to-backend": {
"default": "false",
"description": "If set to true, frontend will rewrite Accept-Encoding request header to simply 'gzip' for all variants of Accept-Encoding containing 'gzip', in order to maximize cache hits for resources cached with Vary: Accept-Encoding when enable_cache is used",
"enum": [
"false",
"true"
],
"title": "Prefer gzip Encoding for Backend",
"type": "string"
}
},
"title": "Input Parameters",
"type": "object"
}
instance-slave-output-schema.json 0000664 0000000 0000000 00000003257 13723117434 0040034 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend {
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Values returned by Caddy Frontend instanciation",
"properties": {
"domain": {
"description": "Base domain used by the instance",
"type": "string"
},
"key-generate-auth-url": {
"description": "URL to GET once auth for key-upload-url",
"type": "string"
},
"key-upload-url": {
"description": "URL to PUT PEM bundle of certificate and key",
"type": "string"
},
"log-access-url": {
"description": "List of URLs to access logs",
"type": "array"
},
"public-ipv4": {
"description": "Public IPv4 to be included on DNS",
"type": "string"
},
"replication_number": {
"description": "Number of nodes the slave is replicated",
"type": "integer"
},
"secure_access": {
"description": "URL for HTTP access",
"type": "string"
},
"site_url": {
"description": "URL for HTTP access",
"type": "string"
},
"url": {
"description": "Default URL provided",
"type": "string"
},
"request-error-list": {
"description": "In case if slave has been rejected by master or has error in the request, the list contains information about each problem",
"type": "array"
},
"warning-list": {
"description": "List of warning found during the request.",
"type": "array"
},
"kedifa-caucase-url": {
"description": "URL to caucase used by KeDiFa",
"type": "string"
},
"backend-client-caucase-url": {
"description": "URL to caucase used by authentication to the backend.",
"type": "string"
}
},
"type": "object"
}
instance.cfg.in 0000664 0000000 0000000 00000011142 13723117434 0034313 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend [buildout]
extends = {{ common_profile }}
parts =
dynamic-template-caddy-replicate
switch-softwaretype
[caddyprofiledeps]
recipe = caddyprofiledeps
[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
rendered = ${buildout:directory}/${:filename}
extra-context =
context =
import json_module json
key slap_software_type instance-parameter:slap-software-type
key slapparameter_dict instance-parameter:configuration
key slave_instance_list instance-parameter:slave-instance-list
section instance_parameter instance-parameter
${:extra-context}
[switch-softwaretype]
recipe = slapos.cookbook:softwaretype
default = ${dynamic-template-caddy-replicate:rendered}
RootSoftwareInstance = ${dynamic-template-caddy-replicate:rendered}
custom-personal = ${dynamic-template-caddy-replicate:rendered}
single-default = ${dynamic-template-caddy-frontend:rendered}
single-custom-personal = ${dynamic-template-caddy-frontend:rendered}
replicate = ${dynamic-template-caddy-replicate:rendered}
kedifa = ${dynamic-template-kedifa:rendered}
[dynamic-template-caddy-frontend-parameters]
{% for key,value in template_frontend_parameter_dict.iteritems() %}
{{ key }} = {{ dumps(value) }}
{% endfor -%}
[dynamic-template-caddy-frontend]
< = jinja2-template-base
template = {{ template_caddy_frontend }}
filename = instance-caddy-frontend.cfg
extensions = jinja2.ext.do
extra-context =
section parameter_dict dynamic-template-caddy-frontend-parameters
raw software_type single-custom-personal
caucase-jinja2-library = {{ caucase_jinja2_library }}
import-list =
file caucase :caucase-jinja2-library
[dynamic-template-caddy-replicate]
< = jinja2-template-base
depends = ${caddyprofiledeps:recipe}
template = {{ template_caddy_replicate }}
filename = instance-caddy-replicate.cfg
extensions = jinja2.ext.do
extra-context =
import subprocess_module subprocess
import functools_module functools
import validators validators
key cluster_identification instance-parameter:root-instance-title
raw caddy_backend_url_validator {{ caddy_backend_url_validator }}
raw template_publish_slave_information {{ template_replicate_publish_slave_information }}
# Must match the key id in [switch-softwaretype] which uses this section.
raw software_type RootSoftwareInstance-default-custom-personal-replicate
raw template_monitor {{ monitor2_template }}
raw common_profile {{ common_profile }}
section parameter_dict dynamic-template-caddy-frontend-parameters
caucase-jinja2-library = {{ caucase_jinja2_library }}
import-list =
file caucase :caucase-jinja2-library
[dynamic-template-kedifa]
< = jinja2-template-base
template = {{ template_kedifa }}
filename = instance-kedifa.cfg
extensions = jinja2.ext.do
extra-context =
section parameter_dict dynamic-template-caddy-frontend-parameters
raw software_type kedifa
caucase-jinja2-library = {{ caucase_jinja2_library }}
import-list =
file caucase :caucase-jinja2-library
[instance-parameter]
# Fetches parameters defined in SlapOS Master for this instance.
# Always the same.
recipe = slapos.cookbook:slapconfiguration.serialised
computer = ${slap-connection:computer-id}
partition = ${slap-connection:partition-id}
url = ${slap-connection:server-url}
key = ${slap-connection:key-file}
cert = ${slap-connection:cert-file}
# Define default parameter(s) that will be used later, in case user didn't
# specify it
# All parameters are available through the configuration.XX syntax.
# All possible parameters should have a default.
configuration.domain = example.org
configuration.public-ipv4 =
configuration.port = 4443
configuration.plain_http_port = 8080
configuration.plain_nginx_port = 8081
configuration.nginx_port = 9443
configuration.kedifa_port = 7879
# Warning: Caucase takes also cacuase_port+1
configuration.caucase_port = 8890
configuration.caucase_backend_client_port = 8990
configuration.apache-key =
configuration.apache-certificate =
configuration.open-port = 80 443
configuration.disk-cache-size = 8G
configuration.ram-cache-size = 1G
configuration.trafficserver-synthetic-port = 8083
configuration.trafficserver-mgmt-port = 8084
configuration.re6st-verification-url = http://[2001:67c:1254:4::1]/index.html
configuration.enable-http2-by-default = true
configuration.global-disable-http2 = false
configuration.ciphers =
configuration.request-timeout = 600
configuration.mpm-graceful-shutdown-timeout = 5
configuration.frontend-name =
configuration.backend-connect-timeout = 5
configuration.backend-connect-retries = 3
configuration.backend-haproxy-http-port = 21080
configuration.backend-haproxy-https-port = 21443
configuration.authenticate-to-backend = False
configuration.rotate-num = 4000
setup.py 0000664 0000000 0000000 00000000554 13723117434 0033140 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend # The caddyprofiledeps egg allows to set dependecies of the Caddy profiles
# which are enabled during the instance run, thanks to using caddyprofiledeps
# recipe
from setuptools import setup
setup(
name='caddyprofiledeps',
install_requires=[
'validators',
],
entry_points={
'zc.buildout': [
'default = caddyprofiledummy:Recipe',
]
}
)
software.cfg 0000664 0000000 0000000 00000001134 13723117434 0033734 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend [buildout]
extends = common.cfg
[versions]
# Modern KeDiFa requires zc.lockfile
zc.lockfile = 1.4
# Versions pinned for kedifa need urllib3 >= 1.18
urllib3 = 1.24
requests = 2.20.0
certifi = 2018.10.15
idna = 2.7
chardet = 3.0.4
# ipaddress is patching IPAddress so IPv6 match works
ipaddress = 1.0.22
# Versions pinned for kedifa need urllib3 >= 1.18
validators = 0.12.2
PyRSS2Gen = 1.1
cns.recipe.symlink = 0.2.3
ecdsa = 0.13
gitdb = 0.6.4
plone.recipe.command = 1.1
pycrypto = 2.6.1
rdiff-backup = 1.0.5+SlapOSPatched001
slapos.recipe.template = 4.4
smmap = 0.9.0
numpy = 1.16.4
websockify = 0.8.0
software.cfg.json 0000664 0000000 0000000 00000002655 13723117434 0034715 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend {
"description": "Caddy Frontend",
"name": "Caddy Frontend",
"serialisation": "xml",
"software-type": {
"custom-personal": {
"description": "",
"index": 2,
"request": "instance-caddy-input-schema.json",
"response": "instance-output-schema.json",
"title": "Custom Personal"
},
"custom-personal-slave": {
"description": "Custom Personal",
"index": 1,
"request": "instance-slave-caddy-input-schema.json",
"response": "instance-output-schema.json",
"shared": true,
"software-type": "custom-personal",
"title": "Custom Personal (Slave)"
},
"default": {
"description": "Default",
"index": 3,
"request": "instance-caddy-input-schema.json",
"response": "instance-output-schema.json",
"software-type": "default",
"title": "Default"
},
"default-slave": {
"description": "Default",
"index": 4,
"request": "instance-slave-caddy-input-schema.json",
"response": "instance-output-schema.json",
"shared": true,
"software-type": "default",
"title": "Default (slave)"
},
"default-simplified-slave": {
"description": "Default",
"index": 5,
"request": "instance-slave-caddy-simplified-input-schema.json",
"response": "instance-output-schema.json",
"shared": true,
"software-type": "default",
"title": "Default Basic (slave)"
}
}
}
templates/ 0000775 0000000 0000000 00000000000 13723117434 0033420 5 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend Caddyfile.in 0000664 0000000 0000000 00000002706 13723117434 0035641 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates # Main caddy configuration file
import {{frontend_configuration.get('log-access-configuration')}}
import {{ slave_configuration_directory }}/*.conf
:{{ https_port }} {
tls {{ master_certificate }} {{ master_certificate }}
bind {{ local_ipv4 }}
status 404 /
log / {{ access_log }} "{remote} - {>REMOTE_USER} [{when}] \"{method} {uri} {proto}\" {status} {size} \"{>Referer}\" \"{>User-Agent}\" {latency_ms}" {
rotate_size 0
}
errors {{ error_log }} {
rotate_size 0
* {{ not_found_file }}
}
}
:{{ http_port }} {
bind {{ local_ipv4 }}
status 404 /
log / {{ access_log }} "{remote} - {>REMOTE_USER} [{when}] \"{method} {uri} {proto}\" {status} {size} \"{>Referer}\" \"{>User-Agent}\" {latency_ms}" {
rotate_size 0
}
errors {{ error_log }} {
rotate_size 0
* {{ not_found_file }}
}
}
# Access to server-status Caddy-style
https://[{{ global_ipv6 }}]:{{ https_port }}/server-status, https://{{ local_ipv4 }}:{{ https_port }}/server-status {
tls {{ frontend_configuration['ip-access-certificate'] }} {{ frontend_configuration['ip-access-certificate'] }}
bind {{ local_ipv4 }}
basicauth "{{ username }}" {{ password | trim }} {
"Server Status"
/
}
expvar
pprof
log / {{ access_log }} "{remote} - {>REMOTE_USER} [{when}] \"{method} {uri} {proto}\" {status} {size} \"{>Referer}\" \"{>User-Agent}\" {latency_ms}" {
rotate_size 0
}
errors {{ error_log }} {
rotate_size 0
* {{ not_found_file }}
}
}
apache-custom-slave-list.cfg.in 0000664 0000000 0000000 00000055203 13723117434 0041325 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates {%- if software_type == slap_software_type %}
{%- set kedifa_updater_mapping = [] %}
{%- set cached_server_dict = {} %}
{%- set backend_slave_list = [] %}
{%- set part_list = [] %}
{%- set cache_port = caddy_configuration.get('cache-port') %}
{%- set cache_access = "http://%s:%s" % (local_ipv4, cache_port) %}
{%- set ssl_cache_access = "http://%s:%s/HTTPS" % (local_ipv4, cache_port) %}
{%- set backend_haproxy_http_url = 'http://%s:%s' % (local_ipv4, backend_haproxy_configuration['http-port']) %}
{%- set backend_haproxy_https_url = 'http://%s:%s' % (local_ipv4, backend_haproxy_configuration['https-port']) %}
{%- set TRUE_VALUES = ['y', 'yes', '1', 'true'] %}
{%- set generic_instance_parameter_dict = { 'cache_access': cache_access, 'local_ipv4': local_ipv4, 'http_port': http_port, 'https_port': https_port} %}
{%- set slave_log_dict = {} %}
{%- if extra_slave_instance_list %}
{%- set slave_instance_information_list = [] %}
{%- set slave_instance_list = slave_instance_list + json_module.loads(extra_slave_instance_list) %}
{%- endif %}
{%- if master_key_download_url %}
{%- do kedifa_updater_mapping.append((master_key_download_url, master_certificate, apache_certificate)) %}
{%- else %}
{%- do kedifa_updater_mapping.append(('notreadyyet', master_certificate, apache_certificate)) %}
{%- endif %}
{%- if kedifa_configuration['slave_kedifa_information'] %}
{%- set slave_kedifa_information = json_module.loads(kedifa_configuration['slave_kedifa_information']) %}
{%- else %}
{%- set slave_kedifa_information = {} %}
{%- endif -%}
[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
extra-context =
context =
raw common_profile {{ common_profile }}
${:extra-context}
# empty sections if no slaves are available
[slave-log-directory-dict]
[slave-password]
{#- Loop thought slave list to set up slaves #}
{%- set DEFAULT_PORT = {'http': 80, 'https': 443, '': None} %}
{%- for slave_instance in slave_instance_list %}
{#- prepare backend parameters #}
{%- for key, prefix in [('url', 'http_backend'), ('https-url', 'https_backend')] %}
{%- set parsed = urlparse_module.urlparse(slave_instance.get(key, '').strip()) %}
{%- set info_dict = {'scheme': parsed.scheme, 'hostname': parsed.hostname, 'port': parsed.port or DEFAULT_PORT[parsed.scheme], 'path': parsed.path, 'fragment': parsed.fragment} %}
{%- do slave_instance.__setitem__(prefix, info_dict) %}
{%- endfor %}
{%- do slave_instance.__setitem__('ssl_proxy_verify', ('' ~ slave_instance.get('ssl-proxy-verify', '')).lower() in TRUE_VALUES) %}
{#- Manage ciphers #}
{%- set slave_ciphers = slave_instance.get('ciphers', '').strip().split() %}
{%- if slave_ciphers %}
{%- set slave_cipher_list = ' '.join(slave_ciphers) %}
{%- else %}
{%- set slave_cipher_list = ciphers.strip() %}
{%- endif %}
{%- do slave_instance.__setitem__('cipher_list', slave_cipher_list) %}
{#- Manage common instance parameters #}
{%- set slave_type = slave_instance.get('type', '') %}
{%- set enable_cache = (('' ~ slave_instance.get('enable_cache', '')).lower() in TRUE_VALUES and slave_type != 'redirect') %}
{%- set slave_reference = slave_instance.get('slave_reference') %}
{%- set slave_kedifa = slave_kedifa_information.get(slave_reference) %}
{#- Setup backend URLs for front facing Caddy #}
{%- if slave_type == 'redirect' %}
{%- do slave_instance.__setitem__('backend-http-url', slave_instance.get('url', '').rstrip('/')) %}
{%- if slave_instance.get('https-url') %}
{%- do slave_instance.__setitem__('backend-https-url', slave_instance.get['https-url'].rstrip('/')) %}
{%- endif %}
{%- elif enable_cache %}
{%- if 'domain' in slave_instance %}
{%- if not slave_instance.get('custom_domain') %}
{%- do slave_instance.__setitem__('custom_domain', slave_instance.get('domain')) %}
{%- endif %}
{%- endif %}
{%- do slave_instance.__setitem__('backend-http-url', cache_access) %}
{%- if slave_instance.get('https-url') %}
{%- do slave_instance.__setitem__('backend-https-url', ssl_cache_access) %}
{%- endif %}
{%- do cached_server_dict.__setitem__(slave_reference, slave_configuration_section_name) %}
{%- else %}
{%- do slave_instance.__setitem__('backend-http-url', backend_haproxy_http_url) %}
{%- if slave_instance.get('https-url') %}
{%- do slave_instance.__setitem__('backend-https-url', backend_haproxy_https_url) %}
{%- endif %}
{%- endif %}
{%- if slave_kedifa %}
{%- set key_download_url = slave_kedifa.get('key-download-url') %}
{%- else %}
{%- set key_download_url = 'notreadyyet' %}
{%- endif %}
{%- set slave_section_title = 'dynamic-template-slave-instance-%s' % slave_reference %}
{%- set slave_parameter_dict = generic_instance_parameter_dict.copy() %}
{%- set slave_publish_dict = {} %}
{%- set slave_configuration_section_name = 'slave-instance-%s-configuration' % slave_reference %}
{%- set slave_logrotate_section = slave_reference + "-logs" %}
{%- set slave_password_section = slave_reference + "-password" %}
{%- set slave_ln_section = slave_reference + "-ln" %}
{#- extend parts #}
{%- do part_list.extend([slave_ln_section]) %}
{%- do part_list.extend([slave_logrotate_section, slave_section_title]) %}
{%- set slave_log_folder = '${logrotate-directory:logrotate-backup}/' + slave_reference + "-logs" %}
{#- Pass HTTP2 switch #}
{%- do slave_instance.__setitem__('enable_http2_by_default', enable_http2_by_default) %}
{%- do slave_instance.__setitem__('global_disable_http2', global_disable_http2) %}
{#- Pass backend timeout values #}
{%- for key in ['backend-connect-timeout', 'backend-connect-retries', 'request-timeout', 'authenticate-to-backend'] %}
{%- if slave_instance.get(key, '') == '' %}
{%- do slave_instance.__setitem__(key, configuration[key]) %}
{%- endif %}
{%- endfor %}
{%- do slave_instance.__setitem__('authenticate-to-backend', ('' ~ slave_instance.get('authenticate-to-backend', '')).lower() in TRUE_VALUES) %}
{#- Set Up log files #}
{%- do slave_parameter_dict.__setitem__('access_log', '/'.join([caddy_log_directory, '%s_access_log' % slave_reference])) %}
{%- do slave_parameter_dict.__setitem__('error_log', '/'.join([caddy_log_directory, '%s_error_log' % slave_reference])) %}
{%- do slave_parameter_dict.__setitem__('backend_log', '/'.join([caddy_log_directory, '%s_backend_log' % slave_reference])) %}
{%- do slave_instance.__setitem__('access_log', slave_parameter_dict.get('access_log')) %}
{%- do slave_instance.__setitem__('error_log', slave_parameter_dict.get('error_log')) %}
{%- do slave_instance.__setitem__('backend_log', slave_parameter_dict.get('backend_log')) %}
{#- Add slave log directory to the slave log access dict #}
{%- do slave_log_dict.__setitem__(slave_reference, slave_log_folder) %}
{%- set slave_log_access_url = 'https://' + slave_reference.lower() + ':${'+ slave_password_section +':passwd}@[' + frontend_configuration.get('caddy-ipv6') + ']:' + frontend_configuration.get('caddy-https-port') + '/' + slave_reference.lower() + '/' %}
{%- do slave_publish_dict.__setitem__('log-access', slave_log_access_url) %}
{%- do slave_publish_dict.__setitem__('slave-reference', slave_reference) %}
{%- do slave_publish_dict.__setitem__('public-ipv4', public_ipv4) %}
{%- do slave_publish_dict.__setitem__('backend-client-caucase-url', backend_client_caucase_url) %}
{#- Set slave domain if none was defined #}
{%- if slave_instance.get('custom_domain', None) == None %}
{%- set domain_prefix = slave_instance.get('slave_reference').replace("-", "").replace("_", "").lower() %}
{%- do slave_instance.__setitem__('custom_domain', "%s.%s" % (domain_prefix, slapparameter_dict.get('domain'))) %}
{%- endif %}
{%- do slave_publish_dict.__setitem__('domain', slave_instance.get('custom_domain')) %}
{%- do slave_publish_dict.__setitem__('url', "http://%s" % slave_instance.get('custom_domain')) %}
{%- do slave_publish_dict.__setitem__('site_url', "http://%s" % slave_instance.get('custom_domain')) %}
{%- do slave_publish_dict.__setitem__('secure_access', 'https://%s' % slave_instance.get('custom_domain')) %}
[slave-log-directory-dict]
{{slave_reference}} = {{ slave_log_folder }}
[slave-password]
{{ slave_reference }} = {{ '${' + slave_password_section + ':passwd}' }}
{#- Set slave logrotate entry #}
[{{slave_logrotate_section}}]
<= logrotate-entry-base
name = ${:_buildout_section_name_}
log = {{slave_parameter_dict.get('access_log')}} {{slave_parameter_dict.get('error_log')}} {{slave_parameter_dict.get('backend_log')}}
backup = {{ slave_log_folder }}
rotate-num = {{ dumps('' ~ configuration['rotate-num']) }}
{#- integrate current logs inside #}
[{{slave_ln_section}}]
recipe = plone.recipe.command
stop-on-error = false
update-command = ${:command}
command = ln -sf {{slave_parameter_dict.get('error_log')}} {{ slave_log_folder }}/error.log && ln -sf {{slave_parameter_dict.get('access_log')}} {{ slave_log_folder }}/access.log && ln -sf {{slave_parameter_dict.get('backend_log')}} {{ slave_log_folder }}/backend.log
{#- Set password for slave #}
[{{slave_password_section}}]
recipe = slapos.cookbook:generate.password
storage-path = {{caddy_configuration_directory}}/.{{slave_reference}}.passwd
bytes = 8
{#- ################################################## #}
{#- Set Slave Certificates if needed #}
{#- Set certificate key for custom configuration #}
{%- set cert_name = slave_reference.replace('-','.') + '.pem' %}
{%- set certificate = '%s/%s' % (autocert, cert_name) %}
{%- do slave_parameter_dict.__setitem__('certificate', certificate )%}
{#- Set ssl certificates for each slave #}
{%- for cert_name in ('ssl_csr', 'ssl_proxy_ca_crt')%}
{%- if cert_name in slave_instance %}
{%- set cert_title = '%s-%s' % (slave_reference, cert_name.replace('ssl_', '')) %}
{%- set cert_file = '/'.join([custom_ssl_directory, cert_title.replace('-','.')]) %}
{%- do part_list.append(cert_title) %}
{%- do slave_parameter_dict.__setitem__(cert_name, cert_file) %}
{%- do slave_instance.__setitem__('path_to_' + cert_name, cert_file) %}
{#- Store certificates on fs #}
[{{ cert_title }}]
< = jinja2-template-base
template = {{ empty_template }}
rendered = {{ cert_file }}
extra-context =
key content {{ cert_title + '-config:value' }}
{#- BBB: SlapOS Master non-zero knowledge BEGIN #}
{#- Store certificate in config #}
[{{ cert_title + '-config' }}]
value = {{ dumps(slave_instance.get(cert_name)) }}
{%- endif %}
{%- endfor %}
{#- Set Up Certs #}
{%- if 'ssl_key' in slave_instance and 'ssl_crt' in slave_instance %}
{%- set cert_title = '%s-crt' % (slave_reference) %}
{%- set cert_file = '/'.join([directory['bbb-ssl-dir'], cert_title.replace('-','.')]) %}
{%- do kedifa_updater_mapping.append((key_download_url, certificate, cert_file)) %}
{%- do part_list.append(cert_title) %}
{%- do slave_parameter_dict.__setitem__("ssl_crt", cert_file) %}
[{{cert_title}}]
< = jinja2-template-base
template = {{ empty_template }}
rendered = {{ cert_file }}
cert-content = {{ dumps(slave_instance.get('ssl_crt') + '\n' + slave_instance.get('ssl_ca_crt', '') + '\n' + slave_instance.get('ssl_key')) }}
extra-context =
key content :cert-content
{%- else %}
{%- do kedifa_updater_mapping.append((key_download_url, certificate, master_certificate)) %}
{%- endif %}
{#- BBB: SlapOS Master non-zero knowledge END #}
{#- ########################################## #}
{#- Set Slave Configuration #}
[{{ slave_configuration_section_name }}]
certificate = {{ certificate }}
https_port = {{ dumps('' ~ https_port) }}
http_port = {{ dumps('' ~ http_port) }}
local_ipv4 = {{ dumps('' ~ local_ipv4) }}
{%- for key, value in slave_instance.iteritems() %}
{%- if value is not none %}
{{ key }} = {{ dumps('' ~ value) }}
{%- endif %}
{%- endfor %}
[{{ slave_section_title }}]
< = jinja2-template-base
rendered = {{ caddy_configuration_directory }}/${:filename}
template = {{ template_default_slave_configuration }}
extra-context =
section slave_parameter {{ slave_configuration_section_name }}
import urllib_module urllib
filename = {{ '%s.conf' % slave_reference }}
{{ '\n' }}
{%- set monitor_ipv6_test = slave_instance.get('monitor-ipv6-test', '') %}
{%- if monitor_ipv6_test %}
{%- set monitor_ipv6_section_title = 'check-%s-ipv6-packet-list-test' % slave_instance.get('slave_reference') %}
{%- do part_list.append(monitor_ipv6_section_title) %}
[{{ monitor_ipv6_section_title }}]
<= monitor-promise-base
module = check_icmp_packet_lost
name = {{ monitor_ipv6_section_title }}.py
config-address = {{ dumps(monitor_ipv6_test) }}
# promise frequency in minutes (2 times/day)
config-frequency = 720
{%- endif %}
{%- set monitor_ipv4_test = slave_instance.get('monitor-ipv4-test', '') %}
{%- if monitor_ipv4_test %}
{%- set monitor_ipv4_section_title = 'check-%s-ipv4-packet-list-test' % slave_instance.get('slave_reference') %}
{%- do part_list.append(monitor_ipv4_section_title) %}
[{{ monitor_ipv4_section_title }}]
<= monitor-promise-base
module = check_icmp_packet_lost
name = {{ monitor_ipv4_section_title }}.py
config-address = {{ dumps(monitor_ipv4_test) }}
config-ipv4 = true
# promise frequency in minutes (2 times/day)
config-frequency = 720
{%- endif %}
{#- ############################### #}
{#- Publish Slave Information #}
{%- if not extra_slave_instance_list %}
{%- set publish_section_title = 'publish-%s-connection-information' % slave_instance.get('slave_reference') %}
{%- do part_list.append(publish_section_title) %}
[{{ publish_section_title }}]
recipe = slapos.cookbook:publish
{%- for key, value in slave_publish_dict.iteritems() %}
{{ key }} = {{ value }}
{%- endfor %}
{%- else %}
{%- do slave_instance_information_list.append(slave_publish_dict) %}
{%- endif %}
{%- if slave_type != 'redirect' %}
{%- do backend_slave_list.append(slave_instance) %}
{%- endif %}
{%- endfor %} {# Slave iteration ends for slave_instance in slave_instance_list #}
[slave-log-directories]
<= slave-log-directory-dict
recipe = slapos.cookbook:mkdirectory
{%- do part_list.append('slave-log-directories') %}
{%- do part_list.append('caddy-log-access') %}
{#- ############################################## #}
{#- ## Prepare virtualhost for slaves using cache #}
{#- Define IPv6 to IPV4 tunneling #}
[tunnel-6to4-base]
recipe = slapos.cookbook:wrapper
ipv4 = ${slap-network-information:local-ipv4}
ipv6 = ${slap-network-information:global-ipv6}
wrapper-path = {{ directory['service'] }}/6tunnel-${:ipv6-port}
command-line = {{ sixtunnel_executable }} -6 -4 -d -l ${:ipv6} ${:ipv6-port} ${:ipv4} ${:ipv4-port}
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
[tunnel-6to4-base-http_port]
<= tunnel-6to4-base
ipv4-port = {{ http_port }}
ipv6-port = {{ http_port }}
[tunnel-6to4-base-https_port]
<= tunnel-6to4-base
ipv4-port = {{ https_port }}
ipv6-port = {{ https_port }}
{#- Define log access #}
[caddy-log-access-parameters]
caddy_log_directory = {{ dumps(caddy_log_directory) }}
caddy_configuration_directory = {{ dumps(caddy_configuration_directory) }}
local_ipv4 = {{ dumps(local_ipv4) }}
global_ipv6 = {{ dumps(global_ipv6) }}
https_port = {{ dumps(https_port) }}
http_port = {{ dumps(http_port) }}
ip_access_certificate = {{ frontend_configuration.get('ip-access-certificate') }}
access_log = {{ dumps(access_log) }}
error_log = {{ dumps(error_log) }}
not_found_file = {{ dumps(not_found_file) }}
[caddy-log-access]
< = jinja2-template-base
template = {{frontend_configuration.get('template-log-access')}}
rendered = {{frontend_configuration.get('log-access-configuration')}}
extra-context =
section slave_log_directory slave-log-directory-dict
section slave_password slave-password
section parameter_dict caddy-log-access-parameters
{#- Publish information for the instance #}
[publish-caddy-information]
recipe = slapos.cookbook:publish.serialised
public-ipv4 = {{ public_ipv4 }}
private-ipv4 = {{ local_ipv4 }}
{%- if extra_slave_instance_list %}
{#- sort_keys are important in order to avoid shuffling parameters on each run #}
slave-instance-information-list = {{ json_module.dumps(slave_instance_information_list, sort_keys=True) }}
{%- endif %}
monitor-base-url = {{ monitor_base_url }}
csr_id-url = https://[${expose-csr_id-configuration:ip}]:${expose-csr_id-configuration:port}/csr_id.txt
backend-client-csr_id-url = https://[${expose-csr_id-configuration:ip}]:${expose-csr_id-configuration:port}/backend-haproxy-csr_id.txt
csr_id-certificate = ${get-csr_id-certificate:certificate}
[kedifa-updater]
recipe = slapos.cookbook:wrapper
command-line = {{ kedifa_configuration['kedifa-updater'] }}
--server-ca-certificate {{ kedifa_configuration['ca-certificate'] }}
--identity {{ kedifa_configuration['certificate'] }}
--master-certificate {{ master_certificate }}
--on-update "{{ frontend_graceful_reload }}"
${kedifa-updater-mapping:file}
{{ kedifa_configuration['kedifa-updater-state-file'] }}
wrapper-path = {{ directory['service'] }}/kedifa-updater
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
[kedifa-updater-run]
recipe = plone.recipe.command
stop-on-error = True
command = {{ kedifa_configuration['kedifa-updater'] }} --prepare-only ${kedifa-updater-mapping:file} --on-update "{{ frontend_graceful_reload }}"
update-command = ${:command}
[kedifa-updater-mapping]
recipe = slapos.recipe.template:jinja2
file = {{ kedifa_configuration['kedifa-updater-mapping-file'] }}
template = inline:
{%- for mapping in kedifa_updater_mapping %}
{{ mapping[0] }} {{ mapping[1] }} {{ mapping[2] }}
{%- endfor %}
rendered = ${:file}
[caddy-log-access-empty]
# Caddy refuse to start if an `import`ed file is empty, so we prepend a header
# so that the file is never empty.
< = jinja2-template-base
template = inline: # This file contain directives to serve directories with log files for shared instances, but no shared instances are defined yet.
rendered = {{frontend_configuration.get('log-access-configuration')}}
##
[backend-haproxy-configuration]
< = jinja2-template-base
template = {{ template_backend_haproxy_configuration }}
rendered = ${backend-haproxy-config:file}
backend_slave_list = {{ dumps(sorted(backend_slave_list)) }}
extra-context =
key backend_slave_list :backend_slave_list
section configuration backend-haproxy-config
[backend-haproxy-config]
file = {{ backend_haproxy_configuration['file'] }}
pid-file = {{ backend_haproxy_configuration['pid-file'] }}
log-socket = {{ backend_haproxy_configuration['log-socket'] }}
local-ipv4 = {{ dumps('' ~ local_ipv4) }}
http-port = {{ ('' ~ backend_haproxy_configuration['http-port']) }}
https-port = {{ ('' ~ backend_haproxy_configuration['https-port']) }}
request-timeout = {{ dumps('' ~ configuration['request-timeout']) }}
backend-connect-timeout = {{ dumps('' ~ configuration['backend-connect-timeout']) }}
backend-connect-retries = {{ dumps('' ~ configuration['backend-connect-retries']) }}
certificate = {{ dumps('' ~ backend_haproxy_configuration['certificate']) }}
[store-backend-haproxy-csr_id]
recipe = plone.recipe.command
csr_id_path = {{ directory['csr_id'] }}/backend-haproxy-csr_id.txt
csr_work_path = {{ directory['tmp'] }}/${:_buildout_section_name_}
stop-on-error = False
update-command = ${:command}
command =
{{ bin_directory }}/caucase \
--ca-url {{ backend_haproxy_configuration['caucase-url'] }} \
--ca-crt {{ backend_haproxy_configuration['cas-ca-certificate'] }} \
--crl {{ backend_haproxy_configuration['crl'] }} \
--mode service \
--send-csr {{ backend_haproxy_configuration['csr'] }} > ${:csr_work_path} && \
cut -d ' ' -f 1 ${:csr_work_path} > ${:csr_id_path}
##
[buildout]
extends =
{{ common_profile }}
{{ logrotate_base_instance }}
{{ monitor_template }}
parts +=
kedifa-updater
kedifa-updater-run
backend-haproxy-configuration
{%- for part in part_list %}
{{ ' %s' % part }}
{%- endfor %}
{%- if 'caddy-log-access' not in part_list %}
caddy-log-access-empty
{%- endif %}
publish-caddy-information
tunnel-6to4-base-http_port
tunnel-6to4-base-https_port
expose-csr_id
promise-expose-csr_id-ip-port
cache-access = {{ cache_access }}
[store-csr_id]
recipe = plone.recipe.command
csr_id_path = {{ directory['csr_id'] }}/csr_id.txt
csr_work_path = {{ directory['tmp'] }}/${:_buildout_section_name_}
stop-on-error = False
update-command = ${:command}
command =
{{ bin_directory }}/caucase \
--ca-url {{ kedifa_configuration['caucase-url'] }} \
--ca-crt {{ kedifa_configuration['cas-ca-certificate'] }} \
--crl {{ kedifa_configuration['crl'] }} \
--mode service \
--send-csr {{ kedifa_configuration['csr'] }} > ${:csr_work_path} && \
cut -d ' ' -f 1 ${:csr_work_path} > ${:csr_id_path}
[certificate-csr_id]
recipe = plone.recipe.command
certificate = {{ directory['caddy-csr_id'] }}/certificate.pem
key = {{ directory['caddy-csr_id'] }}/key.pem
stop-on-error = True
update-command = ${:command}
command =
if ! [ -f ${:key} ] && ! [ -f ${:certificate} ] ; then
openssl req -new -newkey rsa:2048 -sha256 -subj \
"/O={{ expose_csr_id_organization }}/OU={{ expose_csr_id_organizational_unit }}/CN=${slap-network-information:global-ipv6}" \
-days 5 -nodes -x509 -keyout ${:key} -out ${:certificate}
fi
[expose-csr_id-configuration]
ip = ${slap-network-information:global-ipv6}
port = 17001
key = ${certificate-csr_id:key}
certificate = ${certificate-csr_id:certificate}
error-log = {{ directory['caddy-csr_id-log'] }}/expose-csr_id.log
[expose-csr_id-template]
recipe = slapos.recipe.template:jinja2
template = inline:
https://:${expose-csr_id-configuration:port}/ {
bind ${expose-csr_id-configuration:ip}
tls ${expose-csr_id-configuration:certificate} ${expose-csr_id-configuration:key}
log ${expose-csr_id-configuration:error-log}
}
rendered = {{ directory['caddy-csr_id'] }}/Caddyfile
[promise-expose-csr_id-ip-port]
<= monitor-promise-base
module = check_port_listening
name = expose-csr_id-ip-port-listening.py
config-hostname = ${expose-csr_id-configuration:ip}
config-port = ${expose-csr_id-configuration:port}
[expose-csr_id]
depends =
${store-csr_id:command}
${store-backend-haproxy-csr_id:command}
recipe = slapos.cookbook:wrapper
command-line = {{ caddy_executable }}
-conf ${expose-csr_id-template:rendered}
-log ${expose-csr_id-configuration:error-log}
-http2=true
-disable-http-challenge
-disable-tls-alpn-challenge
-root {{ directory['csr_id'] }}
wrapper-path = {{ directory['service'] }}/expose-csr_id
hash-existing-files = ${buildout:directory}/software_release/buildout.cfg
[get-csr_id-certificate]
recipe = collective.recipe.shelloutput
commands =
certificate = cat ${certificate-csr_id:certificate}
{%- endif %} {# if software_type == slap_software_type #}
apache-lazy-script-call.sh.in 0000664 0000000 0000000 00000000566 13723117434 0041001 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates #!/bin/bash
PID=$$
PIDFILE={{ pid_file }}
sleep $((RANDOM % 10))
if [ ! -f $PIDFILE ]; then
echo $PID > $PIDFILE
sleep {{ wait_time }}
{{ lazy_command }}
rm -f $PIDFILE
else
ps --pid `cat $PIDFILE` &>/dev/null
if [ $? -eq 0 ]; then
echo "Skipped"
else
echo $PID > $PIDFILE
sleep {{ wait_time }}
{{ lazy_command }}
rm -f $PIDFILE
fi
fi
backend-haproxy-rsyslogd.conf.in 0000664 0000000 0000000 00000002156 13723117434 0041623 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates module(
load="imuxsock"
SysSock.Name="{{ configuration['log-socket'] }}")
# Just simply output the raw line without any additional information, as
# haproxy emits enough information by itself
# Also cut out first empty space in msg, which is related to rsyslogd
# internal and end up cutting on 8k, as it's default of $MaxMessageSize
template(name="rawoutput" type="string" string="%msg:2:8192%\n")
$ActionFileDefaultTemplate rawoutput
$FileCreateMode 0600
$DirCreateMode 0700
$Umask 0022
$WorkDirectory {{ configuration['spool-directory'] }}
# Setup logging per slave, by extracting the slave name from the log stream
{%- set regex = ".*-backend (.*)-http.*" %}
template(name="extract_slave_name" type="string" string="%msg:R,ERE,1,FIELD:{{ regex }}--end%")
set $!slave_name = exec_template("extract_slave_name");
template(name="slave_output" type="string" string="{{ configuration['caddy-log-directory'] }}/%$!slave_name%_backend_log")
if (re_match($msg, "{{ regex }}")) then {
action(type="omfile" dynaFile="slave_output")
stop
}
{#- emit all not catched messages to full log file #}
*.* {{ configuration['log-file'] }}
backend-haproxy.cfg.in 0000664 0000000 0000000 00000006601 13723117434 0037570 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates global
pidfile {{ configuration['pid-file'] }}
# master-worker is compatible with foreground with process management
master-worker
log {{ configuration['log-socket'] }} local0
defaults
log global
mode http
option httplog
timeout queue 60s
timeout server {{ configuration['request-timeout'] }}s
timeout client {{ configuration['request-timeout'] }}s
timeout connect {{ configuration['backend-connect-timeout'] }}s
retries {{ configuration['backend-connect-retries'] }}
{%- macro frontend_entry(slave_instance, scheme) %}
{%- set host_list = (slave_instance.get('server-alias') or '').split() %}
{%- if slave_instance.get('custom_domain') not in host_list %}
{%- do host_list.append(slave_instance.get('custom_domain')) %}
{%- endif %}
{%- for host in host_list %}
{%- if host.startswith('*.') %}
{#- hdr_sub has to be used, as anyway something.example.com shall match *.example.com[:port], with optional port #}
acl is_{{ slave_instance['slave_reference'] }} hdr_sub(host) -i {{ host[2:] }}
{%- else %}
acl is_{{ slave_instance['slave_reference'] }} hdr_dom(host) -i {{ host }}
{%- endif %}
{%- endfor %}
use_backend {{ slave_instance['slave_reference'] }}-{{ scheme }} if is_{{ slave_instance['slave_reference'] }}
{%- endmacro %}
frontend http-backend
bind {{ configuration['local-ipv4'] }}:{{ configuration['http-port'] }}
{%- for slave_instance in backend_slave_list %}
{{ frontend_entry(slave_instance, 'http') }}
{%- endfor %}
frontend https-backend
bind {{ configuration['local-ipv4'] }}:{{ configuration['https-port'] }}
{%- for slave_instance in backend_slave_list %}
{{ frontend_entry(slave_instance, 'https') }}
{%- endfor %}
{%- for slave_instance in backend_slave_list %}
{%- for (scheme, prefix) in [('http', 'http_backend'), ('https', 'https_backend')] %}
{%- set info_dict = slave_instance[prefix] %}
{%- if info_dict['scheme'] == 'https' %}
{%- set ssl = [] %}
{%- if slave_instance['authenticate-to-backend'] %}
{%- set ssl = ['crt %s' % (configuration['certificate'],)] %}
{%- endif %}
{%- do ssl.append('ssl verify') %}
{%- set path_to_ssl_proxy_ca_crt = slave_instance.get('path_to_ssl_proxy_ca_crt') %}
{%- if slave_instance['ssl_proxy_verify'] %}
{%- if path_to_ssl_proxy_ca_crt %}
{%- do ssl.append('required ca-file %s' % (path_to_ssl_proxy_ca_crt,)) %}
{%- else %}
{#- Backend SSL shall be verified, but not CA provided, disallow connection #}
{#- Simply dropping hostname from the dict will result with ignoring it... #}
{%- do info_dict.__setitem__('hostname', '') %}
{%- endif %}
{%- else %}
{%- do ssl.append('none') %}
{%- endif %}
{%- set ssl = ' '.join(ssl) %}
{%- else %}
{%- set ssl = '' %}
{%- endif %}
backend {{ slave_instance['slave_reference'] }}-{{ scheme }}
{%- set hostname = info_dict['hostname'] %}
{%- set port = info_dict['port'] %}
{%- set path = info_dict['path'].rstrip('/') %}
{%- if hostname and port %}
timeout server {{ slave_instance['request-timeout'] }}s
timeout connect {{ slave_instance['backend-connect-timeout'] }}s
retries {{ slave_instance['backend-connect-retries'] }}
server backend {{ hostname }}:{{ port }} {{ ssl }}
{%- if path %}
http-request set-path {{ path }}%[path]
{%- endif %}
{%- endif %}
{%- endfor %}
{%- endfor %}
caddy-backend-url-validator.in 0000664 0000000 0000000 00000000235 13723117434 0041204 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates #!${dash:location}/bin/dash
config="https://example.com {\n proxy / $1 {\n }\n}"
echo -e $config | ${caddy:output} -conf stdin -validate > /dev/null 2>&1
configuration-state-script.sh.in 0000664 0000000 0000000 00000000745 13723117434 0041656 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates #!/bin/sh
set -e
SIGNATURE_FILE={{ signature_file }}
NSIGNATURE_FILE={{ signature_file }}.tmp
touch $SIGNATURE_FILE
{{ sha256sum }} {{ path_list }} 2> /dev/null | sort -k 66 > $NSIGNATURE_FILE
if diff "$SIGNATURE_FILE" "$NSIGNATURE_FILE" > /dev/null ; then
# No changes since last run just propagate information
rm -f ${NSIGNATURE_FILE}
exit 1
else
# Changes since last run, so store new value and propagate information
mv "$NSIGNATURE_FILE" "$SIGNATURE_FILE"
exit 0
fi
default-virtualhost.conf.in 0000664 0000000 0000000 00000023561 13723117434 0040711 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates {%- set TRUE_VALUES = ['y', 'yes', '1', 'true'] %}
{%- set enable_cache = slave_parameter.get('enable_cache', '').lower() in TRUE_VALUES %}
{%- set disable_no_cache_header = slave_parameter.get('disable-no-cache-request', '').lower() in TRUE_VALUES %}
{%- set disable_via_header = slave_parameter.get('disable-via-header', '').lower() in TRUE_VALUES %}
{%- set prefer_gzip = slave_parameter.get('prefer-gzip-encoding-to-backend', '').lower() in TRUE_VALUES %}
{%- set proxy_append_list = [('', 'Default proxy configuration')] %}
{%- if prefer_gzip %}
{%- do proxy_append_list.append(('prefer-gzip', 'Proxy which always overrides Accept-Encoding to gzip if such is found')) %}
{%- endif %} {#- if prefer_gzip #}
{%- set server_alias_list = slave_parameter.get('server-alias', '').split() %}
{%- set enable_h2 = slave_parameter['global_disable_http2'].lower() not in TRUE_VALUES and slave_parameter.get('enable-http2', slave_parameter['enable_http2_by_default']).lower() in TRUE_VALUES %}
{%- set disabled_cookie_list = slave_parameter.get('disabled-cookie-list', '').split() %}
{%- set https_only = slave_parameter.get('https-only', 'true').lower() in TRUE_VALUES %}
{%- set slave_type = slave_parameter.get('type', '') %}
{%- set host_list = server_alias_list %}
{%- set cipher_list = slave_parameter.get('cipher_list', '').strip() %}
{%- if slave_parameter.get('custom_domain') not in host_list %}
{%- do host_list.append(slave_parameter.get('custom_domain')) %}
{%- endif %}
{%- set http_host_list = [] %}
{%- set https_host_list = [] %}
{%- for host in host_list %}
{%- do http_host_list.append('http://%s:%s' % (host, slave_parameter['http_port'] )) %}
{%- do https_host_list.append('https://%s:%s' % (host, slave_parameter['https_port'] )) %}
{%- endfor %} {#- for host in host_list #}
{%- set default_path = slave_parameter.get('default-path', '').strip('/') | urlencode %}
{%- set websocket_path_list = [] %}
{%- for websocket_path in slave_parameter.get('websocket-path-list', '').split() %}
{%- set websocket_path = websocket_path.strip('/') %}
{#- Unquote the path, so %20 and similar can be represented correctly #}
{%- set websocket_path = urllib_module.unquote(websocket_path.strip()) %}
{%- if websocket_path %}
{%- do websocket_path_list.append(websocket_path) %}
{%- endif %}
{%- endfor %}
{%- set websocket_transparent = slave_parameter.get('websocket-transparent', 'true').lower() in TRUE_VALUES %}
{%- if slave_type in ['notebook', 'websocket'] %}
{# websocket style needs http 1.1 max #}
{%- set enable_h2 = False %}
{%- endif %}
{%- macro proxy_header() %}
timeout {{ slave_parameter['request-timeout'] }}s
# force reset of X-Forwarded-For
header_upstream X-Forwarded-For {remote}
{%- endmacro %} {# proxy_header #}
{%- for tls in [True, False] %}
{%- if tls %}
{%- set backend_url = slave_parameter.get('backend-https-url', slave_parameter.get('backend-http-url')) %}
# SSL enabled hosts
{{ https_host_list|join(', ') }} {
{%- else %}
{%- set backend_url = slave_parameter['backend-http-url'] %}
# SSL-disabled hosts
{{ http_host_list|join(', ') }} {
{%- endif %}
bind {{ slave_parameter['local_ipv4'] }}
{%- if tls %}
tls {{ slave_parameter['certificate'] }} {{ slave_parameter['certificate'] }} {
{%- if cipher_list %}
ciphers {{ cipher_list }}
{%- endif %}
{%- if enable_h2 %}
# Allow HTTP2
alpn h2 http/1.1
{%- else %} {#- if enable_h2 #}
# Disallow HTTP2
alpn http/1.1
{%- endif %} {#- if enable_h2 #}
} {# tls #}
{%- endif %} {#- if tls #}
log / {{ slave_parameter.get('access_log') }} "{remote} - {>REMOTE_USER} [{when}] \"{method} {uri} {proto}\" {status} {size} \"{>Referer}\" \"{>User-Agent}\" {latency_ms}" {
rotate_size 0
}
errors {{ slave_parameter.get('error_log') }} {
rotate_size 0
}
{%- if not (slave_type == 'zope' and backend_url) %}
{% if prefer_gzip and not (not tls and https_only) %}
rewrite {
regexp (.*)
if {>Accept-Encoding} match "(^gzip,.*|.*, gzip,.*|.*, gzip$|^gzip$)"
to /prefer-gzip{1}
}
rewrite {
regexp (.*)
if {>Accept-Encoding} not_match "(^gzip,.*|.*, gzip,.*|.*, gzip$|^gzip$)"
to {1}
}
{% elif slave_type not in ['notebook', 'websocket'] %}
rewrite {
regexp (.*)
to {1}
}
{% endif %} {# elif slave_type != 'notebook' #}
{%- endif %} {#- if not (slave_type == 'zope' and backend_url) #}
{%- if not tls and https_only %}
# Enforced redirection to SSL-enabled host
redir 302 {
/ https://{host}{rewrite_uri}
}
{%- elif slave_type == 'zope' and backend_url %}
# Zope configuration
{%- for (proxy_name, proxy_comment) in proxy_append_list %}
# {{ proxy_comment }}
proxy "/{{ proxy_name }}" {{ backend_url }} {
{{ proxy_header() }}
{%- if proxy_name == 'prefer-gzip' %}
without /prefer-gzip
header_upstream Accept-Encoding gzip
{%- endif %} {#- if proxy_name == 'prefer-gzip' #}
{%- for disabled_cookie in disabled_cookie_list %}
# Remove cookie {{ disabled_cookie }} from client Cookies
header_upstream Cookie "(.*)(^{{ disabled_cookie }}=[^;]*; |; {{ disabled_cookie }}=[^;]*|^{{ disabled_cookie }}=[^;]*$)(.*)" "$1 $3"
{%- endfor %} {#- for disabled_cookie in disabled_cookie_list #}
{%- if disable_via_header %}
header_downstream -Via
{%- endif %} {#- if disable_via_header #}
{%- if disable_no_cache_header %}
header_upstream -Cache-Control
header_upstream -Pragma
{%- endif %} {#- if disable_no_cache_header #}
transparent
} {# proxy #}
{%- endfor %} {#- for (proxy_name, proxy_comment) in proxy_append_list #}
{%- if default_path %}
redir 301 {
if {path} is /
/ {scheme}://{host}/{{ default_path }}
} {# redir #}
{%- endif %} {#- if default_path #}
{%- if prefer_gzip and not (not tls and https_only) %}
rewrite {
regexp (.*)
if {>Accept-Encoding} match "(^gzip,.*|.*, gzip,.*|.*, gzip$|^gzip$)"
{%- if tls %}
to /prefer-gzip/VirtualHostBase/{scheme}%2F%2F{hostonly}:{{ slave_parameter.get('virtualhostroot-https-port', '443') | int }}%2F{{ slave_parameter.get('path', '').strip('/') }}%2FVirtualHostRoot/{1}
{%- else %}
to /prefer-gzip/VirtualHostBase/{scheme}%2F%2F{hostonly}:{{ slave_parameter.get('virtualhostroot-http-port', '80') | int }}%2F{{ slave_parameter.get('path', '').strip('/') }}%2FVirtualHostRoot/{1}
{%- endif %}
}
rewrite {
regexp (.*)
if {>Accept-Encoding} not_match "(^gzip,.*|.*, gzip,.*|.*, gzip$|^gzip$)"
{%- if tls %}
to /VirtualHostBase/{scheme}%2F%2F{hostonly}:{{ slave_parameter.get('virtualhostroot-https-port', '443') | int }}%2F{{ slave_parameter.get('path', '').strip('/') }}%2FVirtualHostRoot/{1}
{%- else %}
to /VirtualHostBase/{scheme}%2F%2F{hostonly}:{{ slave_parameter.get('virtualhostroot-http-port', '80') | int }}%2F{{ slave_parameter.get('path', '').strip('/') }}%2FVirtualHostRoot/{1}
{%- endif %}
}
{%- else %}
rewrite {
regexp (.*)
{%- if tls %}
to /VirtualHostBase/{scheme}%2F%2F{hostonly}:{{ slave_parameter.get('virtualhostroot-https-port', '443') | int }}%2F{{ slave_parameter.get('path', '').strip('/') }}%2FVirtualHostRoot/{1}
{%- else %}
to /VirtualHostBase/{scheme}%2F%2F{hostonly}:{{ slave_parameter.get('virtualhostroot-http-port', '80') | int }}%2F{{ slave_parameter.get('path', '').strip('/') }}%2FVirtualHostRoot/{1}
{%- endif %}
} {# rewrite #}
{%- endif %} {#- if prefer_gzip #}
{%- elif slave_type == 'redirect' %}
{%- if backend_url %}
# Redirect configuration
redir 302 {
/ {{ backend_url }}{rewrite_uri}
}
{%- endif %}
{%- elif slave_type == 'notebook' %}
proxy / {{ backend_url }} {
{{ proxy_header() }}
transparent
}
rewrite {
regexp "/(api/kernels/[^/]+/(channels|iopub|shell|stdin)|terminals/websocket)/?"
to /proxy/{1}
}
proxy /proxy/ {{ backend_url }} {
{{ proxy_header() }}
transparent
websocket
without /proxy/
}
{%- elif slave_type == 'websocket' %}
{%- if websocket_path_list %}
proxy / {{ backend_url }} {
{{ proxy_header() }}
{%- if websocket_transparent %}
transparent
{%- else %}
header_upstream Host {host}
{%- endif %}
}
{%- for websocket_path in websocket_path_list %}
proxy "/{{ websocket_path }}" {{ backend_url }} {
{{ proxy_header() }}
websocket
{%- if websocket_transparent %}
transparent
{%- else %}
header_upstream Host {host}
{%- endif %}
}
{%- endfor %}
{%- else %}
proxy / {{ backend_url }} {
{{ proxy_header() }}
websocket
{%- if websocket_transparent %}
transparent
{%- else %}
header_upstream Host {host}
{%- endif %}
}
{%- endif %}
{%- else %} {#- if slave_type == 'zope' and backend_url #}
# Default configuration
{%- if default_path %}
redir 301 {
if {path} is /
/ {scheme}://{host}/{{ default_path }}
} {# redir #}
{%- endif %} {#- if default_path #}
{%- if backend_url %}
{%- for (proxy_name, proxy_comment) in proxy_append_list %}
# {{ proxy_comment }}
proxy "/{{ proxy_name }}" {{ backend_url }} {
{{ proxy_header() }}
{%- if proxy_name == 'prefer-gzip' %}
without /prefer-gzip
header_upstream Accept-Encoding gzip
{%- endif %} {#- if proxy_name == 'prefer-gzip' #}
{%- for disabled_cookie in disabled_cookie_list %}
# Remove cookie {{ disabled_cookie }} from client Cookies
header_upstream Cookie "(.*)(^{{ disabled_cookie }}=[^;]*; |; {{ disabled_cookie }}=[^;]*|^{{ disabled_cookie }}=[^;]*$)(.*)" "$1 $3"
{%- endfor %} {#- for disabled_cookie in disabled_cookie_list #}
{%- if disable_via_header %}
header_downstream -Via
{%- endif %} {#- if disable_via_header #}
{%- if disable_no_cache_header %}
header_upstream -Cache-Control
header_upstream -Pragma
{%- endif %} {#- if disable_no_cache_header #}
transparent
} {# proxy #}
{%- endfor %} {#- for (proxy_name, proxy_comment) in proxy_append_list #}
{%- endif %} {#- if backend_url #}
{%- endif %} {#- if slave_type == 'zope' and backend_url #}
} {# https_host_list|join(', ') #}
{%- endfor %} {#- for tls in [True, False] #}
empty.in 0000664 0000000 0000000 00000000016 13723117434 0035103 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates {{ content }}
graceful-script.sh.in 0000664 0000000 0000000 00000000262 13723117434 0037453 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates #!/bin/sh
set -e
if {{ caddy_configuration_state }} ; then
echo "Reloading.."
{{ graceful_reload_command }}
else
echo "Nothing changed, so nothing to reload"
exit 0
fi
nginx-eventsource-slave.conf.in 0000664 0000000 0000000 00000010771 13723117434 0041475 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates {% set url = slave_parameter.get('url') %}
{% set https_url = slave_parameter.get('https-url', url) %}
{% if url.startswith("http://") or url.startswith("https://") %}
{% set upstream = url.split("/")[2] %}
{% set https_upstream = https_url.split("/")[2] %}
{% set protocol = url.split("/")[0] %}
{% set https_protocol = https_url.split("/")[0] %}
{% set proxy_pass = '%s//%s' % (protocol, slave_parameter.get('slave_reference')) %}
{% set https_proxy_pass = '%s//https_%s' % (protocol, slave_parameter.get('slave_reference')) %}
# TODO-Caddy upstream {{ slave_parameter.get('slave_reference') }} {
# TODO-Caddy server {{ upstream }};
# TODO-Caddy
# TODO-Caddy pstream https_{{ slave_parameter.get('slave_reference') }} {
# TODO-Caddy server {{ https_upstream }};
# TODO-Caddy
# TODO-Caddy server {
# TODO-Caddy listen {{ slave_parameter['local_ipv4'] }}:{{ slave_parameter['nginx_http_port'] }};
# TODO-Caddy
# TODO-Caddy server_name {{ slave_parameter.get('custom_domain') }};
# TODO-Caddy
# TODO-Caddy error_log {{ slave_parameter.get('error_log') }} error;
# TODO-Caddy access_log {{ slave_parameter.get('access_log') }} custom;
# TODO-Caddy
# TODO-Caddy location /pub {
# TODO-Caddy push_stream_publisher;
# TODO-Caddy push_stream_channels_path $arg_id;
# TODO-Caddy # store messages in memory
# TODO-Caddy push_stream_store_messages off;
# TODO-Caddy
# TODO-Caddy # Message size limit
# TODO-Caddy # client_max_body_size MUST be equal to client_body_buffer_size or
# TODO-Caddy # you will be sorry.
# TODO-Caddy client_max_body_size 16k;
# TODO-Caddy client_body_buffer_size 16k;
# TODO-Caddy
# TODO-Caddy }
# TODO-Caddy
# TODO-Caddy location ~ /sub/(.*) {
# TODO-Caddy # activate subscriber mode for this location
# TODO-Caddy add_header "Access-Control-Allow-Origin" "*";
# TODO-Caddy add_header 'Access-Control-Allow-Credentials' 'false';
# TODO-Caddy add_header 'Access-Control-Allow-Methods' 'GET, HEAD, OPTIONS';
# TODO-Caddy add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since';
# TODO-Caddy
# TODO-Caddy push_stream_subscriber eventsource;
# TODO-Caddy # positional channel path
# TODO-Caddy push_stream_channels_path $1;
# TODO-Caddy
# TODO-Caddy # content-type
# TODO-Caddy default_type "text/event-stream; charset=utf-8";
# TODO-Caddy }
# TODO-Caddy
# TODO-Caddy
# TODO-Caddy server {
# TODO-Caddy listen {{ slave_parameter['local_ipv4'] }}:{{ slave_parameter['nginx_https_port'] }} ssl;
# TODO-Caddy
# TODO-Caddy server_name {{ slave_parameter.get('custom_domain') }};
# TODO-Caddy
# TODO-Caddy error_log {{ slave_parameter.get('error_log') }} error;
# TODO-Caddy access_log {{ slave_parameter.get('access_log') }} custom;
# TODO-Caddy
# TODO-Caddy ssl on;
# TODO-Caddy
# TODO-Caddy ssl_session_timeout 5m;
# TODO-Caddy ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# TODO-Caddy ssl_ciphers 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:HIGH:!aNULL:!MD5';
# TODO-Caddy ssl_prefer_server_ciphers on;
# TODO-Caddy ssl_session_cache shared:SSL:10m;
# TODO-Caddy location /pub {
# TODO-Caddy push_stream_publisher;
# TODO-Caddy push_stream_channels_path $arg_id;
# TODO-Caddy # store messages in memory
# TODO-Caddy push_stream_store_messages off;
# TODO-Caddy
# TODO-Caddy # Message size limit
# TODO-Caddy # client_max_body_size MUST be equal to client_body_buffer_size or
# TODO-Caddy # you will be sorry.
# TODO-Caddy client_max_body_size 16k;
# TODO-Caddy client_body_buffer_size 16k;
# TODO-Caddy
# TODO-Caddy }
# TODO-Caddy
# TODO-Caddy location ~ /sub/(.*) {
# TODO-Caddy # activate subscriber mode for this location
# TODO-Caddy add_header "Access-Control-Allow-Origin" "*";
# TODO-Caddy add_header 'Access-Control-Allow-Credentials' 'false';
# TODO-Caddy add_header 'Access-Control-Allow-Methods' 'GET, HEAD, OPTIONS';
# TODO-Caddy add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since';
# TODO-Caddy
# TODO-Caddy push_stream_subscriber eventsource;
# TODO-Caddy # positional channel path
# TODO-Caddy push_stream_channels_path $1;
# TODO-Caddy
# TODO-Caddy # content-type
# TODO-Caddy default_type "text/event-stream; charset=utf-8";
# TODO-Caddy }
# TODO-Caddy}
{% endif %}
notfound.html 0000664 0000000 0000000 00000000327 13723117434 0036144 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates
Instance not found
This instance has not been found.
If this error persists, please check your instance URL and status on SlapOS Master.
replicate-publish-slave-information.cfg.in 0000664 0000000 0000000 00000007231 13723117434 0043560 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates {% set part_list = [] %}
{% set slave_information_dict = {} %}
# regroup slave information from all frontends
{% for frontend, slave_list_raw in slave_information.iteritems() %}
{% if slave_list_raw %}
{% set slave_list = json_module.loads(slave_list_raw) %}
{% else %}
{% set slave_list = [] %}
{% endif %}
{% for slave_dict in slave_list %}
{% set slave_reference = slave_dict.pop('slave-reference') %}
{% set log_access_url = slave_dict.pop('log-access', '') %}
{% set current_slave_dict = slave_information_dict.get(slave_reference, {}) %}
{% do current_slave_dict.update(slave_dict) %}
{% set log_access_list = current_slave_dict.get('log-access-urls', []) %}
{% do log_access_list.append( frontend + ': ' + log_access_url) %}
{% do current_slave_dict.__setitem__(
'log-access-urls',
log_access_list
) %}
{% do current_slave_dict.__setitem__(
'replication_number',
current_slave_dict.get('replication_number', 0) + 1
) %}
{% do slave_information_dict.__setitem__(slave_reference, current_slave_dict) %}
{% endfor %}
{% endfor %}
{% for slave_reference, rejected_info_list in rejected_slave_information.iteritems() %}
{% if slave_reference not in slave_information_dict %}
{% do slave_information_dict.__setitem__(slave_reference, {}) %}
{% endif %}
{% do slave_information_dict[slave_reference].__setitem__('request-error-list', rejected_info_list) %}
{% endfor %}
{% for slave_reference, warning_info_list in warning_slave_information.iteritems() %}
{% if slave_reference not in slave_information_dict %}
{% do slave_information_dict.__setitem__(slave_reference, {}) %}
{% endif %}
{% do slave_information_dict[slave_reference].__setitem__('warning-list', warning_info_list) %}
{% endfor %}
{% for slave_reference, kedifa_dict in json_module.loads(slave_kedifa_information).iteritems() %}
{% if slave_reference not in rejected_slave_information %}
{% if slave_reference not in slave_information_dict %}
{% do slave_information_dict.__setitem__(slave_reference, {}) %}
{% endif %}
{% do slave_information_dict[slave_reference].__setitem__('key-generate-auth-url', kedifa_dict['key-generate-auth-url']) %}
{% do slave_information_dict[slave_reference].__setitem__('key-upload-url', kedifa_dict['key-upload-url']) %}
{% do slave_information_dict[slave_reference].__setitem__('kedifa-caucase-url', kedifa_dict['kedifa-caucase-url']) %}
{% endif %}
{% endfor %}
# Publish information for each slave
{% set active_slave_instance_list = json_module.loads(active_slave_instance_dict['active-slave-instance-list']) %}
{% for slave_reference, slave_information in slave_information_dict.iteritems() %}
{# Filter out destroyed, so not existing anymore, slaves #}
{# Note: This functionality is not yet covered by tests, please modify with care #}
{% if slave_reference in active_slave_instance_list %}
{% set publish_section_title = 'publish-%s' % slave_reference %}
{% do part_list.append(publish_section_title) %}
[{{ publish_section_title }}]
recipe = slapos.cookbook:publish
-slave-reference = {{ slave_reference }}
{% set log_access_url = slave_information.pop('log-access-urls', None) %}
{% if log_access_url %}
{# sort_keys are important in order to avoid shuffling parameters on each run #}
log-access-url = {{ dumps(json_module.dumps(log_access_url, sort_keys=True)) }}
{% endif %}
{% for key, value in slave_information.iteritems() %}
{{ key }} = {{ dumps(value) }}
{% endfor %}
{% endif %}
{% endfor %}
[buildout]
extends = {{ common_profile }}
parts =
{% for part in part_list %}
{{ ' %s' % part }}
{% endfor %}
rotate-script.sh.in 0000664 0000000 0000000 00000000702 13723117434 0037160 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates #!/bin/sh
set -e
LOG_DIR={{ log_dir }}
LOGROTATE_DIR={{ rotate_dir }}
PATTERN={{ pattern }}
COMPRESS={{ xz_binary }}
KEEP_DAYS={{ keep_days }}
# Move out ${PATTERN} files
find ${LOG_DIR} -maxdepth 1 -type f -name ${PATTERN} -exec mv {} ${LOGROTATE_DIR}/ \;
# Compress
find ${LOGROTATE_DIR} -maxdepth 1 -type f -name ${PATTERN} -exec ${COMPRESS} -9 {} \;
# Retent old files
find ${LOGROTATE_DIR} -maxdepth 1 -type f -mtime +${KEEP_DAYS} -delete
template-log-access.conf.in 0000664 0000000 0000000 00000001546 13723117434 0040533 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates # Access log configuration
{% for slave, directory in slave_log_directory.iteritems() %}
https://[{{ parameter_dict['global_ipv6'] }}]:{{ parameter_dict['https_port'] }}/{{ slave }}, https://{{ parameter_dict['local_ipv4'] }}:{{ parameter_dict['https_port'] }}/{{ slave }} {
bind {{ parameter_dict['local_ipv4'] }}
root {{ directory }}/
browse
tls {{ parameter_dict['ip_access_certificate'] }} {{ parameter_dict['ip_access_certificate'] }}
basicauth "{{ slave }}" {{ slave_password[slave] | trim }} {
"Log Access {{ slave }}"
/
}
log / {{ parameter_dict['access_log'] }} "{remote} - {>REMOTE_USER} [{when}] \"{method} {uri} {proto}\" {status} {size} \"{>Referer}\" \"{>User-Agent}\" {latency_ms}" {
rotate_size 0
}
errors {{ parameter_dict['error_log'] }} {
rotate_size 0
* {{ parameter_dict['not_found_file'] }}
}
}
{% endfor %}
trafficserver/ 0000775 0000000 0000000 00000000000 13723117434 0036265 5 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates logging.config.jinja2 0000664 0000000 0000000 00000000413 13723117434 0042254 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates/trafficserver squid = format {
Format = '% % % %/% % % % % % %/% %'
}
log.ascii {
Format = squid,
Filename = 'squid',
RollingEnabled = 1,
RollingIntervalSec = 86400,
RollingOffsetHr = 0
}
records.config.jinja2 0000664 0000000 0000000 00000031567 13723117434 0042305 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates/trafficserver ##############################################################################
# *NOTE*: All options covered in this file should be documented in the docs:
#
# https://docs.trafficserver.apache.org/records.config
##############################################################################
##############################################################################
# SlapOS Specific configuration
##############################################################################
CONFIG proxy.config.proxy_name STRING {{ ats_configuration['hostname'] }}
CONFIG proxy.config.local_state_dir STRING {{ ats_directory['local-state'] }}
CONFIG proxy.config.config_dir STRING {{ ats_directory['configuration'] }}
CONFIG proxy.config.bin_path STRING {{ ats_directory['bin_path'] }}
CONFIG proxy.config.env_prep STRING example_prep.sh
CONFIG proxy.config.alarm_email STRING nobody
CONFIG proxy.config.syslog_facility STRING LOG_DAEMON
CONFIG proxy.config.output.logfile STRING traffic.out
CONFIG proxy.config.snapshot_dir STRING snapshots
CONFIG proxy.config.admin.user_id STRING {{ '#%s' % os_module.geteuid() }}
CONFIG proxy.config.admin.number_config_bak INT 0
CONFIG proxy.config.process_manager.mgmt_port INT {{ ats_configuration['mgmt-port'] }}
CONFIG proxy.config.admin.synthetic_port INT {{ ats_configuration['synthetic-port'] }}
LOCAL proxy.local.incoming_ip_to_bind STRING {{ ats_configuration['local-ip'] }}
CONFIG proxy.config.log.logfile_dir STRING {{ ats_directory['log'] }}
# Implement RFC 5861 with core
CONFIG proxy.config.http.cache.open_write_fail_action INT 2
CONFIG proxy.config.body_factory.template_sets_dir STRING {{ ats_configuration['templates-dir'] }}
# Support stale-if-error by returning cached content on backend 5xx or unavailability
CONFIG proxy.config.http.negative_revalidating_enabled INT 1
##############################################################################
# Proxy users variables. Docs:
# https://docs.trafficserver.apache.org/records.config#proxy-user-variables
##############################################################################
# Do not modify headers, as it needlessly pollutes information
CONFIG proxy.config.http.insert_client_ip INT 0
CONFIG proxy.config.http.insert_squid_x_forwarded_for INT 0
##############################################################################
# Thread configurations. Docs:
# https://docs.trafficserver.apache.org/records.config#thread-variables
##############################################################################
CONFIG proxy.config.exec_thread.autoconfig INT 1
CONFIG proxy.config.exec_thread.autoconfig.scale FLOAT 1.5
CONFIG proxy.config.exec_thread.limit INT 2
CONFIG proxy.config.accept_threads INT 1
CONFIG proxy.config.task_threads INT 2
CONFIG proxy.config.cache.threads_per_disk INT 8
CONFIG proxy.config.exec_thread.affinity INT 1
##############################################################################
# Specify server addresses and ports to bind for HTTP and HTTPS. Docs:
# https://docs.trafficserver.apache.org/records.config#proxy.config.http.server_ports
##############################################################################
CONFIG proxy.config.http.server_ports STRING {{ ats_configuration['local-ip'] + ':' + ats_configuration['input-port'] }}
##############################################################################
# Via: headers. Docs:
# https://docs.trafficserver.apache.org/records.config#proxy-config-http-insert-response-via-str
##############################################################################
CONFIG proxy.config.http.insert_request_via_str INT 1
CONFIG proxy.config.http.insert_response_via_str INT 0
##############################################################################
# Parent proxy configuration, in addition to these settings also see parent.config. Docs:
# https://docs.trafficserver.apache.org/records.config#parent-proxy-configuration
# https://docs.trafficserver.apache.org/en/latest/admin-guide/files/parent.config.en.html
##############################################################################
CONFIG proxy.config.http.parent_proxy_routing_enable INT 0
CONFIG proxy.config.http.parent_proxy.retry_time INT 300
CONFIG proxy.config.http.parent_proxy.connect_attempts_timeout INT 30
CONFIG proxy.config.http.forward.proxy_auth_to_parent INT 0
CONFIG proxy.config.http.uncacheable_requests_bypass_parent INT 1
##############################################################################
# HTTP connection timeouts (secs). Docs:
# https://docs.trafficserver.apache.org/records.config#http-connection-timeouts
##############################################################################
CONFIG proxy.config.http.keep_alive_no_activity_timeout_in INT 120
CONFIG proxy.config.http.keep_alive_no_activity_timeout_out INT 120
CONFIG proxy.config.http.transaction_no_activity_timeout_in INT {{ ats_configuration['request-timeout'] }}
CONFIG proxy.config.http.transaction_no_activity_timeout_out INT {{ ats_configuration['request-timeout'] }}
CONFIG proxy.config.http.transaction_active_timeout_in INT 900
CONFIG proxy.config.http.transaction_active_timeout_out INT 0
CONFIG proxy.config.http.accept_no_activity_timeout INT 120
CONFIG proxy.config.net.default_inactivity_timeout INT 86400
##############################################################################
# Origin server connect attempts. Docs:
# https://docs.trafficserver.apache.org/records.config#origin-server-connect-attempts
##############################################################################
# Try only once to connect (do not retry)
CONFIG proxy.config.http.connect_attempts_max_retries INT 0
# Try only once with server marked dead (do not retry)
CONFIG proxy.config.http.connect_attempts_max_retries_dead_server INT 0
CONFIG proxy.config.http.connect_attempts_rr_retries INT 3
CONFIG proxy.config.http.connect_attempts_timeout INT {{ ats_configuration['request-timeout'] }}
CONFIG proxy.config.http.post_connect_attempts_timeout INT {{ ats_configuration['request-timeout'] }}
CONFIG proxy.config.http.down_server.cache_time INT 60
CONFIG proxy.config.http.down_server.abort_threshold INT 10
##############################################################################
# Negative response caching, for redirects and errors. Docs:
# https://docs.trafficserver.apache.org/records.config#negative-response-caching
##############################################################################
CONFIG proxy.config.http.negative_caching_enabled INT 0
CONFIG proxy.config.http.negative_caching_lifetime INT 1800
##############################################################################
# Security. Docs:
# https://docs.trafficserver.apache.org/records.config#security
##############################################################################
CONFIG proxy.config.http.push_method_enabled INT 0
##############################################################################
# Enable / disable HTTP caching. Useful for testing, but also as an
# overridable (per remap) config
##############################################################################
CONFIG proxy.config.http.cache.http INT 1
##############################################################################
# Cache control. Docs:
# https://docs.trafficserver.apache.org/records.config#cache-control
# https://docs.trafficserver.apache.org/en/latest/admin-guide/files/cache.config.en.html
##############################################################################
CONFIG proxy.config.http.cache.ignore_client_cc_max_age INT 1
CONFIG proxy.config.http.normalize_ae_gzip INT 0
CONFIG proxy.config.http.cache.cache_responses_to_cookies INT 1
CONFIG proxy.config.http.cache.cache_urls_that_look_dynamic INT 1
# https://docs.trafficserver.apache.org/records.config#proxy-config-http-cache-when-to-revalidate
CONFIG proxy.config.http.cache.when_to_revalidate INT 0
# https://docs.trafficserver.apache.org/records.config#proxy-config-http-cache-required-headers
CONFIG proxy.config.http.cache.required_headers INT 2
##############################################################################
# Heuristic cache expiration. Docs:
# https://docs.trafficserver.apache.org/records.config#heuristic-expiration
##############################################################################
CONFIG proxy.config.http.cache.heuristic_min_lifetime INT 3600
CONFIG proxy.config.http.cache.heuristic_max_lifetime INT 86400
CONFIG proxy.config.http.cache.heuristic_lm_factor FLOAT 0.10
##############################################################################
# Network. Docs:
# https://docs.trafficserver.apache.org/records.config#network
##############################################################################
CONFIG proxy.config.net.connections_throttle INT 30000
CONFIG proxy.config.net.max_connections_in INT 30000
CONFIG proxy.config.net.max_connections_active_in INT 10000
##############################################################################
# RAM and disk cache configurations. Docs:
# https://docs.trafficserver.apache.org/records.config#ram-cache
# https://docs.trafficserver.apache.org/en/latest/admin-guide/files/storage.config.en.html
##############################################################################
CONFIG proxy.config.cache.ram_cache.size INT {{ ats_configuration.get('ram-cache-size', '1G') }}
CONFIG proxy.config.cache.ram_cache_cutoff INT 4194304
# https://docs.trafficserver.apache.org/records.config#proxy-config-cache-limits-http-max-alts
CONFIG proxy.config.cache.limits.http.max_alts INT 5
# https://docs.trafficserver.apache.org/records.config#proxy-config-cache-max-doc-size
CONFIG proxy.config.cache.max_doc_size INT 0
CONFIG proxy.config.cache.min_average_object_size INT 8000
##############################################################################
# Logging Config. Docs:
# https://docs.trafficserver.apache.org/records.config#logging-configuration
# https://docs.trafficserver.apache.org/en/latest/admin-guide/files/logging.config.en.html
##############################################################################
CONFIG proxy.config.log.logging_enabled INT 3
CONFIG proxy.config.log.max_space_mb_for_logs INT 25000
CONFIG proxy.config.log.max_space_mb_headroom INT 1000
CONFIG proxy.config.log.rolling_enabled INT 1
CONFIG proxy.config.log.rolling_interval_sec INT 86400
CONFIG proxy.config.log.rolling_size_mb INT 10
CONFIG proxy.config.log.auto_delete_rolled_files INT 1
CONFIG proxy.config.log.periodic_tasks_interval INT 5
##############################################################################
# These settings control remapping, and if the proxy allows (open) forward proxy or not. Docs:
# https://docs.trafficserver.apache.org/records.config#url-remap-rules
# https://docs.trafficserver.apache.org/en/latest/admin-guide/files/remap.config.en.html
##############################################################################
CONFIG proxy.config.url_remap.remap_required INT 1
# https://docs.trafficserver.apache.org/records.config#proxy-config-url-remap-pristine-host-hdr
CONFIG proxy.config.url_remap.pristine_host_hdr INT 1
# https://docs.trafficserver.apache.org/records.config#reverse-proxy
CONFIG proxy.config.reverse_proxy.enabled INT 1
##############################################################################
# SSL Termination. Docs:
# https://docs.trafficserver.apache.org/records.config#client-related-configuration
# https://docs.trafficserver.apache.org/en/latest/admin-guide/files/ssl_multicert.config.en.html
##############################################################################
CONFIG proxy.config.ssl.client.verify.server INT 0
CONFIG proxy.config.ssl.client.CA.cert.filename STRING NULL
CONFIG proxy.config.ssl.server.cipher_suite STRING ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
##############################################################################
# Debugging. Docs:
# https://docs.trafficserver.apache.org/records.config#diagnostic-logging-configuration
##############################################################################
CONFIG proxy.config.diags.debug.enabled INT 0
CONFIG proxy.config.diags.debug.tags STRING http.*|dns.*
# ToDo: Undocumented
CONFIG proxy.config.dump_mem_info_frequency INT 0
CONFIG proxy.config.http.slow.log.threshold INT 0
storage.config.jinja2 0000664 0000000 0000000 00000000715 13723117434 0042277 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates/trafficserver #
# storage.config - Storage Configuration file
#
# Documentation:
# https://docs.trafficserver.apache.org/en/latest/admin-guide/files/storage.config.en.html
#
# The storage configuration is a list of all the storage to
# be used by the cache.
#
#
#############################################################
# Using a file for the cache storage
#
#
{{ ats_configuration.get("cache-path") }} {{ ats_configuration.get("disk-cache-size") }}
validate-script.sh.in 0000664 0000000 0000000 00000000633 13723117434 0037456 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates #!/bin/sh
set -e
LAST_STATE_FILE={{ last_state_file }}
# force validation each 2 hours
old_found=1
if [ -f $LAST_STATE_FILE ] ; then
old_found=$(find $LAST_STATE_FILE -mmin +120 | wc -l)
fi
if [ "$old_found" -eq 1 ] || {{ configuration_state_command }} ; then
# do not catch errors during validation
set +e
{{ validate_command }}
echo $? > $LAST_STATE_FILE
set -e
fi
exit `cat $LAST_STATE_FILE`
wrapper.in 0000664 0000000 0000000 00000000044 13723117434 0035426 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/templates #!${dash-output:dash}
{{ content }}
test/ 0000775 0000000 0000000 00000000000 13723117434 0032401 5 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend setup.py 0000664 0000000 0000000 00000004373 13723117434 0034122 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test ##############################################################################
#
# Copyright (c) 2018 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from setuptools import setup, find_packages
version = '0.0.1.dev0'
name = 'slapos.test.caddy-frontend'
setup(name=name,
version=version,
description="Test for SlapOS' Caddy Frontend",
maintainer="Nexedi",
maintainer_email="info@nexedi.com",
url="https://lab.nexedi.com/nexedi/slapos",
packages=find_packages(),
install_requires=[
'slapos.core',
'slapos.cookbook',
'slapos.libnetworkcache',
'erp5.util',
'requests >= 2.20.0', # needed for recent SSL certificate fixes
'urllib3 >= 1.24', # needed for recent SSL certificate fixes
# ipaddress is patching IPAddress so IPv6 in SSL certificates
# match works
'ipaddress >= 1.0.22',
'requests-toolbelt',
'supervisor',
# caucase needed to connect to the KeDiFa caucase
'caucase',
'cryptography',
'backports.lzma',
],
zip_safe=True,
test_suite='test',
)
test.py 0000664 0000000 0000000 00000645377 13723117434 0033760 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test ##############################################################################
#
# Copyright (c) 2018 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import glob
import os
import requests
import httplib
from requests_toolbelt.adapters import source
import json
import multiprocessing
import subprocess
from unittest import skip
import ssl
from BaseHTTPServer import HTTPServer
from BaseHTTPServer import BaseHTTPRequestHandler
import time
import tempfile
import ipaddress
import StringIO
import gzip
import base64
import re
from slapos.recipe.librecipe import generateHashFromFiles
import xml.etree.ElementTree as ET
import urlparse
import socket
try:
import lzma
except ImportError:
from backports import lzma
import datetime
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
from slapos.testing.utils import findFreeTCPPort
from slapos.testing.utils import getPromisePluginParameterDict
setUpModule, SlapOSInstanceTestCase = makeModuleSetUpAndTestCaseClass(
os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'software.cfg')))
# ports chosen to not collide with test systems
HTTP_PORT = '11080'
HTTPS_PORT = '11443'
CAUCASE_PORT = '15090'
KEDIFA_PORT = '15080'
# IP to originate requests from
# has to be not partition one
SOURCE_IP = '127.0.0.1'
# "--resolve" inspired from https://stackoverflow.com/a/44378047/9256748
DNS_CACHE = {}
def add_custom_dns(domain, port, ip):
port = int(port)
key = (domain, port)
value = (socket.AF_INET, 1, 6, '', (ip, port))
DNS_CACHE[key] = [value]
def new_getaddrinfo(*args):
return DNS_CACHE[args[:2]]
# for development: debugging logs and install Ctrl+C handler
if os.environ.get('SLAPOS_TEST_DEBUG'):
import logging
logging.basicConfig(level=logging.DEBUG)
import unittest
unittest.installHandler()
def der2pem(der):
certificate = x509.load_der_x509_certificate(der, default_backend())
return certificate.public_bytes(serialization.Encoding.PEM)
def createKey():
key = rsa.generate_private_key(
public_exponent=65537, key_size=2048, backend=default_backend())
key_pem = key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption()
)
return key, key_pem
def createSelfSignedCertificate(name_list):
key, key_pem = createKey()
subject_alternative_name_list = x509.SubjectAlternativeName(
[x509.DNSName(unicode(q)) for q in name_list]
)
subject = issuer = x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, u'Test Self Signed Certificate'),
])
certificate = x509.CertificateBuilder().subject_name(
subject
).issuer_name(
issuer
).add_extension(
subject_alternative_name_list,
critical=False,
).public_key(
key.public_key()
).serial_number(
x509.random_serial_number()
).not_valid_before(
datetime.datetime.utcnow() - datetime.timedelta(days=2)
).not_valid_after(
datetime.datetime.utcnow() + datetime.timedelta(days=5)
).sign(key, hashes.SHA256(), default_backend())
certificate_pem = certificate.public_bytes(serialization.Encoding.PEM)
return key, key_pem, certificate, certificate_pem
def createCSR(common_name, ip=None):
key, key_pem = createKey()
subject_alternative_name_list = []
if ip is not None:
subject_alternative_name_list.append(
x509.IPAddress(ipaddress.ip_address(unicode(ip)))
)
csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, unicode(common_name)),
]))
if len(subject_alternative_name_list):
csr = csr.add_extension(
x509.SubjectAlternativeName(subject_alternative_name_list),
critical=False
)
csr = csr.sign(key, hashes.SHA256(), default_backend())
csr_pem = csr.public_bytes(serialization.Encoding.PEM)
return key, key_pem, csr, csr_pem
class CertificateAuthority(object):
def __init__(self, common_name):
self.key, self.key_pem = createKey()
public_key = self.key.public_key()
builder = x509.CertificateBuilder()
builder = builder.subject_name(x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, unicode(common_name)),
]))
builder = builder.issuer_name(x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, unicode(common_name)),
]))
builder = builder.not_valid_before(
datetime.datetime.utcnow() - datetime.timedelta(days=2))
builder = builder.not_valid_after(
datetime.datetime.utcnow() + datetime.timedelta(days=30))
builder = builder.serial_number(x509.random_serial_number())
builder = builder.public_key(public_key)
builder = builder.add_extension(
x509.BasicConstraints(ca=True, path_length=None), critical=True,
)
self.certificate = builder.sign(
private_key=self.key, algorithm=hashes.SHA256(),
backend=default_backend()
)
self.certificate_pem = self.certificate.public_bytes(
serialization.Encoding.PEM)
def signCSR(self, csr):
builder = x509.CertificateBuilder(
subject_name=csr.subject,
extensions=csr.extensions,
issuer_name=self.certificate.subject,
not_valid_before=datetime.datetime.utcnow() - datetime.timedelta(days=1),
not_valid_after=datetime.datetime.utcnow() + datetime.timedelta(days=30),
serial_number=x509.random_serial_number(),
public_key=csr.public_key(),
)
certificate = builder.sign(
private_key=self.key,
algorithm=hashes.SHA256(),
backend=default_backend()
)
return certificate, certificate.public_bytes(serialization.Encoding.PEM)
def subprocess_status_output(*args, **kwargs):
prc = subprocess.Popen(
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
*args,
**kwargs)
out, err = prc.communicate()
return prc.returncode, out
def subprocess_output(*args, **kwargs):
return subprocess_status_output(*args, **kwargs)[1]
def isHTTP2(domain, ip):
curl_command = 'curl --http2 -v -k -H "Host: %(domain)s" ' \
'https://%(domain)s:%(https_port)s/ '\
'--resolve %(domain)s:%(https_port)s:%(ip)s' % dict(
ip=ip, domain=domain, https_port=HTTPS_PORT)
prc = subprocess.Popen(
curl_command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
out, err = prc.communicate()
assert prc.returncode == 0, "Problem running %r. Output:\n%s\nError:\n%s" % (
curl_command, out, err)
return 'Using HTTP2, server supports multi-use' in err
class TestDataMixin(object):
def getTrimmedProcessInfo(self):
return '\n'.join(sorted([
'%(group)s:%(name)s %(statename)s' % q for q
in self.callSupervisorMethod('getAllProcessInfo')
if q['name'] != 'watchdog' and q['group'] != 'watchdog']))
def assertTestData(self, runtime_data, hash_value_dict=None, msg=None):
if hash_value_dict is None:
hash_value_dict = {}
filename = '%s-%s.txt' % (self.id(), 'CADDY')
test_data_file = os.path.join(
os.path.dirname(os.path.realpath(__file__)), 'test_data', filename)
try:
test_data = open(test_data_file).read().strip()
except IOError:
test_data = ''
for hash_type, hash_value in hash_value_dict.items():
runtime_data = runtime_data.replace(hash_value, '{hash-%s}' % (
hash_type),)
maxDiff = self.maxDiff
self.maxDiff = None
longMessage = self.longMessage
self.longMessage = True
try:
self.assertMultiLineEqual(
test_data,
runtime_data,
msg=msg
)
except AssertionError:
if os.environ.get('SAVE_TEST_DATA', '0') == '1':
open(test_data_file, 'w').write(runtime_data.strip() + '\n')
raise
finally:
self.maxDiff = maxDiff
self.longMessage = longMessage
def _test_file_list(self, slave_dir_list, IGNORE_PATH_LIST=None):
if IGNORE_PATH_LIST is None:
IGNORE_PATH_LIST = []
runtime_data = []
for slave_var in glob.glob(os.path.join(self.instance_path, '*')):
for entry in os.walk(os.path.join(slave_var, *slave_dir_list)):
for filename in entry[2]:
path = os.path.join(
entry[0][len(self.instance_path) + 1:], filename)
if not any([path.endswith(q) for q in IGNORE_PATH_LIST]):
runtime_data.append(path)
runtime_data = '\n'.join(sorted(runtime_data))
self.assertTestData(runtime_data)
def test_file_list_log(self):
self._test_file_list(['var', 'log'], [
# no control at all when cron would kick in, ignore it
'cron.log',
# appears late and is quite unstable, no need to assert
'trafficserver/.diags.log.meta',
'trafficserver/.manager.log.meta',
'trafficserver/.squid.log.meta',
'trafficserver/.traffic.out.meta',
'trafficserver/diags.log',
'trafficserver/squid.log',
# not important, appears sometimes
'trafficserver/.error.log.meta',
'trafficserver/error.log',
])
def test_file_list_run(self):
self._test_file_list(['var', 'run'], [
# can't be sure regarding its presence
'caddy_configuration_last_state',
'validate_configuration_state_signature',
# run by cron from time to time
'monitor/monitor-collect.pid',
# no control regarding if it would or not be running
'monitor/monitor-bootstrap.pid',
])
def test_file_list_etc_cron_d(self):
self._test_file_list(['etc', 'cron.d'])
def test_file_list_plugin(self):
self._test_file_list(['etc', 'plugin'], ['.pyc'])
def test_supervisor_state(self):
# give a chance for etc/run scripts to finish
time.sleep(1)
hash_file_list = [os.path.join(
self.computer_partition_root_path, 'software_release/buildout.cfg')]
hash_value_dict = {
'generic': generateHashFromFiles(hash_file_list),
}
for caddy_wrapper_path in glob.glob(os.path.join(
self.instance_path, '*', 'bin', 'caddy-wrapper')):
partition_id = caddy_wrapper_path.split('/')[-3]
hash_value_dict[
'caddy-%s' % (partition_id)] = generateHashFromFiles(
[caddy_wrapper_path] + hash_file_list
)
for backend_haproxy_wrapper_path in glob.glob(os.path.join(
self.instance_path, '*', 'bin', 'backend-haproxy-wrapper')):
partition_id = backend_haproxy_wrapper_path.split('/')[-3]
hash_value_dict[
'backend-haproxy-%s' % (partition_id)] = generateHashFromFiles(
[backend_haproxy_wrapper_path] + hash_file_list
)
for rejected_slave_publish_path in glob.glob(os.path.join(
self.instance_path, '*', 'etc', 'Caddyfile-rejected-slave')):
partition_id = rejected_slave_publish_path.split('/')[-3]
rejected_slave_pem_path = os.path.join(
self.instance_path, partition_id, 'etc', 'rejected-slave.pem')
hash_value_dict[
'rejected-slave-publish'
] = generateHashFromFiles(
[rejected_slave_publish_path, rejected_slave_pem_path] + hash_file_list
)
runtime_data = self.getTrimmedProcessInfo()
self.assertTestData(runtime_data, hash_value_dict=hash_value_dict)
def fakeHTTPSResult(domain, real_ip, path, port=HTTPS_PORT,
headers=None, cookies=None, source_ip=SOURCE_IP):
if headers is None:
headers = {}
# workaround request problem of setting Accept-Encoding
# https://github.com/requests/requests/issues/2234
headers.setdefault('Accept-Encoding', 'dummy')
# Headers to tricks the whole system, like rouge user would do
headers.setdefault('X-Forwarded-For', '192.168.0.1')
headers.setdefault('X-Forwarded-Proto', 'irc')
headers.setdefault('X-Forwarded-Port', '17')
session = requests.Session()
if source_ip is not None:
new_source = source.SourceAddressAdapter(source_ip)
session.mount('http://', new_source)
session.mount('https://', new_source)
socket_getaddrinfo = socket.getaddrinfo
try:
add_custom_dns(domain, port, real_ip)
socket.getaddrinfo = new_getaddrinfo
return session.get(
'https://%s:%s/%s' % (domain, port, path),
verify=False,
allow_redirects=False,
headers=headers,
cookies=cookies
)
finally:
socket.getaddrinfo = socket_getaddrinfo
def fakeHTTPResult(domain, real_ip, path, port=HTTP_PORT,
headers=None, source_ip=SOURCE_IP):
if headers is None:
headers = {}
# workaround request problem of setting Accept-Encoding
# https://github.com/requests/requests/issues/2234
headers.setdefault('Accept-Encoding', 'dummy')
# Headers to tricks the whole system, like rouge user would do
headers.setdefault('X-Forwarded-For', '192.168.0.1')
headers.setdefault('X-Forwarded-Proto', 'irc')
headers.setdefault('X-Forwarded-Port', '17')
headers['Host'] = '%s:%s' % (domain, port)
session = requests.Session()
if source_ip is not None:
new_source = source.SourceAddressAdapter(source_ip)
session.mount('http://', new_source)
session.mount('https://', new_source)
return session.get(
'http://%s:%s/%s' % (real_ip, port, path),
headers=headers,
allow_redirects=False,
)
class TestHandler(BaseHTTPRequestHandler):
identification = None
def do_GET(self):
timeout = int(self.headers.dict.get('timeout', '0'))
compress = int(self.headers.dict.get('compress', '0'))
time.sleep(timeout)
self.send_response(200)
if self.identification is not None:
self.send_header('X-Backend-Identification', self.identification)
drop_header_list = []
for header in self.headers.dict.get('x-drop-header', '').split():
drop_header_list.append(header)
prefix = 'x-reply-header-'
length = len(prefix)
for key, value in self.headers.dict.items():
if key.startswith(prefix):
self.send_header(
'-'.join([q.capitalize() for q in key[length:].split('-')]),
value.strip()
)
if 'Content-Type' not in drop_header_list:
self.send_header("Content-Type", "application/json")
if 'Set-Cookie' not in drop_header_list:
self.send_header('Set-Cookie', 'secured=value;secure')
self.send_header('Set-Cookie', 'nonsecured=value')
if 'x-reply-body' not in self.headers.dict:
response = {
'Path': self.path,
'Incoming Headers': self.headers.dict
}
response = json.dumps(response, indent=2)
else:
response = base64.b64decode(self.headers.dict['x-reply-body'])
if compress:
self.send_header('Content-Encoding', 'gzip')
out = StringIO.StringIO()
# compress with level 0, to find out if in the middle someting would
# like to alter the compression
with gzip.GzipFile(fileobj=out, mode="w", compresslevel=0) as f:
f.write(response)
response = out.getvalue()
self.send_header('Backend-Content-Length', len(response))
if 'Content-Length' not in drop_header_list:
self.send_header('Content-Length', len(response))
self.end_headers()
self.wfile.write(response)
class HttpFrontendTestCase(SlapOSInstanceTestCase):
# show full diffs, as it is required for proper analysis of problems
maxDiff = None
# minimise partition path
__partition_reference__ = 'T-'
@classmethod
def getInstanceSoftwareType(cls):
# Because of unknown problem yet, the root instance software type changes
# from RootSoftwareInstance to '', so always request it with given type
return "RootSoftwareInstance"
@classmethod
def prepareCertificate(cls):
cls.another_server_ca = CertificateAuthority("Another Server Root CA")
cls.test_server_ca = CertificateAuthority("Test Server Root CA")
key, key_pem, csr, csr_pem = createCSR(
"testserver.example.com", cls._ipv4_address)
_, cls.test_server_certificate_pem = cls.test_server_ca.signCSR(csr)
cls.test_server_certificate_file = tempfile.NamedTemporaryFile(
delete=False
)
cls.test_server_certificate_file.write(
cls.test_server_certificate_pem + key_pem
)
cls.test_server_certificate_file.close()
@classmethod
def startServerProcess(cls):
server = HTTPServer(
(cls._ipv4_address, cls._server_http_port),
TestHandler)
server_https = HTTPServer(
(cls._ipv4_address, cls._server_https_port),
TestHandler)
server_https.socket = ssl.wrap_socket(
server_https.socket,
certfile=cls.test_server_certificate_file.name,
server_side=True)
cls.backend_url = 'http://%s:%s/' % server.server_address
cls.server_process = multiprocessing.Process(
target=server.serve_forever, name='HTTPServer')
cls.server_process.start()
cls.logger.debug('Started process %s' % (cls.server_process,))
cls.backend_https_url = 'https://%s:%s/' % server_https.server_address
cls.server_https_process = multiprocessing.Process(
target=server_https.serve_forever, name='HTTPSServer')
cls.server_https_process.start()
cls.logger.debug('Started process %s' % (cls.server_https_process,))
@classmethod
def cleanUpCertificate(cls):
if getattr(cls, 'test_server_certificate_file', None) is not None:
os.unlink(cls.test_server_certificate_file.name)
@classmethod
def stopServerProcess(cls):
for server in ['server_process', 'server_https_process']:
process = getattr(cls, server, None)
if process is not None:
cls.logger.debug('Stopping process %s' % (process,))
process.join(10)
process.terminate()
time.sleep(0.1)
if process.is_alive():
cls.logger.warning(
'Process %s still alive' % (process, ))
@classmethod
def setUpMaster(cls):
# run partition until AIKC finishes
cls.runComputerPartitionUntil(
cls.untilNotReadyYetNotInMasterKeyGenerateAuthUrl)
parameter_dict = cls.requestDefaultInstance().getConnectionParameterDict()
ca_certificate = requests.get(
parameter_dict['kedifa-caucase-url'] + '/cas/crt/ca.crt.pem')
assert ca_certificate.status_code == httplib.OK
cls.ca_certificate_file = os.path.join(cls.working_directory, 'ca.crt.pem')
open(cls.ca_certificate_file, 'w').write(ca_certificate.text)
auth = requests.get(
parameter_dict['master-key-generate-auth-url'],
verify=cls.ca_certificate_file)
assert auth.status_code == httplib.CREATED
upload = requests.put(
parameter_dict['master-key-upload-url'] + auth.text,
data=cls.key_pem + cls.certificate_pem,
verify=cls.ca_certificate_file)
assert upload.status_code == httplib.CREATED
@classmethod
def runKedifaUpdater(cls):
kedifa_updater = None
for kedifa_updater in sorted(glob.glob(
os.path.join(
cls.instance_path, '*', 'etc', 'service', 'kedifa-updater*'))):
# fetch first kedifa-updater, as by default most of the tests are using
# only one running partition; in case if test does not need
# kedifa-updater this method can be overridden
break
if kedifa_updater is not None:
# try few times kedifa_updater
for i in range(10):
return_code, output = subprocess_status_output(
[kedifa_updater, '--once'])
if return_code == 0:
break
# wait for the other updater to work
time.sleep(2)
# assert that in the worst case last run was correct
assert return_code == 0, output
# give caddy a moment to refresh its config, as sending signal does not
# block until caddy is refreshed
time.sleep(2)
@classmethod
def createWildcardExampleComCertificate(cls):
_, cls.key_pem, _, cls.certificate_pem = createSelfSignedCertificate(
[
'*.customdomain.example.com',
'*.example.com',
'*.alias1.example.com',
])
@classmethod
def runComputerPartitionUntil(cls, until):
max_try = 10
try_num = 1
while True:
if until():
break
if try_num > max_try:
raise ValueError('Failed to run computer partition with %r' % (until,))
try:
cls.slap.waitForInstance()
except Exception:
cls.logger.exception("Error during until run")
try_num += 1
@classmethod
def untilNotReadyYetNotInMasterKeyGenerateAuthUrl(cls):
parameter_dict = cls.requestDefaultInstance().getConnectionParameterDict()
key = 'master-key-generate-auth-url'
if key not in parameter_dict:
return False
if 'NotReadyYet' in parameter_dict[key]:
return False
return True
@classmethod
def callSupervisorMethod(cls, method, *args, **kwargs):
with cls.slap.instance_supervisor_rpc as instance_supervisor:
return getattr(instance_supervisor, method)(*args, **kwargs)
def assertRejectedSlavePromiseWithPop(self, parameter_dict):
rejected_slave_promise_url = parameter_dict.pop(
'rejected-slave-promise-url')
try:
result = requests.get(rejected_slave_promise_url, verify=False)
if result.text == '':
result_json = {}
else:
result_json = result.json()
self.assertEqual(
parameter_dict['rejected-slave-dict'],
result_json
)
except AssertionError:
raise
except Exception as e:
self.fail(e)
def assertLogAccessUrlWithPop(self, parameter_dict):
log_access_url = parameter_dict.pop('log-access-url')
self.assertTrue(len(log_access_url) >= 1)
# check only the first one, as second frontend will be stopped
log_access = log_access_url[0]
entry = log_access.split(': ')
if len(entry) != 2:
self.fail('Cannot parse %r' % (log_access,))
frontend, url = entry
result = requests.get(url, verify=False)
self.assertEqual(
httplib.OK,
result.status_code,
'While accessing %r of %r the status code was %r' % (
url, frontend, result.status_code))
self.assertEqual(
httplib.OK,
requests.get(url + 'access.log', verify=False).status_code
)
self.assertEqual(
httplib.OK,
requests.get(url + 'error.log', verify=False).status_code
)
# assert only for few tests, as backend log is not available for many of
# them, as it's created on the fly
for test_name in ['test_url', 'test_auth_to_backend', 'test_compressed_result']:
if self.id().endswith(test_name):
self.assertEqual(
httplib.OK,
requests.get(url + 'backend.log', verify=False).status_code
)
def assertKedifaKeysWithPop(self, parameter_dict, prefix=''):
generate_auth_url = parameter_dict.pop('%skey-generate-auth-url' % (
prefix,))
upload_url = parameter_dict.pop('%skey-upload-url' % (prefix,))
kedifa_ipv6_base = 'https://[%s]:%s' % (self._ipv6_address, KEDIFA_PORT)
base = '^' + kedifa_ipv6_base.replace(
'[', r'\[').replace(']', r'\]') + '/.{32}'
self.assertRegexpMatches(
generate_auth_url,
base + r'\/generateauth$'
)
self.assertRegexpMatches(
upload_url,
base + r'\?auth=$'
)
kedifa_caucase_url = parameter_dict.pop('kedifa-caucase-url')
self.assertEqual(
kedifa_caucase_url,
'http://[%s]:%s' % (self._ipv6_address, CAUCASE_PORT),
)
return generate_auth_url, upload_url
def assertKeyWithPop(self, key, d):
self.assertTrue(key in d, 'Key %r is missing in %r' % (key, d))
d.pop(key)
def assertEqualResultJson(self, result, key, value):
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertTrue(key in j, 'No key %r in %s' % (key, j))
self.assertEqual(value, j[key])
def patchRequests(self):
HTTPResponse = requests.packages.urllib3.response.HTTPResponse
HTTPResponse.orig__init__ = HTTPResponse.__init__
def new_HTTPResponse__init__(self, *args, **kwargs):
self.orig__init__(*args, **kwargs)
try:
self.peercert = self._connection.sock.getpeercert(binary_form=True)
except AttributeError:
pass
HTTPResponse.__init__ = new_HTTPResponse__init__
HTTPAdapter = requests.adapters.HTTPAdapter
HTTPAdapter.orig_build_response = HTTPAdapter.build_response
def new_HTTPAdapter_build_response(self, request, resp):
response = self.orig_build_response(request, resp)
try:
response.peercert = resp.peercert
except AttributeError:
pass
return response
HTTPAdapter.build_response = new_HTTPAdapter_build_response
def unpatchRequests(self):
HTTPResponse = requests.packages.urllib3.response.HTTPResponse
if getattr(HTTPResponse, 'orig__init__', None) is not None:
HTTPResponse.__init__ = HTTPResponse.orig__init__
del(HTTPResponse.orig__init__)
HTTPAdapter = requests.adapters.HTTPAdapter
if getattr(HTTPAdapter, 'orig_build_response', None) is not None:
HTTPAdapter.build_response = HTTPAdapter.orig_build_response
del(HTTPAdapter.orig_build_response)
def setUp(self):
# patch requests in order to being able to extract SSL certs
self.patchRequests()
def tearDown(self):
self.unpatchRequests()
super(HttpFrontendTestCase, self).tearDown()
def parseParameterDict(self, parameter_dict):
parsed_parameter_dict = {}
for key, value in parameter_dict.items():
if key in [
'rejected-slave-dict',
'warning-slave-dict',
'warning-list',
'request-error-list',
'log-access-url']:
value = json.loads(value)
parsed_parameter_dict[key] = value
return parsed_parameter_dict
def getMasterPartitionPath(self):
return '/' + os.path.join(
*glob.glob(
os.path.join(
self.instance_path, '*', 'etc', 'Caddyfile-rejected-slave'
)
)[0].split('/')[:-2])
def parseConnectionParameterDict(self):
return self.parseParameterDict(
self.requestDefaultInstance().getConnectionParameterDict()
)
@classmethod
def waitForMethod(cls, name, method):
wait_time = 600
begin = time.time()
try_num = 0
cls.logger.debug('%s for %is' % (name, wait_time,))
while True:
try:
try_num += 1
method()
except Exception:
if time.time() - begin > wait_time:
cls.logger.exception(
"Error during %s after %.2fs" % (name, (time.time() - begin),))
raise
else:
time.sleep(0.5)
else:
cls.logger.info("%s took %.2fs" % (name, (time.time() - begin),))
break
@classmethod
def waitForCaddy(cls):
def method():
fakeHTTPSResult(
cls._ipv4_address, cls._ipv4_address,
'/',
)
cls.waitForMethod('waitForCaddy', method)
@classmethod
def _cleanup(cls, snapshot_name):
cls.cleanUpCertificate()
cls.stopServerProcess()
super(HttpFrontendTestCase, cls)._cleanup(snapshot_name)
@classmethod
def setUpClass(cls):
try:
cls.createWildcardExampleComCertificate()
cls.prepareCertificate()
# find ports once to be able startServerProcess many times
cls._server_http_port = findFreeTCPPort(cls._ipv4_address)
cls._server_https_port = findFreeTCPPort(cls._ipv4_address)
cls._server_https_auth_port = findFreeTCPPort(cls._ipv4_address)
cls.startServerProcess()
except BaseException:
cls.logger.exception("Error during setUpClass")
cls._cleanup("{}.{}.setUpClass".format(cls.__module__, cls.__name__))
cls.setUp = lambda self: self.fail('Setup Class failed.')
raise
super(HttpFrontendTestCase, cls).setUpClass()
try:
# expose instance directory
cls.instance_path = cls.slap.instance_directory
# expose software directory, extract from found computer partition
cls.software_path = os.path.realpath(os.path.join(
cls.computer_partition_root_path, 'software_release'))
# do working directory
cls.working_directory = os.path.join(os.path.realpath(
os.environ.get(
'SLAPOS_TEST_WORKING_DIR',
os.path.join(os.getcwd(), '.slapos'))),
'caddy-frontend-test')
if not os.path.isdir(cls.working_directory):
os.mkdir(cls.working_directory)
cls.setUpMaster()
cls.waitForCaddy()
except BaseException:
cls.logger.exception("Error during setUpClass")
# "{}.{}.setUpClass".format(cls.__module__, cls.__name__) is already used
# by SlapOSInstanceTestCase.setUpClass so we use another name for
# snapshot, to make sure we don't store another snapshot in same
# directory.
cls._cleanup("{}.SlaveHttpFrontendTestCase.{}.setUpClass".format(
cls.__module__, cls.__name__))
cls.setUp = lambda self: self.fail('Setup Class failed.')
raise
class SlaveHttpFrontendTestCase(HttpFrontendTestCase):
@classmethod
def requestDefaultInstance(cls, state='started'):
default_instance = super(
SlaveHttpFrontendTestCase, cls).requestDefaultInstance(state=state)
if state != 'destroyed':
cls.requestSlaves()
return default_instance
@classmethod
def requestSlaves(cls):
software_url = cls.getSoftwareURL()
for slave_reference, partition_parameter_kw in cls\
.getSlaveParameterDictDict().items():
cls.logger.debug(
'requesting slave "%s" software:%s parameters:%s',
slave_reference, software_url, partition_parameter_kw)
cls.slap.request(
software_release=software_url,
partition_reference=slave_reference,
partition_parameter_kw=partition_parameter_kw,
shared=True
)
@classmethod
def setUpClass(cls):
super(SlaveHttpFrontendTestCase, cls).setUpClass()
try:
cls.setUpSlaves()
cls.waitForSlave()
except BaseException:
cls.logger.exception("Error during setUpClass")
# "{}.{}.setUpClass".format(cls.__module__, cls.__name__) is already used
# by SlapOSInstanceTestCase.setUpClass so we use another name for
# snapshot, to make sure we don't store another snapshot in same
# directory.
cls._cleanup("{}.SlaveHttpFrontendTestCase.{}.setUpClass".format(
cls.__module__, cls.__name__))
cls.setUp = lambda self: self.fail('Setup Class failed.')
raise
@classmethod
def waitForSlave(cls):
def method():
for parameter_dict in cls.getSlaveConnectionParameterDictList():
if 'domain' in parameter_dict and 'public-ipv4' in parameter_dict:
try:
fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], '/')
except requests.exceptions.InvalidURL:
# ignore slaves to which connection is impossible by default
continue
cls.waitForMethod('waitForSlave', method)
@classmethod
def getSlaveConnectionParameterDictList(cls):
parameter_dict_list = []
for slave_reference, partition_parameter_kw in cls\
.getSlaveParameterDictDict().items():
parameter_dict_list.append(cls.slap.request(
software_release=cls.getSoftwareURL(),
partition_reference=slave_reference,
partition_parameter_kw=partition_parameter_kw,
shared=True
).getConnectionParameterDict())
return parameter_dict_list
@classmethod
def untilSlavePartitionReady(cls):
# all on-watch services shall not be exited
for process in cls.callSupervisorMethod('getAllProcessInfo'):
if process['name'].endswith('-on-watch') and \
process['statename'] == 'EXITED':
if process['name'].startswith('monitor-http'):
continue
return False
for parameter_dict in cls.getSlaveConnectionParameterDictList():
log_access_ready = 'log-access-url' in parameter_dict
key = 'key-generate-auth-url'
key_generate_auth_ready = key in parameter_dict \
and 'NotReadyYet' not in parameter_dict[key]
if not(log_access_ready and key_generate_auth_ready):
return False
return True
@classmethod
def setUpSlaves(cls):
cls.runComputerPartitionUntil(
cls.untilSlavePartitionReady)
cls.updateSlaveConnectionParameterDictDict()
@classmethod
def updateSlaveConnectionParameterDictDict(cls):
cls.slave_connection_parameter_dict_dict = {}
# run partition for slaves to be setup
request = cls.slap.request
for slave_reference, partition_parameter_kw in cls\
.getSlaveParameterDictDict().items():
slave_instance = request(
software_release=cls.getSoftwareURL(),
partition_reference=slave_reference,
partition_parameter_kw=partition_parameter_kw,
shared=True
)
cls.slave_connection_parameter_dict_dict[slave_reference] = \
slave_instance.getConnectionParameterDict()
def parseSlaveParameterDict(self, key):
return self.parseParameterDict(
self.slave_connection_parameter_dict_dict[
key
]
)
def assertSlaveBase(self, reference):
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, '')
hostname = reference.translate(None, '_-').lower()
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
return parameter_dict
class TestMasterRequestDomain(HttpFrontendTestCase, TestDataMixin):
@classmethod
def getInstanceParameterDict(cls):
return {
'domain': 'example.com',
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
}
def test(self):
parameter_dict = self.parseConnectionParameterDict()
self.assertKeyWithPop('monitor-setup-url', parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, 'master-')
self.assertRejectedSlavePromiseWithPop(parameter_dict)
self.assertEqual(
{
'monitor-base-url': 'https://[%s]:8401' % self._ipv6_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'domain': 'example.com',
'accepted-slave-amount': '0',
'rejected-slave-amount': '0',
'slave-amount': '0',
'rejected-slave-dict': {}
},
parameter_dict
)
class TestMasterRequest(HttpFrontendTestCase, TestDataMixin):
@classmethod
def getInstanceParameterDict(cls):
return {
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
}
def test(self):
parameter_dict = self.parseConnectionParameterDict()
self.assertKeyWithPop('monitor-setup-url', parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, 'master-')
self.assertRejectedSlavePromiseWithPop(parameter_dict)
self.assertEqual(
{
'monitor-base-url': 'https://[%s]:8401' % self._ipv6_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'domain': 'None',
'accepted-slave-amount': '0',
'rejected-slave-amount': '0',
'slave-amount': '0',
'rejected-slave-dict': {}},
parameter_dict
)
class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin):
@classmethod
def getInstanceParameterDict(cls):
return {
'domain': 'example.com',
'public-ipv4': cls._ipv4_address,
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
'mpm-graceful-shutdown-timeout': 2,
'request-timeout': '12',
}
@classmethod
def prepareCertificate(cls):
cls.ca = CertificateAuthority('TestSlave')
_, cls.customdomain_ca_key_pem, csr, _ = createCSR(
'customdomainsslcrtsslkeysslcacrt.example.com')
_, cls.customdomain_ca_certificate_pem = cls.ca.signCSR(csr)
_, cls.customdomain_key_pem, _, cls.customdomain_certificate_pem = \
createSelfSignedCertificate(['customdomainsslcrtsslkey.example.com'])
super(TestSlave, cls).prepareCertificate()
@classmethod
def getSlaveParameterDictDict(cls):
return {
'empty': {
},
'Url': {
# make URL "incorrect", with whitespace, nevertheless it shall be
# correctly handled
'url': ' ' + cls.backend_url + ' ',
# authenticating to http backend shall be no-op
'authenticate-to-backend': True,
},
'auth-to-backend': {
# in here use reserved port for the backend, which is going to be
# started later
'url': 'https://%s:%s/' % (
cls._ipv4_address, cls._server_https_auth_port),
'authenticate-to-backend': True,
},
'auth-to-backend-not-configured': {
# in here use reserved port for the backend, which is going to be
# started later
'url': 'https://%s:%s/' % (
cls._ipv4_address, cls._server_https_auth_port),
},
'auth-to-backend-backend-ignore': {
'url': cls.backend_https_url,
'authenticate-to-backend': True,
},
'url_https-url': {
'url': cls.backend_url + 'http',
'https-url': cls.backend_url + 'https',
'backend-connect-timeout': 10,
'backend-connect-retries': 5,
'request-timeout': 15,
},
'server-alias': {
'url': cls.backend_url,
'server-alias': 'alias1.example.com alias2.example.com',
},
'server-alias-empty': {
'url': cls.backend_url,
'server-alias': '',
},
'server-alias-wildcard': {
'url': cls.backend_url,
'server-alias': '*.alias1.example.com',
},
'server-alias-duplicated': {
'url': cls.backend_url,
'server-alias': 'alias3.example.com alias3.example.com',
},
'server-alias_custom_domain-duplicated': {
'url': cls.backend_url,
'custom_domain': 'alias4.example.com',
'server-alias': 'alias4.example.com alias4.example.com',
},
'ssl-proxy-verify_ssl_proxy_ca_crt': {
'url': cls.backend_https_url,
'ssl-proxy-verify': True,
'ssl_proxy_ca_crt': cls.test_server_ca.certificate_pem,
},
'ssl-proxy-verify_ssl_proxy_ca_crt-unverified': {
'url': cls.backend_https_url,
'ssl-proxy-verify': True,
'ssl_proxy_ca_crt': cls.another_server_ca.certificate_pem,
},
'ssl-proxy-verify-unverified': {
'url': cls.backend_https_url,
'ssl-proxy-verify': True,
},
'https-only': {
'url': cls.backend_url,
'https-only': False,
},
'custom_domain': {
'url': cls.backend_url,
'custom_domain': 'mycustomdomain.example.com',
},
'custom_domain_wildcard': {
'url': cls.backend_url,
'custom_domain': '*.customdomain.example.com',
},
'custom_domain_server_alias': {
'url': cls.backend_url,
'custom_domain': 'mycustomdomainserveralias.example.com',
'server-alias': 'mycustomdomainserveralias1.example.com',
},
'custom_domain_ssl_crt_ssl_key': {
'url': cls.backend_url,
'custom_domain': 'customdomainsslcrtsslkey.example.com',
},
'custom_domain_ssl_crt_ssl_key_ssl_ca_crt': {
'url': cls.backend_url,
'custom_domain': 'customdomainsslcrtsslkeysslcacrt.example.com',
},
'ssl_ca_crt_only': {
'url': cls.backend_url,
},
'ssl_ca_crt_garbage': {
'url': cls.backend_url,
},
'ssl_ca_crt_does_not_match': {
'url': cls.backend_url,
},
'type-zope': {
'url': cls.backend_url,
'type': 'zope',
},
'type-zope-prefer-gzip-encoding-to-backend': {
'url': cls.backend_url,
'prefer-gzip-encoding-to-backend': 'true',
'type': 'zope',
},
'type-zope-prefer-gzip-encoding-to-backend-https-only': {
'url': cls.backend_url,
'prefer-gzip-encoding-to-backend': 'true',
'type': 'zope',
'https-only': 'false',
},
'type-zope-ssl-proxy-verify_ssl_proxy_ca_crt': {
'url': cls.backend_https_url,
'type': 'zope',
'ssl-proxy-verify': True,
'ssl_proxy_ca_crt': cls.test_server_ca.certificate_pem,
},
'type-zope-ssl-proxy-verify_ssl_proxy_ca_crt-unverified': {
'url': cls.backend_https_url,
'type': 'zope',
'ssl-proxy-verify': True,
'ssl_proxy_ca_crt': cls.another_server_ca.certificate_pem,
},
'type-zope-ssl-proxy-verify-unverified': {
'url': cls.backend_https_url,
'type': 'zope',
'ssl-proxy-verify': True,
},
'type-zope-virtualhostroot-http-port': {
'url': cls.backend_url,
'type': 'zope',
'virtualhostroot-http-port': '12345',
'https-only': 'false',
},
'type-zope-virtualhostroot-https-port': {
'url': cls.backend_url,
'type': 'zope',
'virtualhostroot-https-port': '12345'
},
'type-zope-path': {
'url': cls.backend_url,
'type': 'zope',
'path': '///path/to/some/resource///',
},
'type-zope-default-path': {
'url': cls.backend_url,
'type': 'zope',
'default-path': '///default-path/to/some/resource///',
},
'type-notebook': {
'url': cls.backend_url,
'type': 'notebook',
},
'type-websocket': {
'url': cls.backend_url,
'type': 'websocket',
},
'type-websocket-websocket-path-list': {
'url': cls.backend_url,
'type': 'websocket',
'websocket-path-list': '////ws//// /with%20space/',
},
'type-websocket-websocket-transparent-false': {
'url': cls.backend_url,
'type': 'websocket',
'websocket-transparent': 'false',
},
'type-websocket-websocket-path-list-websocket-transparent-false': {
'url': cls.backend_url,
'type': 'websocket',
'websocket-path-list': '////ws//// /with%20space/',
'websocket-transparent': 'false',
},
# 'type-eventsource': {
# 'url': cls.backend_url,
# 'type': 'eventsource',
# },
'type-redirect': {
'url': cls.backend_url,
'type': 'redirect',
},
'type-redirect-custom_domain': {
'url': cls.backend_url,
'type': 'redirect',
'custom_domain': 'customdomaintyperedirect.example.com',
},
'enable_cache': {
'url': cls.backend_url,
'enable_cache': True,
},
'enable_cache_custom_domain': {
'url': cls.backend_url,
'enable_cache': True,
'custom_domain': 'customdomainenablecache.example.com',
},
'enable_cache_server_alias': {
'url': cls.backend_url,
'enable_cache': True,
'server-alias': 'enablecacheserveralias1.example.com',
},
'enable_cache-disable-no-cache-request': {
'url': cls.backend_url,
'enable_cache': True,
'disable-no-cache-request': True,
},
'enable_cache-disable-via-header': {
'url': cls.backend_url,
'enable_cache': True,
'disable-via-header': True,
},
'enable-http2-false': {
'url': cls.backend_url,
'enable-http2': False,
},
'enable_cache-ssl-proxy-verify-unverified': {
'url': cls.backend_https_url,
'enable_cache': True,
'ssl-proxy-verify': True,
},
'enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt': {
'url': cls.backend_https_url,
'enable_cache': True,
'ssl_proxy_ca_crt': cls.test_server_ca.certificate_pem,
'ssl-proxy-verify': True,
},
'enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt-unverified': {
'url': cls.backend_https_url,
'enable_cache': True,
'ssl_proxy_ca_crt': cls.another_server_ca.certificate_pem,
'ssl-proxy-verify': True,
},
'enable-http2-default': {
'url': cls.backend_url,
},
'prefer-gzip-encoding-to-backend': {
'url': cls.backend_url,
'prefer-gzip-encoding-to-backend': 'true',
},
'prefer-gzip-encoding-to-backend-https-only': {
'url': cls.backend_url,
'prefer-gzip-encoding-to-backend': 'true',
'https-only': 'false',
},
'disabled-cookie-list': {
'url': cls.backend_url,
'disabled-cookie-list': 'Chocolate Vanilia',
},
'monitor-ipv4-test': {
'monitor-ipv4-test': 'monitor-ipv4-test',
},
'monitor-ipv6-test': {
'monitor-ipv6-test': 'monitor-ipv6-test',
},
'ciphers': {
'ciphers': 'RSA-3DES-EDE-CBC-SHA RSA-AES128-CBC-SHA',
}
}
monitor_setup_url_key = 'monitor-setup-url'
def test_monitor_setup(self):
IP = self._ipv6_address
self.monitor_configuration_list = [
{
'htmlUrl': 'https://[%s]:8401/public/feed' % (IP,),
'text': 'testing partition 0',
'title': 'testing partition 0',
'type': 'rss',
'url': 'https://[%s]:8401/share/private/' % (IP,),
'version': 'RSS',
'xmlUrl': 'https://[%s]:8401/public/feed' % (IP,),
},
{
'htmlUrl': 'https://[%s]:8402/public/feed' % (IP,),
'text': 'kedifa',
'title': 'kedifa',
'type': 'rss',
'url': 'https://[%s]:8402/share/private/' % (IP,),
'version': 'RSS',
'xmlUrl': 'https://[%s]:8402/public/feed' % (IP,),
},
{
'htmlUrl': 'https://[%s]:8411/public/feed' % (IP,),
'text': 'caddy-frontend-1',
'title': 'caddy-frontend-1',
'type': 'rss',
'url': 'https://[%s]:8411/share/private/' % (IP,),
'version': 'RSS',
'xmlUrl': 'https://[%s]:8411/public/feed' % (IP,),
},
]
connection_parameter_dict = self\
.computer_partition.getConnectionParameterDict()
self.assertTrue(
self.monitor_setup_url_key in connection_parameter_dict,
'%s not in %s' % (self.monitor_setup_url_key, connection_parameter_dict))
monitor_setup_url_value = connection_parameter_dict[
self.monitor_setup_url_key]
monitor_url_match = re.match(r'.*url=(.*)', monitor_setup_url_value)
self.assertNotEqual(
None, monitor_url_match, '%s not parsable' % (monitor_setup_url_value,))
self.assertEqual(1, len(monitor_url_match.groups()))
monitor_url = monitor_url_match.groups()[0]
monitor_url_split = monitor_url.split('&')
self.assertEqual(
3, len(monitor_url_split), '%s not splitabble' % (monitor_url,))
self.monitor_url = monitor_url_split[0]
monitor_username = monitor_url_split[1].split('=')
self.assertEqual(
2, len(monitor_username), '%s not splittable' % (monitor_username))
monitor_password = monitor_url_split[2].split('=')
self.assertEqual(
2, len(monitor_password), '%s not splittable' % (monitor_password))
self.monitor_username = monitor_username[1]
self.monitor_password = monitor_password[1]
opml_text = requests.get(self.monitor_url, verify=False).text
opml = ET.fromstring(opml_text)
body = opml[1]
self.assertEqual('body', body.tag)
outline_list = body[0].findall('outline')
self.assertEqual(
self.monitor_configuration_list,
[q.attrib for q in outline_list]
)
expected_status_code_list = []
got_status_code_list = []
for monitor_configuration in self.monitor_configuration_list:
status_code = requests.get(
monitor_configuration['url'],
verify=False,
auth=(self.monitor_username, self.monitor_password)
).status_code
expected_status_code_list.append(
{
'url': monitor_configuration['url'],
'status_code': 200
}
)
got_status_code_list.append(
{
'url': monitor_configuration['url'],
'status_code': status_code
}
)
self.assertEqual(
expected_status_code_list,
got_status_code_list
)
def getMasterPartitionPath(self):
# partition w/o etc/trafficserver, but with buildout.cfg
return [
q for q in glob.glob(os.path.join(self.instance_path, '*',))
if not os.path.exists(
os.path.join(q, 'etc', 'trafficserver')) and os.path.exists(
os.path.join(q, 'buildout.cfg'))][0]
def getSlavePartitionPath(self):
# partition w/ etc/trafficserver
return [
q for q in glob.glob(os.path.join(self.instance_path, '*',))
if os.path.exists(os.path.join(q, 'etc', 'trafficserver'))][0]
def test_trafficserver_logrotate(self):
ats_partition = [
q for q in glob.glob(os.path.join(self.instance_path, '*',))
if os.path.exists(os.path.join(q, 'bin', 'trafficserver-rotate'))][0]
ats_log_dir = os.path.join(ats_partition, 'var', 'log', 'trafficserver')
ats_logrotate_dir = os.path.join(
ats_partition, 'srv', 'backup', 'logrotate', 'trafficserver')
ats_rotate = os.path.join(ats_partition, 'bin', 'trafficserver-rotate')
old_file_name = 'log-old.old'
older_file_name = 'log-older.old'
with open(os.path.join(ats_log_dir, old_file_name), 'w') as fh:
fh.write('old')
with open(os.path.join(ats_log_dir, older_file_name), 'w') as fh:
fh.write('older')
# check rotation
result, output = subprocess_status_output([ats_rotate])
self.assertEqual(0, result)
self.assertEqual(
set(['log-old.old.xz', 'log-older.old.xz']),
set(os.listdir(ats_logrotate_dir)))
self.assertFalse(old_file_name + '.xz' in os.listdir(ats_log_dir))
self.assertFalse(older_file_name + '.xz' in os.listdir(ats_log_dir))
with lzma.open(
os.path.join(ats_logrotate_dir, old_file_name + '.xz')) as fh:
self.assertEqual(
'old',
fh.read()
)
with lzma.open(
os.path.join(ats_logrotate_dir, older_file_name + '.xz')) as fh:
self.assertEqual(
'older',
fh.read()
)
# check retention
old_time = time.time() - (400 * 24 * 3600)
os.utime(
os.path.join(ats_logrotate_dir, older_file_name + '.xz'),
(old_time, old_time))
result, output = subprocess_status_output([ats_rotate])
self.assertEqual(0, result)
self.assertEqual(
['log-old.old.xz'],
os.listdir(ats_logrotate_dir))
def test_master_partition_state(self):
parameter_dict = self.parseConnectionParameterDict()
self.assertKeyWithPop('monitor-setup-url', parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, 'master-')
self.assertRejectedSlavePromiseWithPop(parameter_dict)
expected_parameter_dict = {
'monitor-base-url': 'https://[%s]:8401' % self._ipv6_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'domain': 'example.com',
'accepted-slave-amount': '56',
'rejected-slave-amount': '0',
'slave-amount': '56',
'rejected-slave-dict': {
},
'warning-slave-dict': {
'_Url': [
"slave url ' %(backend)s ' has been converted to '%(backend)s'" % {
'backend': self.backend_url}]}
}
self.assertEqual(
expected_parameter_dict,
parameter_dict
)
partition_path = self.getMasterPartitionPath()
# check that monitor cors domains are correctly setup by file presence, as
# we trust monitor stack being tested in proper place and it is too hard
# to have working monitor with local proxy
self.assertTestData(
open(
os.path.join(
partition_path, 'etc', 'httpd-cors.cfg'), 'r').read().strip())
def test_slave_partition_state(self):
partition_path = self.getSlavePartitionPath()
self.assertTrue(
'-grace 2s' in
open(os.path.join(partition_path, 'bin', 'caddy-wrapper'), 'r').read()
)
def test_monitor_conf(self):
monitor_conf_list = glob.glob(
os.path.join(
self.instance_path, '*', 'etc', 'monitor.conf'
))
self.assertEqual(3, len(monitor_conf_list))
expected = [(False, q) for q in monitor_conf_list]
got = [('!py!' in open(q).read(), q) for q in monitor_conf_list]
# check that no monitor.conf in generated configuratio has magic !py!
self.assertEqual(
expected,
got
)
def test_empty(self):
parameter_dict = self.assertSlaveBase('empty')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(httplib.SERVICE_UNAVAILABLE, result.status_code)
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
httplib.FOUND,
result_http.status_code
)
self.assertEqual(
'https://empty.example.com:%s/test-path' % (HTTP_PORT,),
result_http.headers['Location']
)
# check that 404 is as configured
result_missing = fakeHTTPSResult(
'forsuredoesnotexists.example.com', parameter_dict['public-ipv4'], '')
self.assertEqual(httplib.NOT_FOUND, result_missing.status_code)
self.assertEqual(
"""
Instance not found
This instance has not been found.
If this error persists, please check your instance URL and status on S"""
"""lapOS Master.
""",
result_missing.text
)
def test_server_polluted_keys_removed(self):
buildout_file = os.path.join(
self.getMasterPartitionPath(), 'buildout-switch-softwaretype.cfg')
for line in [
q for q in open(buildout_file).readlines()
if q.startswith('config-slave-list') or q.startswith(
'config-extra_slave_instance_list')]:
self.assertFalse('slave_title' in line)
self.assertFalse('slap_software_type' in line)
self.assertFalse('connection-parameter-hash' in line)
self.assertFalse('timestamp' in line)
def assertBackendHeaders(
self, backend_header_dict, domain, source_ip=SOURCE_IP, port=HTTPS_PORT,
proto='https', ignore_header_list=None):
if ignore_header_list is None:
ignore_header_list = []
self.assertFalse('remote_user' in backend_header_dict.keys())
if 'Host' not in ignore_header_list:
self.assertEqual(
backend_header_dict['host'],
'%s:%s' % (domain, port))
self.assertEqual(
backend_header_dict['x-forwarded-for'],
source_ip
)
self.assertEqual(
backend_header_dict['x-forwarded-port'],
port
)
self.assertEqual(
backend_header_dict['x-forwarded-proto'],
proto
)
def test_url(self):
parameter_dict = self.assertSlaveBase('Url')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={
'Timeout': '10', # more than default backend-connect-timeout == 5
'Accept-Encoding': 'gzip',
}
)
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertEqual(j['Incoming Headers']['timeout'], '10')
self.assertFalse('Content-Encoding' in result.headers)
self.assertBackendHeaders(j['Incoming Headers'], parameter_dict['domain'])
self.assertEqual(
'secured=value;secure, nonsecured=value',
result.headers['Set-Cookie']
)
# check access log
log_file = glob.glob(
os.path.join(
self.instance_path, '*', 'var', 'log', 'httpd', '_Url_access_log'
))[0]
log_regexp = r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} - - ' \
r'\[\d{2}\/.{3}\/\d{4}\:\d{2}\:\d{2}\:\d{2} \+\d{4}\] ' \
r'"GET \/test-path\/deep\/..\/.\/deeper HTTP\/1.1" \d{3} ' \
r'\d+ "-" "python-requests.*" \d+'
self.assertRegexpMatches(
open(log_file, 'r').readlines()[-1],
log_regexp)
# check backend log
log_file = glob.glob(
os.path.join(
self.instance_path, '*', 'var', 'log', 'httpd', '_Url_backend_log'
))[0]
log_regexp = r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+ ' \
r'\[\d{2}\/.{3}\/\d{4}\:\d{2}\:\d{2}\:\d{2}.\d{3}\] ' \
r'http-backend _Url-http\/backend ' \
r'\d+/\d+\/\d+\/\d+\/\d+ ' \
r'200 \d+ - - ---- ' \
r'\d\/\d\/\d\/\d\/\d \d\/\d ' \
r'"GET /test-path/deeper HTTP/1.1"'
self.assertRegexpMatches(
open(log_file, 'r').readlines()[-1],
log_regexp)
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
httplib.FOUND,
result_http.status_code
)
self.assertEqual(
'https://url.example.com:%s/test-path/deeper' % (HTTP_PORT,),
result_http.headers['Location']
)
# check that timeouts are correctly set in the haproxy configuration
backend_configuration_file = glob.glob(os.path.join(
self.instance_path, '*', 'etc', 'backend-haproxy.cfg'))[0]
with open(backend_configuration_file) as fh:
content = fh.read()
self.assertTrue("""backend _Url-http
timeout server 12s
timeout connect 5s
retries 3""" in content)
self.assertTrue(""" timeout queue 60s
timeout server 12s
timeout client 12s
timeout connect 5s
retries 3""" in content)
def test_auth_to_backend(self):
parameter_dict = self.assertSlaveBase('auth-to-backend')
# 1. fetch certificate from backend-client-caucase-url
master_parameter_dict = self.parseConnectionParameterDict()
caucase_url = master_parameter_dict['backend-client-caucase-url']
ca_certificate = requests.get(caucase_url + '/cas/crt/ca.crt.pem')
assert ca_certificate.status_code == httplib.OK
ca_certificate_file = os.path.join(
self.working_directory, 'ca-backend-client.crt.pem')
with open(ca_certificate_file, 'w') as fh:
fh.write(ca_certificate.text)
# 2. start backend with this certificate
class OwnTestHandler(TestHandler):
identification = 'Auth Backend'
server_https_auth = HTTPServer(
(self._ipv4_address, self._server_https_auth_port),
OwnTestHandler)
server_https_auth.socket = ssl.wrap_socket(
server_https_auth.socket,
certfile=self.test_server_certificate_file.name,
cert_reqs=ssl.CERT_REQUIRED,
ca_certs=ca_certificate_file,
server_side=True)
backend_https_auth_url = 'https://%s:%s/' \
% server_https_auth.server_address
server_https_auth_process = multiprocessing.Process(
target=server_https_auth.serve_forever, name='HTTPSServerAuth')
server_https_auth_process.start()
self.logger.debug('Started process %s' % (server_https_auth_process,))
try:
# 3. assert that you can't fetch nothing without key
try:
requests.get(backend_https_auth_url, verify=False)
except Exception:
pass
else:
self.fail(
'Access to %r shall be not possible without certificate' % (
backend_https_auth_url,))
# 4. check that you can access this backend via frontend
# (so it means that auth to backend worked)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={
'Timeout': '10', # more than default backend-connect-timeout == 5
'Accept-Encoding': 'gzip',
}
)
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertEqual(j['Incoming Headers']['timeout'], '10')
self.assertFalse('Content-Encoding' in result.headers)
self.assertBackendHeaders(
j['Incoming Headers'], parameter_dict['domain'])
self.assertEqual(
'secured=value;secure, nonsecured=value',
result.headers['Set-Cookie']
)
# proof that proper backend was accessed
self.assertEqual(
'Auth Backend',
result.headers['X-Backend-Identification']
)
finally:
self.logger.debug('Stopping process %s' % (server_https_auth_process,))
server_https_auth_process.join(10)
server_https_auth_process.terminate()
time.sleep(0.1)
if server_https_auth_process.is_alive():
self.logger.warning(
'Process %s still alive' % (server_https_auth_process, ))
def test_auth_to_backend_not_configured(self):
parameter_dict = self.assertSlaveBase('auth-to-backend-not-configured')
# 1. fetch certificate from backend-client-caucase-url
master_parameter_dict = self.parseConnectionParameterDict()
caucase_url = master_parameter_dict['backend-client-caucase-url']
ca_certificate = requests.get(caucase_url + '/cas/crt/ca.crt.pem')
assert ca_certificate.status_code == httplib.OK
ca_certificate_file = os.path.join(
self.working_directory, 'ca-backend-client.crt.pem')
with open(ca_certificate_file, 'w') as fh:
fh.write(ca_certificate.text)
# 2. start backend with this certificate
class OwnTestHandler(TestHandler):
identification = 'Auth Backend'
server_https_auth = HTTPServer(
(self._ipv4_address, self._server_https_auth_port),
OwnTestHandler)
server_https_auth.socket = ssl.wrap_socket(
server_https_auth.socket,
certfile=self.test_server_certificate_file.name,
cert_reqs=ssl.CERT_REQUIRED,
ca_certs=ca_certificate_file,
server_side=True)
backend_https_auth_url = 'https://%s:%s/' \
% server_https_auth.server_address
server_https_auth_process = multiprocessing.Process(
target=server_https_auth.serve_forever, name='HTTPSServerAuth')
server_https_auth_process.start()
self.logger.debug('Started process %s' % (server_https_auth_process,))
try:
# 3. assert that you can't fetch nothing without key
try:
requests.get(backend_https_auth_url, verify=False)
except Exception:
pass
else:
self.fail(
'Access to %r shall be not possible without certificate' % (
backend_https_auth_url,))
# 4. check that you can access this backend via frontend
# (so it means that auth to backend worked)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={
'Timeout': '10', # more than default backend-connect-timeout == 5
'Accept-Encoding': 'gzip',
}
)
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(
result.status_code,
httplib.BAD_GATEWAY
)
finally:
self.logger.debug('Stopping process %s' % (server_https_auth_process,))
server_https_auth_process.join(10)
server_https_auth_process.terminate()
time.sleep(0.1)
if server_https_auth_process.is_alive():
self.logger.warning(
'Process %s still alive' % (server_https_auth_process, ))
def test_auth_to_backend_backend_ignore(self):
parameter_dict = self.assertSlaveBase('auth-to-backend-backend-ignore')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={
'Timeout': '10', # more than default backend-connect-timeout == 5
'Accept-Encoding': 'gzip',
}
)
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertEqual(j['Incoming Headers']['timeout'], '10')
self.assertFalse('Content-Encoding' in result.headers)
self.assertBackendHeaders(j['Incoming Headers'], parameter_dict['domain'])
self.assertEqual(
'secured=value;secure, nonsecured=value',
result.headers['Set-Cookie']
)
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
httplib.FOUND,
result_http.status_code
)
self.assertEqual(
'https://authtobackendbackendignore.example.com:%s/test-path/deeper' % (
HTTP_PORT,),
result_http.headers['Location']
)
def test_compressed_result(self):
parameter_dict = self.assertSlaveBase('Url')
result_compressed = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={
'Accept-Encoding': 'gzip',
'Compress': '1',
}
)
self.assertEqual(
'gzip',
result_compressed.headers['Content-Encoding']
)
# Assert that no tampering was done with the request
# (compression/decompression)
# Backend compresses with 0 level, so decompression/compression
# would change somthing
self.assertEqual(
result_compressed.headers['Content-Length'],
result_compressed.headers['Backend-Content-Length']
)
result_not_compressed = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={
'Accept-Encoding': 'gzip',
}
)
self.assertFalse('Content-Encoding' in result_not_compressed.headers)
def test_no_content_type_alter(self):
parameter_dict = self.assertSlaveBase('Url')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={
'Accept-Encoding': 'gzip',
'X-Reply-Body': base64.b64encode(
b"""
Tove
Jani
Reminder
Don't forget me this weekend!
"""),
'X-Drop-Header': 'Content-Type'
}
)
self.assertEqual(
'text/xml; charset=utf-8',
result.headers['Content-Type']
)
@skip('Feature postponed')
def test_url_ipv6_access(self):
parameter_dict = self.parseSlaveParameterDict('url')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'url.example.com',
'replication_number': '1',
'url': 'http://url.example.com',
'site_url': 'http://url.example.com',
'secure_access': 'https://url.example.com',
'public-ipv4': self._ipv4_address,
},
parameter_dict
)
result_ipv6 = fakeHTTPSResult(
parameter_dict['domain'], self._ipv6_address, 'test-path',
source_ip=self._ipv6_address)
self.assertEqual(
self._ipv6_address,
result_ipv6.json()['Incoming Headers']['x-forwarded-for']
)
self.assertEqual(
self.certificate_pem,
der2pem(result_ipv6.peercert))
self.assertEqualResultJson(result_ipv6, 'Path', '/test-path')
def test_type_zope_path(self):
parameter_dict = self.assertSlaveBase('type-zope-path')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(
result,
'Path',
'/VirtualHostBase/'
'https//typezopepath.example.com:443/path/to/some/resource'
'/VirtualHostRoot/'
'test-path/deeper'
)
def test_type_zope_default_path(self):
parameter_dict = self.assertSlaveBase('type-zope-default-path')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], '')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(
httplib.MOVED_PERMANENTLY,
result.status_code
)
self.assertEqual(
'https://typezopedefaultpath.example.com:%s/'
'default-path/to/some/resource' % (
HTTPS_PORT,),
result.headers['Location']
)
def test_server_alias(self):
parameter_dict = self.assertSlaveBase('server-alias')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
result = fakeHTTPSResult(
'alias1.example.com', parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
result = fakeHTTPSResult(
'alias2.example.com', parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
def test_server_alias_empty(self):
parameter_dict = self.assertSlaveBase('server-alias-empty')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={
'Timeout': '10', # more than default backend-connect-timeout == 5
'Accept-Encoding': 'gzip',
}
)
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertEqual(j['Incoming Headers']['timeout'], '10')
self.assertFalse('Content-Encoding' in result.headers)
self.assertBackendHeaders(j['Incoming Headers'], parameter_dict['domain'])
self.assertEqual(
'secured=value;secure, nonsecured=value',
result.headers['Set-Cookie']
)
def test_server_alias_wildcard(self):
parameter_dict = self.parseSlaveParameterDict('server-alias-wildcard')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'serveraliaswildcard.example.com',
'replication_number': '1',
'url': 'http://serveraliaswildcard.example.com',
'site_url': 'http://serveraliaswildcard.example.com',
'secure_access': 'https://serveraliaswildcard.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
result = fakeHTTPSResult(
'wild.alias1.example.com', parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_server_alias_duplicated(self):
parameter_dict = self.parseSlaveParameterDict('server-alias-duplicated')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'serveraliasduplicated.example.com',
'replication_number': '1',
'url': 'http://serveraliasduplicated.example.com',
'site_url': 'http://serveraliasduplicated.example.com',
'secure_access': 'https://serveraliasduplicated.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
result = fakeHTTPSResult(
'alias3.example.com', parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_server_alias_custom_domain_duplicated(self):
parameter_dict = self.parseSlaveParameterDict(
'server-alias_custom_domain-duplicated')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'alias4.example.com',
'replication_number': '1',
'url': 'http://alias4.example.com',
'site_url': 'http://alias4.example.com',
'secure_access': 'https://alias4.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
@skip('Feature postponed')
def test_check_error_log(self):
# Caddy: Need to implement similar thing like check-error-on-apache-log
raise NotImplementedError(self.id())
def test_ssl_ca_crt(self):
parameter_dict = self.parseSlaveParameterDict(
'custom_domain_ssl_crt_ssl_key_ssl_ca_crt')
self.assertLogAccessUrlWithPop(parameter_dict)
generate_auth, upload_url = self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'customdomainsslcrtsslkeysslcacrt.example.com',
'replication_number': '1',
'url': 'http://customdomainsslcrtsslkeysslcacrt.example.com',
'site_url': 'http://customdomainsslcrtsslkeysslcacrt.example.com',
'secure_access':
'https://customdomainsslcrtsslkeysslcacrt.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
# as now the place to put the key is known put the key there
auth = requests.get(
generate_auth,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, auth.status_code)
data = self.customdomain_ca_certificate_pem + \
self.customdomain_ca_key_pem + \
self.ca.certificate_pem
upload = requests.put(
upload_url + auth.text,
data=data,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, upload.status_code)
self.runKedifaUpdater()
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.customdomain_ca_certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
certificate_file_list = glob.glob(os.path.join(
self.instance_path, '*', 'srv', 'autocert',
'_custom_domain_ssl_crt_ssl_key_ssl_ca_crt.pem'))
self.assertEqual(1, len(certificate_file_list))
certificate_file = certificate_file_list[0]
with open(certificate_file) as out:
self.assertEqual(data, out.read())
def test_ssl_ca_crt_only(self):
parameter_dict = self.parseSlaveParameterDict('ssl_ca_crt_only')
self.assertLogAccessUrlWithPop(parameter_dict)
generate_auth, upload_url = self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'sslcacrtonly.example.com',
'replication_number': '1',
'url': 'http://sslcacrtonly.example.com',
'site_url': 'http://sslcacrtonly.example.com',
'secure_access':
'https://sslcacrtonly.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
# as now the place to put the key is known put the key there
auth = requests.get(
generate_auth,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, auth.status_code)
data = self.ca.certificate_pem
upload = requests.put(
upload_url + auth.text,
data=data,
verify=self.ca_certificate_file)
self.assertEqual(httplib.UNPROCESSABLE_ENTITY, upload.status_code)
self.assertEqual('Key incorrect', upload.text)
def test_ssl_ca_crt_garbage(self):
parameter_dict = self.parseSlaveParameterDict('ssl_ca_crt_garbage')
self.assertLogAccessUrlWithPop(parameter_dict)
generate_auth, upload_url = self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'sslcacrtgarbage.example.com',
'replication_number': '1',
'url': 'http://sslcacrtgarbage.example.com',
'site_url': 'http://sslcacrtgarbage.example.com',
'secure_access':
'https://sslcacrtgarbage.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
# as now the place to put the key is known put the key there
auth = requests.get(
generate_auth,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, auth.status_code)
_, ca_key_pem, csr, _ = createCSR(
parameter_dict['domain'])
_, ca_certificate_pem = self.ca.signCSR(csr)
data = ca_certificate_pem + ca_key_pem + 'some garbage'
upload = requests.put(
upload_url + auth.text,
data=data,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, upload.status_code)
self.runKedifaUpdater()
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
ca_certificate_pem,
der2pem(result.peercert)
)
self.assertEqualResultJson(result, 'Path', '/test-path')
certificate_file_list = glob.glob(os.path.join(
self.instance_path, '*', 'srv', 'autocert',
'_ssl_ca_crt_garbage.pem'))
self.assertEqual(1, len(certificate_file_list))
certificate_file = certificate_file_list[0]
with open(certificate_file) as out:
self.assertEqual(data, out.read())
def test_ssl_ca_crt_does_not_match(self):
parameter_dict = self.parseSlaveParameterDict('ssl_ca_crt_does_not_match')
self.assertLogAccessUrlWithPop(parameter_dict)
generate_auth, upload_url = self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'sslcacrtdoesnotmatch.example.com',
'replication_number': '1',
'url': 'http://sslcacrtdoesnotmatch.example.com',
'site_url': 'http://sslcacrtdoesnotmatch.example.com',
'secure_access':
'https://sslcacrtdoesnotmatch.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
# as now the place to put the key is known put the key there
auth = requests.get(
generate_auth,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, auth.status_code)
data = self.certificate_pem + self.key_pem + self.ca.certificate_pem
upload = requests.put(
upload_url + auth.text,
data=data,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, upload.status_code)
self.runKedifaUpdater()
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
certificate_file_list = glob.glob(os.path.join(
self.instance_path, '*', 'srv', 'autocert',
'_ssl_ca_crt_does_not_match.pem'))
self.assertEqual(1, len(certificate_file_list))
certificate_file = certificate_file_list[0]
with open(certificate_file) as out:
self.assertEqual(data, out.read())
def test_https_only(self):
parameter_dict = self.assertSlaveBase('https-only')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqualResultJson(result_http, 'Path', '/test-path/deeper')
def test_custom_domain(self):
reference = 'custom_domain'
hostname = 'mycustomdomain'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, '')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_custom_domain_server_alias(self):
reference = 'custom_domain_server_alias'
hostname = 'mycustomdomainserveralias'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, '')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
result = fakeHTTPSResult(
'mycustomdomainserveralias1.example.com', parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
def test_custom_domain_wildcard(self):
parameter_dict = self.parseSlaveParameterDict('custom_domain_wildcard')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': '*.customdomain.example.com',
'replication_number': '1',
'url': 'http://*.customdomain.example.com',
'site_url': 'http://*.customdomain.example.com',
'secure_access': 'https://*.customdomain.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
'wild.customdomain.example.com', parameter_dict['public-ipv4'],
'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_custom_domain_ssl_crt_ssl_key(self):
reference = 'custom_domain_ssl_crt_ssl_key'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
generate_auth, upload_url = self.assertKedifaKeysWithPop(parameter_dict)
hostname = reference.translate(None, '_-')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
# as now the place to put the key is known put the key there
auth = requests.get(
generate_auth,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, auth.status_code)
data = self.customdomain_certificate_pem + \
self.customdomain_key_pem
upload = requests.put(
upload_url + auth.text,
data=data,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, upload.status_code)
self.runKedifaUpdater()
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.customdomain_certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_type_zope(self):
parameter_dict = self.assertSlaveBase('type-zope')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertBackendHeaders(j['Incoming Headers'], parameter_dict['domain'])
self.assertEqualResultJson(
result,
'Path',
'/VirtualHostBase/https//typezope.example.com:443/'
'/VirtualHostRoot/test-path/deeper'
)
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
httplib.FOUND,
result.status_code
)
self.assertEqual(
'https://typezope.example.com:%s/test-path/deep/.././deeper' % (
HTTP_PORT,),
result.headers['Location']
)
def test_type_zope_prefer_gzip_encoding_to_backend_https_only(self):
parameter_dict = self.assertSlaveBase(
'type-zope-prefer-gzip-encoding-to-backend-https-only')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertBackendHeaders(j['Incoming Headers'], parameter_dict['domain'])
self.assertEqualResultJson(
result,
'Path',
'/VirtualHostBase/https//'
'typezopeprefergzipencodingtobackendhttpsonly.example.com:443/'
'/VirtualHostRoot/test-path/deeper'
)
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqualResultJson(
result,
'Path',
'/VirtualHostBase/http//'
'typezopeprefergzipencodingtobackendhttpsonly.example.com:80/'
'/VirtualHostRoot/test-path/deeper'
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={'Accept-Encoding': 'gzip, deflate'})
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertBackendHeaders(j['Incoming Headers'], parameter_dict['domain'])
self.assertEqualResultJson(
result,
'Path',
'/VirtualHostBase/https//'
'typezopeprefergzipencodingtobackendhttpsonly.example.com:443/'
'/VirtualHostRoot/test-path/deeper'
)
self.assertEqual(
'gzip', result.json()['Incoming Headers']['accept-encoding'])
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={'Accept-Encoding': 'gzip, deflate'})
self.assertEqualResultJson(
result,
'Path',
'/VirtualHostBase/http//'
'typezopeprefergzipencodingtobackendhttpsonly.example.com:80/'
'/VirtualHostRoot/test-path/deeper'
)
self.assertEqual(
'gzip', result.json()['Incoming Headers']['accept-encoding'])
def test_type_zope_prefer_gzip_encoding_to_backend(self):
parameter_dict = self.assertSlaveBase(
'type-zope-prefer-gzip-encoding-to-backend')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertBackendHeaders(j['Incoming Headers'], parameter_dict['domain'])
self.assertEqualResultJson(
result,
'Path',
'/VirtualHostBase/https//'
'typezopeprefergzipencodingtobackend.example.com:443/'
'/VirtualHostRoot/test-path/deeper'
)
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
httplib.FOUND,
result.status_code
)
self.assertEqual(
'https://%s:%s/test-path/deep/.././deeper' % (
parameter_dict['domain'], HTTP_PORT),
result.headers['Location']
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={'Accept-Encoding': 'gzip, deflate'})
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertBackendHeaders(j['Incoming Headers'], parameter_dict['domain'])
self.assertEqualResultJson(
result,
'Path',
'/VirtualHostBase/https//'
'typezopeprefergzipencodingtobackend.example.com:443/'
'/VirtualHostRoot/test-path/deeper'
)
self.assertEqual(
'gzip', result.json()['Incoming Headers']['accept-encoding'])
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={'Accept-Encoding': 'gzip, deflate'})
self.assertEqual(
httplib.FOUND,
result.status_code
)
self.assertEqual(
'https://%s:%s/test-path/deep/.././deeper' % (
parameter_dict['domain'], HTTP_PORT),
result.headers['Location']
)
def test_type_zope_virtualhostroot_http_port(self):
parameter_dict = self.assertSlaveBase(
'type-zope-virtualhostroot-http-port')
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqualResultJson(
result,
'Path',
'/VirtualHostBase/http//typezopevirtualhostroothttpport'
'.example.com:12345//VirtualHostRoot/test-path'
)
def test_type_zope_virtualhostroot_https_port(self):
parameter_dict = self.assertSlaveBase(
'type-zope-virtualhostroot-https-port')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(
result,
'Path',
'/VirtualHostBase/https//typezopevirtualhostroothttpsport'
'.example.com:12345//VirtualHostRoot/test-path'
)
def test_type_notebook(self):
reference = 'type-notebook'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
hostname = reference.translate(None, '_-')
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path',
HTTPS_PORT)
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test/terminals/websocket/test',
HTTPS_PORT)
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/terminals/websocket')
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
def test_type_websocket(self):
parameter_dict = self.assertSlaveBase(
'type-websocket')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path',
headers={'Connection': 'Upgrade'})
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(
result,
'Path',
'/test-path'
)
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertBackendHeaders(j['Incoming Headers'], parameter_dict['domain'])
self.assertEqual(
'Upgrade',
j['Incoming Headers']['connection']
)
self.assertTrue('x-real-ip' in j['Incoming Headers'])
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
def test_type_websocket_websocket_transparent_false(self):
parameter_dict = self.assertSlaveBase(
'type-websocket-websocket-transparent-false')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path',
headers={'Connection': 'Upgrade'})
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(
result,
'Path',
'/test-path'
)
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
parsed = urlparse.urlparse(self.backend_url)
self.assertBackendHeaders(
j['Incoming Headers'], parsed.hostname, port='17', proto='irc',
ignore_header_list=['Host'])
self.assertEqual(
'Upgrade',
j['Incoming Headers']['connection']
)
self.assertFalse('x-real-ip' in j['Incoming Headers'])
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
def test_type_websocket_websocket_path_list(self):
parameter_dict = self.assertSlaveBase(
'type-websocket-websocket-path-list')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path',
headers={'Connection': 'Upgrade'})
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(
result,
'Path',
'/test-path'
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertBackendHeaders(j['Incoming Headers'], parameter_dict['domain'])
self.assertTrue('x-real-ip' in j['Incoming Headers'])
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'ws/test-path',
headers={'Connection': 'Upgrade'})
self.assertEqualResultJson(
result,
'Path',
'/ws/test-path'
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertBackendHeaders(j['Incoming Headers'], parameter_dict['domain'])
self.assertEqual(
'Upgrade',
j['Incoming Headers']['connection']
)
self.assertTrue('x-real-ip' in j['Incoming Headers'])
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'with%20space/test-path', headers={'Connection': 'Upgrade'})
self.assertEqualResultJson(
result,
'Path',
'/with%20space/test-path'
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertBackendHeaders(j['Incoming Headers'], parameter_dict['domain'])
self.assertEqual(
'Upgrade',
j['Incoming Headers']['connection']
)
self.assertTrue('x-real-ip' in j['Incoming Headers'])
def test_type_websocket_websocket_path_list_websocket_transparent_false(
self):
parameter_dict = self.assertSlaveBase(
'type-websocket-websocket-path-list-websocket-transparent-false')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path',
headers={'Connection': 'Upgrade'})
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(
result,
'Path',
'/test-path'
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
parsed = urlparse.urlparse(self.backend_url)
self.assertBackendHeaders(
j['Incoming Headers'], parsed.hostname, port='17', proto='irc',
ignore_header_list=['Host'])
self.assertFalse('x-real-ip' in j['Incoming Headers'])
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'ws/test-path',
headers={'Connection': 'Upgrade'})
self.assertEqualResultJson(
result,
'Path',
'/ws/test-path'
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertBackendHeaders(
j['Incoming Headers'], parsed.hostname, port='17', proto='irc',
ignore_header_list=['Host'])
self.assertEqual(
'Upgrade',
j['Incoming Headers']['connection']
)
self.assertFalse('x-real-ip' in j['Incoming Headers'])
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'with%20space/test-path', headers={'Connection': 'Upgrade'})
self.assertEqualResultJson(
result,
'Path',
'/with%20space/test-path'
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertBackendHeaders(
j['Incoming Headers'], parsed.hostname, port='17', proto='irc',
ignore_header_list=['Host'])
self.assertEqual(
'Upgrade',
j['Incoming Headers']['connection']
)
self.assertFalse('x-real-ip' in j['Incoming Headers'])
@skip('Feature postponed')
def test_type_eventsource(self):
# Caddy: For event source, if I understand
# https://github.com/mholt/caddy/issues/1355 correctly, we could use
# Caddy as a proxy in front of nginx-push-stream . If we have a
# "central shared" caddy instance, can it handle keeping connections
# opens for many clients ?
parameter_dict = self.parseSlaveParameterDict('type-eventsource')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'typeeventsource.nginx.example.com',
'replication_number': '1',
'url': 'http://typeeventsource.nginx.example.com',
'site_url': 'http://typeeventsource.nginx.example.com',
'secure_access': 'https://typeeventsource.nginx.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'pub',
# NGINX_HTTPS_PORT
)
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(
'',
result.content
)
headers = result.headers.copy()
self.assertKeyWithPop('Expires', headers)
self.assertKeyWithPop('Date', headers)
self.assertEqual(
{
'X-Nginx-PushStream-Explain': 'No channel id provided.',
'Content-Length': '0',
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Connection': 'keep-alive',
'Server': 'nginx'
},
headers
)
def test_type_redirect(self):
parameter_dict = self.assertSlaveBase('type-redirect')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(
httplib.FOUND,
result.status_code
)
self.assertEqual(
'%stest-path/deeper' % (self.backend_url,),
result.headers['Location']
)
def test_type_redirect_custom_domain(self):
reference = 'type-redirect-custom_domain'
hostname = 'customdomaintyperedirect'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, '')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(
httplib.FOUND,
result.status_code
)
self.assertEqual(
'%stest-path/deeper' % (self.backend_url,),
result.headers['Location']
)
def test_ssl_proxy_verify_ssl_proxy_ca_crt_unverified(self):
parameter_dict = self.parseSlaveParameterDict(
'ssl-proxy-verify_ssl_proxy_ca_crt-unverified')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'sslproxyverifysslproxycacrtunverified.example.com',
'replication_number': '1',
'url': 'http://sslproxyverifysslproxycacrtunverified.example.com',
'site_url':
'http://sslproxyverifysslproxycacrtunverified.example.com',
'secure_access':
'https://sslproxyverifysslproxycacrtunverified.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(
httplib.SERVICE_UNAVAILABLE,
result.status_code
)
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
httplib.FOUND,
result_http.status_code
)
self.assertEqual(
'https://sslproxyverifysslproxycacrtunverified.example.com:%s/'
'test-path' % (HTTP_PORT,),
result_http.headers['Location']
)
def test_ssl_proxy_verify_ssl_proxy_ca_crt(self):
parameter_dict = self.assertSlaveBase('ssl-proxy-verify_ssl_proxy_ca_crt')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertBackendHeaders(j['Incoming Headers'], parameter_dict['domain'])
self.assertFalse('Content-Encoding' in result.headers)
self.assertEqual(
'secured=value;secure, nonsecured=value',
result.headers['Set-Cookie']
)
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
httplib.FOUND,
result_http.status_code
)
self.assertEqual(
'https://sslproxyverifysslproxycacrt.example.com:%s/test-path' % (
HTTP_PORT,),
result_http.headers['Location']
)
def test_ssl_proxy_verify_unverified(self):
parameter_dict = self.assertSlaveBase('ssl-proxy-verify-unverified')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(
httplib.SERVICE_UNAVAILABLE,
result.status_code
)
def test_enable_cache_ssl_proxy_verify_ssl_proxy_ca_crt_unverified(self):
parameter_dict = self.parseSlaveParameterDict(
'enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt-unverified')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain':
'enablecachesslproxyverifysslproxycacrtunverified.example.com',
'replication_number': '1',
'url':
'http://enablecachesslproxyverifysslproxycacrtunverified.example.com',
'site_url':
'http://enablecachesslproxyverifysslproxycacrtunverified.example.com',
'secure_access':
'https://enablecachesslproxyverifysslproxycacrtunverified.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(
httplib.SERVICE_UNAVAILABLE,
result.status_code
)
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deeper')
self.assertEqual(
httplib.FOUND,
result_http.status_code
)
self.assertEqual(
'https://enablecachesslproxyverifysslproxycacrtunverified.example.com'
':%s/test-path/deeper' % (HTTP_PORT,),
result_http.headers['Location']
)
def test_enable_cache_ssl_proxy_verify_ssl_proxy_ca_crt(self):
parameter_dict = self.assertSlaveBase(
'enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
self.assertKeyWithPop('Age', headers)
# drop keys appearing randomly in headers
headers.pop('Transfer-Encoding', None)
headers.pop('Content-Length', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-type': 'application/json',
'Set-Cookie': 'secured=value;secure, nonsecured=value',
},
headers
)
def test_enable_cache_ssl_proxy_verify_unverified(self):
parameter_dict = self.assertSlaveBase(
'enable_cache-ssl-proxy-verify-unverified')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(
httplib.SERVICE_UNAVAILABLE,
result.status_code
)
def test_type_zope_ssl_proxy_verify_ssl_proxy_ca_crt_unverified(self):
parameter_dict = self.parseSlaveParameterDict(
'type-zope-ssl-proxy-verify_ssl_proxy_ca_crt-unverified')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'typezopesslproxyverifysslproxycacrtunverified.example.com',
'replication_number': '1',
'url':
'http://typezopesslproxyverifysslproxycacrtunverified.example.com',
'site_url':
'http://typezopesslproxyverifysslproxycacrtunverified.example.com',
'secure_access':
'https://typezopesslproxyverifysslproxycacrtunverified.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(
httplib.SERVICE_UNAVAILABLE,
result.status_code
)
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
httplib.FOUND,
result_http.status_code
)
self.assertEqual(
'https://typezopesslproxyverifysslproxycacrtunverified.example.com:%s/'
'test-path' % (HTTP_PORT,),
result_http.headers['Location']
)
def test_type_zope_ssl_proxy_verify_ssl_proxy_ca_crt(self):
parameter_dict = self.assertSlaveBase(
'type-zope-ssl-proxy-verify_ssl_proxy_ca_crt')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertBackendHeaders(j['Incoming Headers'], parameter_dict['domain'])
self.assertEqualResultJson(
result,
'Path',
'/VirtualHostBase/https//'
'typezopesslproxyverifysslproxycacrt.example.com:443/'
'/VirtualHostRoot/test-path'
)
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
httplib.FOUND,
result.status_code
)
self.assertEqual(
'https://typezopesslproxyverifysslproxycacrt.example.com:'
'%s/test-path' % (HTTP_PORT,),
result.headers['Location']
)
def test_type_zope_ssl_proxy_verify_unverified(self):
parameter_dict = self.assertSlaveBase(
'type-zope-ssl-proxy-verify-unverified')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(
httplib.SERVICE_UNAVAILABLE,
result.status_code
)
def test_monitor_ipv6_test(self):
parameter_dict = self.assertSlaveBase('monitor-ipv6-test')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(httplib.SERVICE_UNAVAILABLE, result.status_code)
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
httplib.FOUND,
result_http.status_code
)
self.assertEqual(
'https://monitoripv6test.example.com:%s/test-path' % (HTTP_PORT,),
result_http.headers['Location']
)
monitor_file = glob.glob(
os.path.join(
self.instance_path, '*', 'etc', 'plugin',
'check-_monitor-ipv6-test-ipv6-packet-list-test.py'))[0]
# get promise module and check that parameters are ok
self.assertEqual(
getPromisePluginParameterDict(monitor_file),
{
'frequency': '720',
'address': 'monitor-ipv6-test'
}
)
def test_monitor_ipv4_test(self):
parameter_dict = self.assertSlaveBase('monitor-ipv4-test')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(httplib.SERVICE_UNAVAILABLE, result.status_code)
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
httplib.FOUND,
result_http.status_code
)
self.assertEqual(
'https://monitoripv4test.example.com:%s/test-path' % (HTTP_PORT,),
result_http.headers['Location']
)
monitor_file = glob.glob(
os.path.join(
self.instance_path, '*', 'etc', 'plugin',
'check-_monitor-ipv4-test-ipv4-packet-list-test.py'))[0]
# get promise module and check that parameters are ok
self.assertEqual(
getPromisePluginParameterDict(monitor_file),
{
'frequency': '720',
'ipv4': 'true',
'address': 'monitor-ipv4-test',
}
)
def test_ciphers(self):
parameter_dict = self.assertSlaveBase('ciphers')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(httplib.SERVICE_UNAVAILABLE, result.status_code)
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
httplib.FOUND,
result_http.status_code
)
self.assertEqual(
'https://ciphers.example.com:%s/test-path' % (HTTP_PORT,),
result_http.headers['Location']
)
configuration_file = glob.glob(
os.path.join(
self.instance_path, '*', 'etc', 'caddy-slave-conf.d', '_ciphers.conf'
))[0]
self.assertTrue(
'ciphers RSA-3DES-EDE-CBC-SHA RSA-AES128-CBC-SHA'
in open(configuration_file).read()
)
def test_enable_cache_custom_domain(self):
reference = 'enable_cache_custom_domain'
hostname = 'customdomainenablecache'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, '')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper', headers={
'X-Reply-Header-Cache-Control': 'max-age=1, stale-while-'
'revalidate=3600, stale-if-error=3600'})
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
self.assertKeyWithPop('Age', headers)
# drop keys appearing randomly in headers
headers.pop('Transfer-Encoding', None)
headers.pop('Content-Length', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-type': 'application/json',
'Set-Cookie': 'secured=value;secure, nonsecured=value',
'Cache-Control': 'max-age=1, stale-while-revalidate=3600, '
'stale-if-error=3600'
},
headers
)
backend_headers = result.json()['Incoming Headers']
self.assertBackendHeaders(backend_headers, parameter_dict['domain'])
via = backend_headers.pop('via', None)
self.assertNotEqual(via, None)
self.assertRegexpMatches(
via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/7.1.11\)$'
)
def test_enable_cache_server_alias(self):
parameter_dict = self.assertSlaveBase('enable_cache_server_alias')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper', headers={
'X-Reply-Header-Cache-Control': 'max-age=1, stale-while-'
'revalidate=3600, stale-if-error=3600'})
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
self.assertKeyWithPop('Age', headers)
# drop keys appearing randomly in headers
headers.pop('Transfer-Encoding', None)
headers.pop('Content-Length', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-type': 'application/json',
'Set-Cookie': 'secured=value;secure, nonsecured=value',
'Cache-Control': 'max-age=1, stale-while-revalidate=3600, '
'stale-if-error=3600'
},
headers
)
backend_headers = result.json()['Incoming Headers']
self.assertBackendHeaders(backend_headers, parameter_dict['domain'])
via = backend_headers.pop('via', None)
self.assertNotEqual(via, None)
self.assertRegexpMatches(
via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/7.1.11\)$'
)
result = fakeHTTPResult(
'enablecacheserveralias1.example.com', parameter_dict['public-ipv4'],
'test-path/deep/.././deeper', headers={
'X-Reply-Header-Cache-Control': 'max-age=1, stale-while-'
'revalidate=3600, stale-if-error=3600'})
self.assertEqual(
httplib.FOUND,
result.status_code
)
self.assertEqual(
'https://enablecacheserveralias1.example.com:%s/test-path/deeper' % (
HTTP_PORT,),
result.headers['Location']
)
def test_enable_cache(self):
parameter_dict = self.assertSlaveBase('enable_cache')
source_ip = '127.0.0.1'
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper', headers={
'X-Reply-Header-Cache-Control': 'max-age=1, stale-while-'
'revalidate=3600, stale-if-error=3600',
},
source_ip=source_ip
)
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
self.assertKeyWithPop('Age', headers)
# drop keys appearing randomly in headers
headers.pop('Transfer-Encoding', None)
headers.pop('Content-Length', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-type': 'application/json',
'Set-Cookie': 'secured=value;secure, nonsecured=value',
'Cache-Control': 'max-age=1, stale-while-revalidate=3600, '
'stale-if-error=3600'
},
headers
)
backend_headers = result.json()['Incoming Headers']
self.assertBackendHeaders(backend_headers, parameter_dict['domain'])
via = backend_headers.pop('via', None)
self.assertNotEqual(via, None)
self.assertRegexpMatches(
via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/7.1.11\)$'
)
# check stale-if-error support (assumes stale-while-revalidate is same)
# wait a bit for max-age to expire
time.sleep(2)
# real check: cache access provides old data, access cache directly, as
# caddy has to be stopped
try:
# stop the backend, to have error on while connecting to it
self.stopServerProcess()
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper', headers={
'X-Reply-Header-Cache-Control': 'max-age=1, stale-while-'
'revalidate=3600, stale-if-error=3600',
},
source_ip=source_ip
)
self.assertEqual(result.status_code, httplib.OK)
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
self.assertKeyWithPop('Age', headers)
self.assertKeyWithPop('Expires', headers)
# drop keys appearing randomly in headers
headers.pop('Transfer-Encoding', None)
headers.pop('Content-Length', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-type': 'application/json',
# ATS does not cache the cookied text content, see:
# https://docs.trafficserver.apache.org/en/7.1.x/admin-guide/\
# configuration/cache-basics.en.html#caching-cookied-objects
# 'Set-Cookie': 'secured=value;secure, nonsecured=value',
'Cache-Control': 'max-age=1, stale-while-revalidate=3600, '
'stale-if-error=3600',
},
headers
)
backend_headers = result.json()['Incoming Headers']
self.assertBackendHeaders(backend_headers, parameter_dict['domain'])
via = backend_headers.pop('via', None)
self.assertNotEqual(via, None)
self.assertRegexpMatches(
via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/7.1.11\)$'
)
finally:
self.startServerProcess()
# END: check stale-if-error support
def test_enable_cache_ats_timeout(self):
parameter_dict = self.assertSlaveBase('enable_cache')
# check that timeout seen by ATS does not result in many queries done
# to the backend and that next request works like a charm
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test_enable_cache_ats_timeout', headers={
'Timeout': '15',
'X-Reply-Header-Cache-Control': 'max-age=1, stale-while-'
'revalidate=3600, stale-if-error=3600'})
# ATS timed out
self.assertEqual(
httplib.GATEWAY_TIMEOUT,
result.status_code
)
backend_haproxy_log_file = glob.glob(
os.path.join(
self.instance_path, '*', 'var', 'log', 'backend-haproxy.log'
))[0]
matching_line_amount = 0
pattern = re.compile(
r'.* _enable_cache-http.backend .* 504 .*'
'"GET .test_enable_cache_ats_timeout HTTP.1.1"$')
with open(backend_haproxy_log_file) as fh:
for line in fh.readlines():
if pattern.match(line):
matching_line_amount += 1
# Haproxy backend received maximum one connection
self.assertIn(matching_line_amount, [0, 1])
timeout = 5
b = time.time()
# ATS created squid.log with a delay
while True:
if (time.time() - b) > timeout:
self.fail('Squid log file did not appear in %ss' % (timeout,))
ats_log_file_list = glob.glob(
os.path.join(
self.instance_path, '*', 'var', 'log', 'trafficserver', 'squid.log'
))
if len(ats_log_file_list) == 1:
ats_log_file = ats_log_file_list[0]
break
time.sleep(0.1)
pattern = re.compile(
r'.*ERR_READ_TIMEOUT/504 .*test_enable_cache_ats_timeout'
'.*TIMEOUT_DIRECT*')
timeout = 5
b = time.time()
# ATS needs some time to flush logs
while True:
matching_line_amount = 0
if (time.time() - b) > timeout:
break
with open(ats_log_file) as fh:
for line in fh.readlines():
if pattern.match(line):
matching_line_amount += 1
if matching_line_amount > 0:
break
time.sleep(0.1)
# ATS has maximum one entry for this query
self.assertIn(matching_line_amount, [0, 1])
# the result is available immediately after
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper', headers={
'X-Reply-Header-Cache-Control': 'max-age=1, stale-while-'
'revalidate=3600, stale-if-error=3600'})
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
def test_enable_cache_disable_no_cache_request(self):
parameter_dict = self.assertSlaveBase(
'enable_cache-disable-no-cache-request')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path',
headers={'Pragma': 'no-cache', 'Cache-Control': 'something'})
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
self.assertKeyWithPop('Age', headers)
# drop keys appearing randomly in headers
headers.pop('Transfer-Encoding', None)
headers.pop('Content-Length', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-type': 'application/json',
'Set-Cookie': 'secured=value;secure, nonsecured=value'
},
headers
)
backend_headers = result.json()['Incoming Headers']
self.assertBackendHeaders(backend_headers, parameter_dict['domain'])
via = backend_headers.pop('via', None)
self.assertNotEqual(via, None)
self.assertRegexpMatches(
via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/7.1.11\)$'
)
try:
j = result.json()
except Exception:
raise ValueError('JSON decode problem in:\n%s' % (result.text,))
self.assertFalse('pragma' in j['Incoming Headers'].keys())
def test_enable_cache_disable_via_header(self):
parameter_dict = self.assertSlaveBase('enable_cache-disable-via-header')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
self.assertKeyWithPop('Age', headers)
# drop keys appearing randomly in headers
headers.pop('Transfer-Encoding', None)
headers.pop('Content-Length', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-type': 'application/json',
'Set-Cookie': 'secured=value;secure, nonsecured=value',
},
headers
)
backend_headers = result.json()['Incoming Headers']
self.assertBackendHeaders(backend_headers, parameter_dict['domain'])
via = backend_headers.pop('via', None)
self.assertNotEqual(via, None)
self.assertRegexpMatches(
via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/7.1.11\)$'
)
def test_enable_http2_false(self):
parameter_dict = self.assertSlaveBase('enable-http2-false')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
# drop vary-keys
headers.pop('Content-Length', None)
headers.pop('Transfer-Encoding', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-Type': 'application/json',
'Set-Cookie': 'secured=value;secure, nonsecured=value',
},
headers
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
def test_enable_http2_default(self):
parameter_dict = self.assertSlaveBase('enable-http2-default')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
# drop vary-keys
headers.pop('Content-Length', None)
headers.pop('Transfer-Encoding', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-type': 'application/json',
'Set-Cookie': 'secured=value;secure, nonsecured=value',
},
headers
)
self.assertTrue(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
def test_prefer_gzip_encoding_to_backend_https_only(self):
parameter_dict = self.assertSlaveBase(
'prefer-gzip-encoding-to-backend-https-only')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={'Accept-Encoding': 'gzip, deflate'})
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
self.assertBackendHeaders(
result.json()['Incoming Headers'], parameter_dict['domain'])
self.assertEqual(
'gzip', result.json()['Incoming Headers']['accept-encoding'])
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={'Accept-Encoding': 'deflate'})
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
self.assertBackendHeaders(
result.json()['Incoming Headers'], parameter_dict['domain'])
self.assertEqual(
'deflate', result.json()['Incoming Headers']['accept-encoding'])
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={'Accept-Encoding': 'gzip, deflate'})
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
self.assertBackendHeaders(
result.json()['Incoming Headers'], parameter_dict['domain'],
port=HTTP_PORT, proto='http')
self.assertEqual(
'gzip', result.json()['Incoming Headers']['accept-encoding'])
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={'Accept-Encoding': 'deflate'})
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
self.assertBackendHeaders(
result.json()['Incoming Headers'], parameter_dict['domain'],
port=HTTP_PORT, proto='http')
self.assertEqual(
'deflate', result.json()['Incoming Headers']['accept-encoding'])
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
def test_prefer_gzip_encoding_to_backend(self):
parameter_dict = self.assertSlaveBase(
'prefer-gzip-encoding-to-backend')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={'Accept-Encoding': 'gzip, deflate'})
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
self.assertBackendHeaders(
result.json()['Incoming Headers'], parameter_dict['domain'])
self.assertEqual(
'gzip', result.json()['Incoming Headers']['accept-encoding'])
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={'Accept-Encoding': 'deflate'})
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
self.assertBackendHeaders(
result.json()['Incoming Headers'], parameter_dict['domain'])
self.assertEqual(
'deflate', result.json()['Incoming Headers']['accept-encoding'])
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={'Accept-Encoding': 'gzip, deflate'})
self.assertEqual(
httplib.FOUND,
result.status_code
)
self.assertEqual(
'https://%s:%s/test-path/deeper' % (parameter_dict['domain'], HTTP_PORT),
result.headers['Location']
)
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper',
headers={'Accept-Encoding': 'deflate'})
self.assertEqual(
httplib.FOUND,
result.status_code
)
self.assertEqual(
'https://%s:%s/test-path/deeper' % (parameter_dict['domain'], HTTP_PORT),
result.headers['Location']
)
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
httplib.FOUND,
result.status_code
)
self.assertEqual(
'https://%s:%s/test-path/deeper' % (parameter_dict['domain'], HTTP_PORT),
result.headers['Location']
)
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
httplib.FOUND,
result.status_code
)
self.assertEqual(
'https://%s:%s/test-path/deeper' % (parameter_dict['domain'], HTTP_PORT),
result.headers['Location']
)
def test_disabled_cookie_list(self):
parameter_dict = self.assertSlaveBase('disabled-cookie-list')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path',
cookies=dict(
Chocolate='absent',
Vanilia='absent',
Coffee='present'
))
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
self.assertBackendHeaders(
result.json()['Incoming Headers'], parameter_dict['domain'])
self.assertEqual(
'Coffee=present', result.json()['Incoming Headers']['cookie'])
def test_https_url(self):
parameter_dict = self.assertSlaveBase('url_https-url')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/https/test-path/deeper')
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
httplib.FOUND,
result_http.status_code
)
self.assertEqual(
'https://urlhttpsurl.example.com:%s/test-path/deeper' % (HTTP_PORT,),
result_http.headers['Location']
)
# check that timeouts are correctly set in the haproxy configuration
backend_configuration_file = glob.glob(os.path.join(
self.instance_path, '*', 'etc', 'backend-haproxy.cfg'))[0]
with open(backend_configuration_file) as fh:
content = fh.read()
self.assertTrue("""backend _url_https-url-http
timeout server 15s
timeout connect 10s
retries 5""" in content)
@skip('Impossible to instantiate cluster with stopped partition')
class TestReplicateSlave(SlaveHttpFrontendTestCase, TestDataMixin):
@classmethod
def getInstanceParameterDict(cls):
return {
'domain': 'example.com',
'public-ipv4': cls._ipv4_address,
'-frontend-quantity': 2,
'-sla-2-computer_guid': cls.slap._computer_id,
'-frontend-2-state': 'stopped',
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
}
@classmethod
def getSlaveParameterDictDict(cls):
return {
'replicate': {
'url': cls.backend_url,
'enable_cache': True,
},
}
def test(self):
parameter_dict = self.parseSlaveParameterDict('replicate')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'replicate.example.com',
'replication_number': '2',
'url': 'http://replicate.example.com',
'site_url': 'http://replicate.example.com',
'secure_access': 'https://replicate.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqualResultJson(result_http, 'Path', '/test-path')
# prove 2nd frontend by inspection of the instance
slave_configuration_name = '_replicate.conf'
slave_configuration_file_list = [
'/'.join([f[0], slave_configuration_name]) for f in [
q for q in os.walk(self.instance_path)
if slave_configuration_name in q[2]
]
]
self.assertEqual(
2, len(slave_configuration_file_list), slave_configuration_file_list)
@skip('Impossible to instantiate cluster with destroyed partition')
class TestReplicateSlaveOtherDestroyed(SlaveHttpFrontendTestCase):
@classmethod
def getInstanceParameterDict(cls):
return {
'domain': 'example.com',
'public-ipv4': cls._ipv4_address,
'-frontend-quantity': 2,
'-sla-2-computer_guid': cls.slap._computer_id,
'-frontend-2-state': 'destroyed',
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
}
@classmethod
def getSlaveParameterDictDict(cls):
return {
'empty': {
'url': cls.backend_url,
'enable_cache': True,
}
}
def test_extra_slave_instance_list_not_present_destroyed_request(self):
buildout_file = os.path.join(
self.getMasterPartitionPath(), 'buildout-switch-softwaretype.cfg')
with open(buildout_file) as fh:
buildout_file_content = fh.read()
node_1_present = re.search(
"^config-frontend-name = !py!'caddy-frontend-1'$",
buildout_file_content, flags=re.M) is not None
node_2_present = re.search(
"^config-frontend-name = !py!'caddy-frontend-2'$",
buildout_file_content, flags=re.M) is not None
self.assertTrue(node_1_present)
self.assertFalse(node_2_present)
class TestEnableHttp2ByDefaultFalseSlave(SlaveHttpFrontendTestCase,
TestDataMixin):
@classmethod
def getInstanceParameterDict(cls):
return {
'domain': 'example.com',
'public-ipv4': cls._ipv4_address,
'enable-http2-by-default': 'false',
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
}
@classmethod
def getSlaveParameterDictDict(cls):
return {
'enable-http2-default': {
},
'enable-http2-false': {
'enable-http2': 'false',
},
'enable-http2-true': {
'enable-http2': 'true',
},
'dummy-cached': {
'url': cls.backend_url,
'enable_cache': True,
}
}
def test_enable_http2_default(self):
parameter_dict = self.parseSlaveParameterDict('enable-http2-default')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'enablehttp2default.example.com',
'replication_number': '1',
'url': 'http://enablehttp2default.example.com',
'site_url': 'http://enablehttp2default.example.com',
'secure_access':
'https://enablehttp2default.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
def test_enable_http2_false(self):
parameter_dict = self.parseSlaveParameterDict('enable-http2-false')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'enablehttp2false.example.com',
'replication_number': '1',
'url': 'http://enablehttp2false.example.com',
'site_url': 'http://enablehttp2false.example.com',
'secure_access':
'https://enablehttp2false.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
def test_enable_http2_true(self):
parameter_dict = self.parseSlaveParameterDict('enable-http2-true')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'enablehttp2true.example.com',
'replication_number': '1',
'url': 'http://enablehttp2true.example.com',
'site_url': 'http://enablehttp2true.example.com',
'secure_access':
'https://enablehttp2true.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
self.assertTrue(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
class TestEnableHttp2ByDefaultDefaultSlave(SlaveHttpFrontendTestCase,
TestDataMixin):
@classmethod
def getInstanceParameterDict(cls):
return {
'domain': 'example.com',
'public-ipv4': cls._ipv4_address,
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
}
@classmethod
def getSlaveParameterDictDict(cls):
return {
'enable-http2-default': {
},
'enable-http2-false': {
'enable-http2': 'false',
},
'enable-http2-true': {
'enable-http2': 'true',
},
'dummy-cached': {
'url': cls.backend_url,
'enable_cache': True,
}
}
def test_enable_http2_default(self):
parameter_dict = self.parseSlaveParameterDict('enable-http2-default')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'enablehttp2default.example.com',
'replication_number': '1',
'url': 'http://enablehttp2default.example.com',
'site_url': 'http://enablehttp2default.example.com',
'secure_access':
'https://enablehttp2default.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
self.assertTrue(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
def test_enable_http2_false(self):
parameter_dict = self.parseSlaveParameterDict('enable-http2-false')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'enablehttp2false.example.com',
'replication_number': '1',
'url': 'http://enablehttp2false.example.com',
'site_url': 'http://enablehttp2false.example.com',
'secure_access':
'https://enablehttp2false.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
def test_enable_http2_true(self):
parameter_dict = self.parseSlaveParameterDict('enable-http2-true')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'enablehttp2true.example.com',
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'replication_number': '1',
'url': 'http://enablehttp2true.example.com',
'site_url': 'http://enablehttp2true.example.com',
'secure_access':
'https://enablehttp2true.example.com',
'public-ipv4': self._ipv4_address,
},
parameter_dict
)
self.assertTrue(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
class TestRe6stVerificationUrlDefaultSlave(SlaveHttpFrontendTestCase,
TestDataMixin):
@classmethod
def getInstanceParameterDict(cls):
return {
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
}
@classmethod
def getSlaveParameterDictDict(cls):
return {
'default': {
'url': cls.backend_url,
'enable_cache': True
},
}
@classmethod
def waitForSlave(cls):
# no need to wait for slave availability here
return True
def test_default(self):
parameter_dict = self.parseSlaveParameterDict('default')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'default.None',
'replication_number': '1',
'url': 'http://default.None',
'site_url': 'http://default.None',
'secure_access': 'https://default.None',
'public-ipv4': 'None',
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
re6st_connectivity_promise_list = glob.glob(
os.path.join(
self.instance_path, '*', 'etc', 'plugin',
're6st-connectivity.py'))
self.assertEqual(1, len(re6st_connectivity_promise_list))
re6st_connectivity_promise_file = re6st_connectivity_promise_list[0]
self.assertEqual(
getPromisePluginParameterDict(re6st_connectivity_promise_file),
{
'url': 'http://[2001:67c:1254:4::1]/index.html',
}
)
@skip('New test system cannot be used with failing promises')
class TestRe6stVerificationUrlSlave(SlaveHttpFrontendTestCase,
TestDataMixin):
@classmethod
def getInstanceParameterDict(cls):
return {
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
're6st-verification-url': 'some-re6st-verification-url',
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
}
@classmethod
def getSlaveParameterDictDict(cls):
return {
'default': {
'url': cls.backend_url,
'enable_cache': True,
},
}
def test_default(self):
parameter_dict = self.parseSlaveParameterDict('default')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'default.None',
'replication_number': '1',
'url': 'http://default.None',
'site_url': 'http://default.None',
'secure_access': 'https://default.None',
'public-ipv4': 'None',
},
parameter_dict
)
re6st_connectivity_promise_list = glob.glob(
os.path.join(
self.instance_path, '*', 'etc', 'plugin',
're6st-connectivity.py'))
self.assertEqual(1, len(re6st_connectivity_promise_list))
re6st_connectivity_promise_file = re6st_connectivity_promise_list[0]
self.assertEqual(
getPromisePluginParameterDict(re6st_connectivity_promise_file),
{
'url': 'some-re6st-verification-url',
}
)
@skip('Impossible to instantiate cluster with stopped partition')
class TestDefaultMonitorHttpdPort(SlaveHttpFrontendTestCase, TestDataMixin):
@classmethod
def getInstanceParameterDict(cls):
return {
'-frontend-1-state': 'stopped',
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
}
@classmethod
def runKedifaUpdater(cls):
return
@classmethod
def getSlaveParameterDictDict(cls):
return {
'test': {
'url': cls.backend_url,
},
'testcached': {
'url': cls.backend_url,
'enable_cache': True,
},
}
def test(self):
parameter_dict = self.parseSlaveParameterDict('test')
self.assertKeyWithPop('log-access-url', parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'test.None', 'replication_number': '1',
'url': 'http://test.None', 'site_url': 'http://test.None',
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'secure_access': 'https://test.None', 'public-ipv4': 'None'},
parameter_dict
)
master_monitor_conf = open(os.path.join(
self.instance_path, 'T-0', 'etc',
'monitor-httpd.conf')).read()
slave_monitor_conf = open(os.path.join(
self.instance_path, 'T-2', 'etc',
'monitor-httpd.conf')).read()
self.assertTrue(
'Listen [%s]:8196' % (self._ipv6_address,) in master_monitor_conf)
self.assertTrue(
'Listen [%s]:8072' % (self._ipv6_address,) in slave_monitor_conf)
class TestSlaveGlobalDisableHttp2(TestSlave):
@classmethod
def getInstanceParameterDict(cls):
instance_parameter_dict = super(
TestSlaveGlobalDisableHttp2, cls).getInstanceParameterDict()
instance_parameter_dict['global-disable-http2'] = 'TrUe'
return instance_parameter_dict
def test_enable_http2_default(self):
parameter_dict = self.parseSlaveParameterDict('enable-http2-default')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'enablehttp2default.example.com',
'replication_number': '1',
'url': 'http://enablehttp2default.example.com',
'site_url': 'http://enablehttp2default.example.com',
'secure_access':
'https://enablehttp2default.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
# drop vary-keys
headers.pop('Content-Length', None)
headers.pop('Transfer-Encoding', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-type': 'application/json',
'Set-Cookie': 'secured=value;secure, nonsecured=value',
},
headers
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
class TestEnableHttp2ByDefaultFalseSlaveGlobalDisableHttp2(
TestEnableHttp2ByDefaultFalseSlave):
@classmethod
def getInstanceParameterDict(cls):
instance_parameter_dict = super(
TestEnableHttp2ByDefaultFalseSlaveGlobalDisableHttp2,
cls).getInstanceParameterDict()
instance_parameter_dict['global-disable-http2'] = 'TrUe'
return instance_parameter_dict
def test_enable_http2_true(self):
parameter_dict = self.parseSlaveParameterDict('enable-http2-true')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'enablehttp2true.example.com',
'replication_number': '1',
'url': 'http://enablehttp2true.example.com',
'site_url': 'http://enablehttp2true.example.com',
'secure_access':
'https://enablehttp2true.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
class TestEnableHttp2ByDefaultDefaultSlaveGlobalDisableHttp2(
TestEnableHttp2ByDefaultDefaultSlave):
@classmethod
def getInstanceParameterDict(cls):
instance_parameter_dict = super(
TestEnableHttp2ByDefaultDefaultSlaveGlobalDisableHttp2,
cls).getInstanceParameterDict()
instance_parameter_dict['global-disable-http2'] = 'TrUe'
return instance_parameter_dict
def test_enable_http2_true(self):
parameter_dict = self.parseSlaveParameterDict('enable-http2-true')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'enablehttp2true.example.com',
'replication_number': '1',
'url': 'http://enablehttp2true.example.com',
'site_url': 'http://enablehttp2true.example.com',
'secure_access':
'https://enablehttp2true.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
def test_enable_http2_default(self):
parameter_dict = self.parseSlaveParameterDict('enable-http2-default')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'enablehttp2default.example.com',
'replication_number': '1',
'url': 'http://enablehttp2default.example.com',
'site_url': 'http://enablehttp2default.example.com',
'secure_access':
'https://enablehttp2default.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
self.assertFalse(
isHTTP2(parameter_dict['domain'], parameter_dict['public-ipv4']))
class TestSlaveSlapOSMasterCertificateCompatibilityOverrideMaster(
SlaveHttpFrontendTestCase, TestDataMixin):
@classmethod
def setUpMaster(cls):
# run partition until AIKC finishes
cls.runComputerPartitionUntil(
cls.untilNotReadyYetNotInMasterKeyGenerateAuthUrl)
parameter_dict = cls.requestDefaultInstance().getConnectionParameterDict()
ca_certificate = requests.get(
parameter_dict['kedifa-caucase-url'] + '/cas/crt/ca.crt.pem')
assert ca_certificate.status_code == httplib.OK
cls.ca_certificate_file = os.path.join(cls.working_directory, 'ca.crt.pem')
open(cls.ca_certificate_file, 'w').write(ca_certificate.text)
# Do not upload certificates for the master partition
@classmethod
def getInstanceParameterDict(cls):
return {
'domain': 'example.com',
'public-ipv4': cls._ipv4_address,
'apache-certificate': cls.certificate_pem,
'apache-key': cls.key_pem,
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
'mpm-graceful-shutdown-timeout': 2,
}
@classmethod
def getSlaveParameterDictDict(cls):
return {
'ssl_from_master_kedifa_overrides_master_certificate': {
'url': cls.backend_url,
'enable_cache': True
},
}
def test_ssl_from_master_kedifa_overrides_master_certificate(self):
reference = 'ssl_from_master_kedifa_overrides_master_certificate'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
hostname = reference.translate(None, '_-')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
_, key_pem, _, certificate_pem = \
createSelfSignedCertificate([parameter_dict['domain']])
master_parameter_dict = \
self.requestDefaultInstance().getConnectionParameterDict()
auth = requests.get(
master_parameter_dict['master-key-generate-auth-url'],
verify=self.ca_certificate_file)
requests.put(
master_parameter_dict['master-key-upload-url'] + auth.text,
data=key_pem + certificate_pem,
verify=self.ca_certificate_file)
self.runKedifaUpdater()
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
class TestSlaveSlapOSMasterCertificateCompatibility(
SlaveHttpFrontendTestCase, TestDataMixin):
@classmethod
def setUpMaster(cls):
# run partition until AIKC finishes
cls.runComputerPartitionUntil(
cls.untilNotReadyYetNotInMasterKeyGenerateAuthUrl)
parameter_dict = cls.requestDefaultInstance().getConnectionParameterDict()
ca_certificate = requests.get(
parameter_dict['kedifa-caucase-url'] + '/cas/crt/ca.crt.pem')
assert ca_certificate.status_code == httplib.OK
cls.ca_certificate_file = os.path.join(cls.working_directory, 'ca.crt.pem')
open(cls.ca_certificate_file, 'w').write(ca_certificate.text)
# Do not upload certificates for the master partition
@classmethod
def prepareCertificate(cls):
_, cls.ssl_from_slave_key_pem, _, cls.ssl_from_slave_certificate_pem = \
createSelfSignedCertificate(
[
'sslfromslave.example.com',
])
_, cls.ssl_from_slave_kedifa_overrides_key_pem, _, \
cls.ssl_from_slave_kedifa_overrides_certificate_pem = \
createSelfSignedCertificate(
[
'sslfromslavekedifaoverrides.example.com',
])
_, cls.type_notebook_ssl_from_slave_key_pem, _, \
cls.type_notebook_ssl_from_slave_certificate_pem = \
createSelfSignedCertificate(
[
'typenotebooksslfromslave.example.com',
])
_, cls.type_notebook_ssl_from_slave_kedifa_overrides_key_pem, _, \
cls.type_notebook_ssl_from_slave_kedifa_overrides_certificate_pem = \
createSelfSignedCertificate(
[
'typenotebooksslfromslavekedifaoverrides.example.com',
])
cls.ca = CertificateAuthority(
'TestSlaveSlapOSMasterCertificateCompatibility')
_, cls.customdomain_ca_key_pem, csr, _ = createCSR(
'customdomainsslcrtsslkeysslcacrt.example.com')
_, cls.customdomain_ca_certificate_pem = cls.ca.signCSR(csr)
_, cls.sslcacrtgarbage_ca_key_pem, csr, _ = createCSR(
'sslcacrtgarbage.example.com')
_, cls.sslcacrtgarbage_ca_certificate_pem = cls.ca.signCSR(csr)
_, cls.ssl_from_slave_ca_key_pem, csr, _ = createCSR(
'sslfromslave.example.com')
_, cls.ssl_from_slave_ca_certificate_pem = cls.ca.signCSR(csr)
_, cls.customdomain_key_pem, _, cls.customdomain_certificate_pem = \
createSelfSignedCertificate(['customdomainsslcrtsslkey.example.com'])
super(
TestSlaveSlapOSMasterCertificateCompatibility, cls).prepareCertificate()
@classmethod
def getInstanceParameterDict(cls):
return {
'domain': 'example.com',
'public-ipv4': cls._ipv4_address,
'apache-certificate': cls.certificate_pem,
'apache-key': cls.key_pem,
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
'mpm-graceful-shutdown-timeout': 2,
}
@classmethod
def getSlaveParameterDictDict(cls):
return {
'ssl_from_master': {
'url': cls.backend_url,
'enable_cache': True,
},
'ssl_from_master_kedifa_overrides': {
'url': cls.backend_url,
},
'ssl_from_slave': {
'url': cls.backend_url,
'ssl_crt': cls.ssl_from_slave_certificate_pem,
'ssl_key': cls.ssl_from_slave_key_pem,
},
'ssl_from_slave_kedifa_overrides': {
'url': cls.backend_url,
'ssl_crt': cls.ssl_from_slave_kedifa_overrides_certificate_pem,
'ssl_key': cls.ssl_from_slave_kedifa_overrides_key_pem,
},
'custom_domain_ssl_crt_ssl_key': {
'url': cls.backend_url,
'ssl_crt': cls.customdomain_certificate_pem,
'ssl_key': cls.customdomain_key_pem,
'custom_domain': 'customdomainsslcrtsslkey.example.com'
},
'custom_domain_ssl_crt_ssl_key_ssl_ca_crt': {
'url': cls.backend_url,
'ssl_crt': cls.customdomain_ca_certificate_pem,
'ssl_key': cls.customdomain_ca_key_pem,
'ssl_ca_crt': cls.ca.certificate_pem,
'custom_domain': 'customdomainsslcrtsslkeysslcacrt.example.com',
},
'ssl_ca_crt_garbage': {
'url': cls.backend_url,
'ssl_crt': cls.sslcacrtgarbage_ca_certificate_pem,
'ssl_key': cls.sslcacrtgarbage_ca_key_pem,
'ssl_ca_crt': 'some garbage',
},
'ssl_ca_crt_does_not_match': {
'url': cls.backend_url,
'ssl_crt': cls.certificate_pem,
'ssl_key': cls.key_pem,
'ssl_ca_crt': cls.ca.certificate_pem,
},
'type-notebook-ssl_from_master': {
'url': cls.backend_url,
'type': 'notebook',
},
'type-notebook-ssl_from_slave': {
'url': cls.backend_url,
'ssl_crt': cls.type_notebook_ssl_from_slave_certificate_pem,
'ssl_key': cls.type_notebook_ssl_from_slave_key_pem,
'type': 'notebook',
},
'type-notebook-ssl_from_master_kedifa_overrides': {
'url': cls.backend_url,
'type': 'notebook',
},
'type-notebook-ssl_from_slave_kedifa_overrides': {
'url': cls.backend_url,
'ssl_crt':
cls.type_notebook_ssl_from_slave_kedifa_overrides_certificate_pem,
'ssl_key':
cls.type_notebook_ssl_from_slave_kedifa_overrides_key_pem,
'type': 'notebook',
}
}
def test_master_partition_state(self):
parameter_dict = self.parseConnectionParameterDict()
self.assertKeyWithPop('monitor-setup-url', parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, 'master-')
self.assertRejectedSlavePromiseWithPop(parameter_dict)
expected_parameter_dict = {
'monitor-base-url': 'https://[%s]:8401' % self._ipv6_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'domain': 'example.com',
'accepted-slave-amount': '12',
'rejected-slave-amount': '0',
'slave-amount': '12',
'rejected-slave-dict': {
# u"_ssl_ca_crt_only":
# [u"ssl_ca_crt is present, so ssl_crt and ssl_key are required"],
# u"_ssl_key-ssl_crt-unsafe":
# [u"slave ssl_key and ssl_crt does not match"]
},
'warning-list': [
u'apache-certificate is obsolete, please use master-key-upload-url',
u'apache-key is obsolete, please use master-key-upload-url',
],
'warning-slave-dict': {
u'_custom_domain_ssl_crt_ssl_key': [
u'ssl_key is obsolete, please use key-upload-url',
u'ssl_crt is obsolete, please use key-upload-url'
],
u'_custom_domain_ssl_crt_ssl_key_ssl_ca_crt': [
u'ssl_key is obsolete, please use key-upload-url',
u'ssl_crt is obsolete, please use key-upload-url',
u'ssl_ca_crt is obsolete, please use key-upload-url'
],
u'_ssl_ca_crt_does_not_match': [
u'ssl_key is obsolete, please use key-upload-url',
u'ssl_crt is obsolete, please use key-upload-url',
u'ssl_ca_crt is obsolete, please use key-upload-url',
],
u'_ssl_ca_crt_garbage': [
u'ssl_key is obsolete, please use key-upload-url',
u'ssl_crt is obsolete, please use key-upload-url',
u'ssl_ca_crt is obsolete, please use key-upload-url',
],
# u'_ssl_ca_crt_only': [
# u'ssl_ca_crt is obsolete, please use key-upload-url',
# ],
u'_ssl_from_slave': [
u'ssl_key is obsolete, please use key-upload-url',
u'ssl_crt is obsolete, please use key-upload-url',
],
u'_ssl_from_slave_kedifa_overrides': [
u'ssl_key is obsolete, please use key-upload-url',
u'ssl_crt is obsolete, please use key-upload-url',
],
# u'_ssl_key-ssl_crt-unsafe': [
# u'ssl_key is obsolete, please use key-upload-url',
# u'ssl_crt is obsolete, please use key-upload-url',
# ],
u'_type-notebook-ssl_from_slave': [
u'ssl_key is obsolete, please use key-upload-url',
u'ssl_crt is obsolete, please use key-upload-url',
],
u'_type-notebook-ssl_from_slave_kedifa_overrides': [
u'ssl_key is obsolete, please use key-upload-url',
u'ssl_crt is obsolete, please use key-upload-url',
],
}
}
self.assertEqual(
expected_parameter_dict,
parameter_dict
)
def test_ssl_from_master(self):
parameter_dict = self.parseSlaveParameterDict('ssl_from_master')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, '')
hostname = 'ssl_from_master'.translate(None, '_-')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_ssl_from_master_kedifa_overrides(self):
reference = 'ssl_from_master_kedifa_overrides'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
generate_auth, upload_url = self.assertKedifaKeysWithPop(parameter_dict)
hostname = reference.translate(None, '_-')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
_, key_pem, _, certificate_pem = \
createSelfSignedCertificate([parameter_dict['domain']])
# as now the place to put the key is known put the key there
auth = requests.get(
generate_auth,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, auth.status_code)
data = certificate_pem + key_pem
upload = requests.put(
upload_url + auth.text,
data=data,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, upload.status_code)
self.runKedifaUpdater()
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_ssl_from_slave(self):
reference = 'ssl_from_slave'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
hostname = reference.translate(None, '_-')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'warning-list': [
'ssl_key is obsolete, please use key-upload-url',
'ssl_crt is obsolete, please use key-upload-url',
]
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.ssl_from_slave_certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_ssl_from_slave_kedifa_overrides(self):
reference = 'ssl_from_slave_kedifa_overrides'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
generate_auth, upload_url = self.assertKedifaKeysWithPop(parameter_dict)
hostname = reference.translate(None, '_-')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'warning-list': [
'ssl_key is obsolete, please use key-upload-url',
'ssl_crt is obsolete, please use key-upload-url',
]
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.ssl_from_slave_kedifa_overrides_certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
_, key_pem, _, certificate_pem = \
createSelfSignedCertificate([parameter_dict['domain']])
# as now the place to put the key is known put the key there
auth = requests.get(
generate_auth,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, auth.status_code)
data = certificate_pem + key_pem
upload = requests.put(
upload_url + auth.text,
data=data,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, upload.status_code)
self.runKedifaUpdater()
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_type_notebook_ssl_from_master(self):
reference = 'type-notebook-ssl_from_master'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
hostname = reference.translate(None, '_-')
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path',
HTTPS_PORT)
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_type_notebook_ssl_from_master_kedifa_overrides(self):
reference = 'type-notebook-ssl_from_master_kedifa_overrides'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
generate_auth, upload_url = self.assertKedifaKeysWithPop(parameter_dict)
hostname = reference.translate(None, '_-')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path',
HTTPS_PORT)
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
_, key_pem, _, certificate_pem = \
createSelfSignedCertificate([parameter_dict['domain']])
# as now the place to put the key is known put the key there
auth = requests.get(
generate_auth,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, auth.status_code)
data = certificate_pem + key_pem
upload = requests.put(
upload_url + auth.text,
data=data,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, upload.status_code)
self.runKedifaUpdater()
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path',
HTTPS_PORT)
self.assertEqual(
certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_type_notebook_ssl_from_slave(self):
reference = 'type-notebook-ssl_from_slave'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
hostname = reference.translate(None, '_-')
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'warning-list': [
'ssl_key is obsolete, please use key-upload-url',
'ssl_crt is obsolete, please use key-upload-url',
]
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path',
HTTPS_PORT)
self.assertEqual(
self.type_notebook_ssl_from_slave_certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_type_notebook_ssl_from_slave_kedifa_overrides(self):
reference = 'type-notebook-ssl_from_slave_kedifa_overrides'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
generate_auth, upload_url = self.assertKedifaKeysWithPop(parameter_dict)
hostname = reference.translate(None, '_-')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'warning-list': [
'ssl_key is obsolete, please use key-upload-url',
'ssl_crt is obsolete, please use key-upload-url',
]
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path',
HTTPS_PORT)
self.assertEqual(
self.type_notebook_ssl_from_slave_kedifa_overrides_certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
_, key_pem, _, certificate_pem = \
createSelfSignedCertificate([parameter_dict['domain']])
# as now the place to put the key is known put the key there
auth = requests.get(
generate_auth,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, auth.status_code)
data = certificate_pem + key_pem
upload = requests.put(
upload_url + auth.text,
data=data,
verify=self.ca_certificate_file)
self.assertEqual(httplib.CREATED, upload.status_code)
self.runKedifaUpdater()
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path',
HTTPS_PORT)
self.assertEqual(
certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
@skip('Not implemented in new test system')
def test_custom_domain_ssl_crt_ssl_key(self):
reference = 'custom_domain_ssl_crt_ssl_key'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
generate_auth, upload_url = self.assertKedifaKeysWithPop(parameter_dict)
hostname = reference.translate(None, '_-')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'warning-list': ['ssl_key is obsolete, please use key-upload-url',
'ssl_crt is obsolete, please use key-upload-url']
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.customdomain_certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_ssl_ca_crt(self):
parameter_dict = self.parseSlaveParameterDict(
'custom_domain_ssl_crt_ssl_key_ssl_ca_crt')
self.assertLogAccessUrlWithPop(parameter_dict)
generate_auth, upload_url = self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'customdomainsslcrtsslkeysslcacrt.example.com',
'replication_number': '1',
'url': 'http://customdomainsslcrtsslkeysslcacrt.example.com',
'site_url': 'http://customdomainsslcrtsslkeysslcacrt.example.com',
'secure_access':
'https://customdomainsslcrtsslkeysslcacrt.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'warning-list': [
'ssl_key is obsolete, please use key-upload-url',
'ssl_crt is obsolete, please use key-upload-url',
'ssl_ca_crt is obsolete, please use key-upload-url'
]
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.customdomain_ca_certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
certificate_file_list = glob.glob(os.path.join(
self.instance_path, '*', 'srv', 'bbb-ssl',
'_custom_domain_ssl_crt_ssl_key_ssl_ca_crt.crt'))
self.assertEqual(1, len(certificate_file_list))
certificate_file = certificate_file_list[0]
with open(certificate_file) as out:
expected = self.customdomain_ca_certificate_pem + '\n' + \
self.ca.certificate_pem + '\n' + self.customdomain_ca_key_pem
self.assertEqual(
expected,
out.read()
)
ca = CertificateAuthority(
'TestSlaveSlapOSMasterCertificateCompatibility')
_, customdomain_ca_key_pem, csr, _ = createCSR(
'customdomainsslcrtsslkeysslcacrt.example.com')
_, customdomain_ca_certificate_pem = ca.signCSR(csr)
slave_parameter_dict = self.getSlaveParameterDictDict()[
'custom_domain_ssl_crt_ssl_key_ssl_ca_crt'].copy()
slave_parameter_dict.update(
ssl_crt=customdomain_ca_certificate_pem,
ssl_key=customdomain_ca_key_pem,
ssl_ca_crt=ca.certificate_pem,
)
self.slap.request(
software_release=self.getSoftwareURL(),
partition_reference='custom_domain_ssl_crt_ssl_key_ssl_ca_crt',
partition_parameter_kw=slave_parameter_dict,
shared=True
)
self.slap.waitForInstance()
self.runKedifaUpdater()
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
customdomain_ca_certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
certificate_file_list = glob.glob(os.path.join(
self.instance_path, '*', 'srv', 'bbb-ssl',
'_custom_domain_ssl_crt_ssl_key_ssl_ca_crt.crt'))
self.assertEqual(1, len(certificate_file_list))
certificate_file = certificate_file_list[0]
with open(certificate_file) as out:
expected = customdomain_ca_certificate_pem + '\n' + ca.certificate_pem \
+ '\n' + customdomain_ca_key_pem
self.assertEqual(
expected,
out.read()
)
def test_ssl_ca_crt_garbage(self):
parameter_dict = self.parseSlaveParameterDict('ssl_ca_crt_garbage')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'sslcacrtgarbage.example.com',
'replication_number': '1',
'url': 'http://sslcacrtgarbage.example.com',
'site_url': 'http://sslcacrtgarbage.example.com',
'secure_access':
'https://sslcacrtgarbage.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'warning-list': [
'ssl_key is obsolete, please use key-upload-url',
'ssl_crt is obsolete, please use key-upload-url',
'ssl_ca_crt is obsolete, please use key-upload-url']
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.sslcacrtgarbage_ca_certificate_pem,
der2pem(result.peercert)
)
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_ssl_ca_crt_does_not_match(self):
parameter_dict = self.parseSlaveParameterDict('ssl_ca_crt_does_not_match')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'sslcacrtdoesnotmatch.example.com',
'replication_number': '1',
'url': 'http://sslcacrtdoesnotmatch.example.com',
'site_url': 'http://sslcacrtdoesnotmatch.example.com',
'secure_access':
'https://sslcacrtdoesnotmatch.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'warning-list': [
'ssl_key is obsolete, please use key-upload-url',
'ssl_crt is obsolete, please use key-upload-url',
'ssl_ca_crt is obsolete, please use key-upload-url'
]
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
certificate_file_list = glob.glob(os.path.join(
self.instance_path, '*', 'srv', 'bbb-ssl',
'_ssl_ca_crt_does_not_match.crt'))
self.assertEqual(1, len(certificate_file_list))
certificate_file = certificate_file_list[0]
with open(certificate_file) as out:
expected = self.certificate_pem + '\n' + self.ca.certificate_pem + \
'\n' + self.key_pem
self.assertEqual(
expected,
out.read()
)
class TestSlaveSlapOSMasterCertificateCompatibilityUpdate(
SlaveHttpFrontendTestCase, TestDataMixin):
@classmethod
def setUpMaster(cls):
# run partition until AIKC finishes
cls.runComputerPartitionUntil(
cls.untilNotReadyYetNotInMasterKeyGenerateAuthUrl)
parameter_dict = cls.requestDefaultInstance().getConnectionParameterDict()
ca_certificate = requests.get(
parameter_dict['kedifa-caucase-url'] + '/cas/crt/ca.crt.pem')
assert ca_certificate.status_code == httplib.OK
cls.ca_certificate_file = os.path.join(cls.working_directory, 'ca.crt.pem')
open(cls.ca_certificate_file, 'w').write(ca_certificate.text)
# Do not upload certificates for the master partition
instance_parameter_dict = {
'domain': 'example.com',
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
'mpm-graceful-shutdown-timeout': 2,
}
@classmethod
def getInstanceParameterDict(cls):
if 'apache-certificate' not in cls.instance_parameter_dict:
cls.instance_parameter_dict.update(**{
'apache-certificate': cls.certificate_pem,
'apache-key': cls.key_pem,
})
cls.instance_parameter_dict['public-ipv4'] = cls._ipv4_address
return cls.instance_parameter_dict
@classmethod
def getSlaveParameterDictDict(cls):
return {
'ssl_from_master': {
'url': cls.backend_url,
'enable_cache': True,
},
}
def test_master_partition_state(self):
parameter_dict = self.parseConnectionParameterDict()
self.assertKeyWithPop('monitor-setup-url', parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, 'master-')
self.assertRejectedSlavePromiseWithPop(parameter_dict)
expected_parameter_dict = {
'monitor-base-url': 'https://[%s]:8401' % self._ipv6_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'domain': 'example.com',
'accepted-slave-amount': '1',
'rejected-slave-amount': '0',
'rejected-slave-dict': {},
'slave-amount': '1',
'warning-list': [
u'apache-certificate is obsolete, please use master-key-upload-url',
u'apache-key is obsolete, please use master-key-upload-url',
],
}
self.assertEqual(
expected_parameter_dict,
parameter_dict
)
def test_apache_key_apache_certificate_update(self):
parameter_dict = self.parseSlaveParameterDict('ssl_from_master')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, '')
hostname = 'ssl_from_master'.translate(None, '_-')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
_, key_pem, _, certificate_pem = createSelfSignedCertificate(
[
'*.customdomain.example.com',
'*.example.com',
'*.alias1.example.com',
])
self.instance_parameter_dict.update(**{
'apache-certificate': certificate_pem,
'apache-key': key_pem,
})
self.requestDefaultInstance()
self.slap.waitForInstance()
self.runKedifaUpdater()
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
class TestSlaveCiphers(SlaveHttpFrontendTestCase, TestDataMixin):
@classmethod
def getInstanceParameterDict(cls):
return {
'domain': 'example.com',
'public-ipv4': cls._ipv4_address,
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
'mpm-graceful-shutdown-timeout': 2,
'ciphers': 'ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384'
}
@classmethod
def getSlaveParameterDictDict(cls):
return {
'default_ciphers': {
'url': cls.backend_url,
'enable_cache': True,
},
'own_ciphers': {
'ciphers': 'ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256',
'url': cls.backend_url,
'enable_cache': True,
},
}
def test_master_partition_state(self):
parameter_dict = self.parseConnectionParameterDict()
self.assertKeyWithPop('monitor-setup-url', parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, 'master-')
self.assertRejectedSlavePromiseWithPop(parameter_dict)
expected_parameter_dict = {
'monitor-base-url': 'https://[%s]:8401' % self._ipv6_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'domain': 'example.com',
'accepted-slave-amount': '2',
'rejected-slave-amount': '0',
'slave-amount': '2',
'rejected-slave-dict': {}
}
self.assertEqual(
expected_parameter_dict,
parameter_dict
)
def test_default_ciphers(self):
parameter_dict = self.assertSlaveBase('default_ciphers')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(httplib.OK, result.status_code)
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(httplib.FOUND, result_http.status_code)
configuration_file = glob.glob(
os.path.join(
self.instance_path, '*', 'etc', 'caddy-slave-conf.d',
'_default_ciphers.conf'
))[0]
self.assertTrue(
'ciphers ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384'
in open(configuration_file).read()
)
def test_own_ciphers(self):
parameter_dict = self.assertSlaveBase('own_ciphers')
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(httplib.OK, result.status_code)
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(httplib.FOUND, result_http.status_code)
configuration_file = glob.glob(
os.path.join(
self.instance_path, '*', 'etc', 'caddy-slave-conf.d',
'_own_ciphers.conf'
))[0]
self.assertTrue(
'ciphers ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256'
in open(configuration_file).read()
)
class TestSlaveRejectReportUnsafeDamaged(SlaveHttpFrontendTestCase):
@classmethod
def prepareCertificate(cls):
cls.ca = CertificateAuthority('TestSlaveRejectReportUnsafeDamaged')
super(TestSlaveRejectReportUnsafeDamaged, cls).prepareCertificate()
@classmethod
def getInstanceParameterDict(cls):
return {
'domain': 'example.com',
'public-ipv4': cls._ipv4_address,
'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT,
'kedifa_port': KEDIFA_PORT,
'caucase_port': CAUCASE_PORT,
}
@classmethod
def setUpClass(cls):
super(TestSlaveRejectReportUnsafeDamaged, cls).setUpClass()
cls.fillSlaveParameterDictDict()
cls.requestSlaves()
try:
cls.slap.waitForInstance(
max_retry=2 # two runs shall be enough
)
except Exception:
# ignores exceptions, as problems are tested
pass
cls.updateSlaveConnectionParameterDictDict()
slave_parameter_dict_dict = {}
@classmethod
def getSlaveParameterDictDict(cls):
return cls.slave_parameter_dict_dict
@classmethod
def fillSlaveParameterDictDict(cls):
cls.slave_parameter_dict_dict = {
'url': {
'url': "https://[fd46::c2ae]:!py!u'123123'",
},
'https-url': {
'https-url': "https://[fd46::c2ae]:!py!u'123123'",
},
'ssl-proxy-verify_ssl_proxy_ca_crt_damaged': {
'url': cls.backend_https_url,
'ssl-proxy-verify': True,
'ssl_proxy_ca_crt': 'damaged',
},
'ssl-proxy-verify_ssl_proxy_ca_crt_empty': {
'url': cls.backend_https_url,
'ssl-proxy-verify': True,
'ssl_proxy_ca_crt': '',
},
'bad-backend': {
'url': 'http://1:2:3:4',
'https-url': 'http://host.domain:badport',
},
'empty-backend': {
'url': '',
'https-url': '',
},
'custom_domain-unsafe': {
'custom_domain': '${section:option} afterspace\nafternewline',
},
'server-alias-unsafe': {
'server-alias': '${section:option} afterspace',
},
'server-alias-same': {
'url': cls.backend_url,
'server-alias': 'serveraliassame.example.com',
},
'virtualhostroot-http-port-unsafe': {
'type': 'zope',
'url': cls.backend_url,
'virtualhostroot-http-port': '${section:option}',
},
'virtualhostroot-https-port-unsafe': {
'type': 'zope',
'url': cls.backend_url,
'virtualhostroot-https-port': '${section:option}',
},
'default-path-unsafe': {
'type': 'zope',
'url': cls.backend_url,
'default-path': '${section:option}\nn"\newline\n}\n}proxy\n/slashed',
},
'monitor-ipv4-test-unsafe': {
'monitor-ipv4-test': '${section:option}\nafternewline ipv4',
},
'monitor-ipv6-test-unsafe': {
'monitor-ipv6-test': '${section:option}\nafternewline ipv6',
},
'bad-ciphers': {
'ciphers': 'bad ECDHE-ECDSA-AES256-GCM-SHA384 again',
},
'site_1': {
'custom_domain': 'duplicate.example.com',
},
'site_2': {
'custom_domain': 'duplicate.example.com',
},
'site_3': {
'server-alias': 'duplicate.example.com',
},
'site_4': {
'custom_domain': 'duplicate.example.com',
'server-alias': 'duplicate.example.com',
},
'ssl_ca_crt_only': {
'url': cls.backend_url,
'ssl_ca_crt': cls.ca.certificate_pem,
},
'ssl_key-ssl_crt-unsafe': {
'ssl_key': '${section:option}ssl_keyunsafe\nunsafe',
'ssl_crt': '${section:option}ssl_crtunsafe\nunsafe',
},
}
def test_master_partition_state(self):
parameter_dict = self.parseConnectionParameterDict()
self.assertKeyWithPop('monitor-setup-url', parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, 'master-')
self.assertRejectedSlavePromiseWithPop(parameter_dict)
expected_parameter_dict = {
'monitor-base-url': 'https://[%s]:8401' % self._ipv6_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'domain': 'example.com',
'accepted-slave-amount': '7',
'rejected-slave-amount': '14',
'slave-amount': '21',
'rejected-slave-dict': {
'_https-url': ['slave https-url "https://[fd46::c2ae]:!py!u\'123123\'"'
' invalid'],
'_url': [u'slave url "https://[fd46::c2ae]:!py!u\'123123\'" invalid'],
'_ssl-proxy-verify_ssl_proxy_ca_crt_damaged': [
'ssl_proxy_ca_crt is invalid'
],
'_ssl-proxy-verify_ssl_proxy_ca_crt_empty': [
'ssl_proxy_ca_crt is invalid'
],
'_bad-ciphers': [
"Cipher 'bad' is not supported.",
"Cipher 'again' is not supported."
],
'_custom_domain-unsafe': [
"custom_domain '${section:option} afterspace\\nafternewline' invalid"
],
'_server-alias-unsafe': [
"server-alias '${section:option}' not valid",
"server-alias 'afterspace' not valid"
],
'_site_2': ["custom_domain 'duplicate.example.com' clashes"],
'_site_3': ["server-alias 'duplicate.example.com' clashes"],
'_site_4': ["custom_domain 'duplicate.example.com' clashes"],
'_ssl_ca_crt_only': [
"ssl_ca_crt is present, so ssl_crt and ssl_key are required"],
'_ssl_key-ssl_crt-unsafe': [
"slave ssl_key and ssl_crt does not match"],
'_bad-backend': [
"slave url 'http://1:2:3:4' invalid",
"slave https-url 'http://host.domain:badport' invalid"],
'_empty-backend': [
"slave url '' invalid",
"slave https-url '' invalid"],
},
'warning-slave-dict': {
'_ssl_ca_crt_only': [
'ssl_ca_crt is obsolete, please use key-upload-url'],
'_ssl_key-ssl_crt-unsafe': [
'ssl_key is obsolete, please use key-upload-url',
'ssl_crt is obsolete, please use key-upload-url']}
}
self.assertEqual(
expected_parameter_dict,
parameter_dict
)
def test_url(self):
parameter_dict = self.parseSlaveParameterDict('url')
self.assertEqual(
{
'request-error-list': [
"slave url \"https://[fd46::c2ae]:!py!u'123123'\" invalid"]
},
parameter_dict
)
def test_https_url(self):
parameter_dict = self.parseSlaveParameterDict('https-url')
self.assertEqual(
{
'request-error-list': [
"slave https-url \"https://[fd46::c2ae]:!py!u'123123'\" invalid"]
},
parameter_dict
)
def test_ssl_proxy_verify_ssl_proxy_ca_crt_damaged(self):
parameter_dict = self.parseSlaveParameterDict(
'ssl-proxy-verify_ssl_proxy_ca_crt_damaged')
self.assertEqual(
{'request-error-list': ["ssl_proxy_ca_crt is invalid"]},
parameter_dict
)
def test_ssl_proxy_verify_ssl_proxy_ca_crt_empty(self):
parameter_dict = self.parseSlaveParameterDict(
'ssl-proxy-verify_ssl_proxy_ca_crt_empty')
self.assertEqual(
{'request-error-list': ["ssl_proxy_ca_crt is invalid"]},
parameter_dict
)
def test_server_alias_same(self):
parameter_dict = self.parseSlaveParameterDict('server-alias-same')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'serveraliassame.example.com',
'replication_number': '1',
'url': 'http://serveraliassame.example.com',
'site_url': 'http://serveraliassame.example.com',
'secure_access': 'https://serveraliassame.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_custom_domain_unsafe(self):
parameter_dict = self.parseSlaveParameterDict('custom_domain-unsafe')
self.assertEqual(
{
'request-error-list': [
"custom_domain '${section:option} afterspace\\nafternewline' invalid"
]
},
parameter_dict
)
def test_server_alias_unsafe(self):
parameter_dict = self.parseSlaveParameterDict('server-alias-unsafe')
self.assertEqual(
{
'request-error-list': [
"server-alias '${section:option}' not valid", "server-alias "
"'afterspace' not valid"]
},
parameter_dict
)
def test_bad_ciphers(self):
parameter_dict = self.parseSlaveParameterDict('bad-ciphers')
self.assertEqual(
{
'request-error-list': [
"Cipher 'bad' is not supported.",
"Cipher 'again' is not supported."
]
},
parameter_dict
)
def test_virtualhostroot_http_port_unsafe(self):
parameter_dict = self.parseSlaveParameterDict(
'virtualhostroot-http-port-unsafe')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'virtualhostroothttpportunsafe.example.com',
'replication_number': '1',
'url': 'http://virtualhostroothttpportunsafe.example.com',
'site_url': 'http://virtualhostroothttpportunsafe.example.com',
'secure_access':
'https://virtualhostroothttpportunsafe.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(httplib.FOUND, result.status_code)
def test_virtualhostroot_https_port_unsafe(self):
parameter_dict = self.parseSlaveParameterDict(
'virtualhostroot-https-port-unsafe')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'virtualhostroothttpsportunsafe.example.com',
'replication_number': '1',
'url': 'http://virtualhostroothttpsportunsafe.example.com',
'site_url': 'http://virtualhostroothttpsportunsafe.example.com',
'secure_access':
'https://virtualhostroothttpsportunsafe.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(
result,
'Path',
'/VirtualHostBase/https//virtualhostroothttpsportunsafe'
'.example.com:0//VirtualHostRoot/test-path'
)
def default_path_unsafe(self):
parameter_dict = self.parseSlaveParameterDict('default-path-unsafe')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, 'master-')
self.assertEqual(
{
'domain': 'defaultpathunsafe.example.com',
'replication_number': '1',
'url': 'http://defaultpathunsafe.example.com',
'site_url': 'http://defaultpathunsafe.example.com',
'secure_access': 'https://defaultpathunsafe.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], '')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(
httplib.MOVED_PERMANENTLY,
result.status_code
)
self.assertEqual(
'https://defaultpathunsafe.example.com:%s/%%24%%7Bsection%%3Aoption%%7D'
'%%0An%%22%%0Aewline%%0A%%7D%%0A%%7Dproxy%%0A/slashed' % (HTTPS_PORT,),
result.headers['Location']
)
def test_monitor_ipv4_test_unsafe(self):
parameter_dict = self.parseSlaveParameterDict('monitor-ipv4-test-unsafe')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'monitoripv4testunsafe.example.com',
'replication_number': '1',
'url': 'http://monitoripv4testunsafe.example.com',
'site_url': 'http://monitoripv4testunsafe.example.com',
'secure_access': 'https://monitoripv4testunsafe.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(httplib.SERVICE_UNAVAILABLE, result.status_code)
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(httplib.FOUND, result_http.status_code)
monitor_file = glob.glob(
os.path.join(
self.instance_path, '*', 'etc', 'plugin',
'check-_monitor-ipv4-test-unsafe-ipv4-packet-list-test.py'))[0]
# get promise module and check that parameters are ok
self.assertEqual(
getPromisePluginParameterDict(monitor_file),
{
'frequency': '720',
'ipv4': 'true',
'address': '${section:option}\nafternewline ipv4',
}
)
def test_monitor_ipv6_test_unsafe(self):
parameter_dict = self.parseSlaveParameterDict('monitor-ipv6-test-unsafe')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'monitoripv6testunsafe.example.com',
'replication_number': '1',
'url': 'http://monitoripv6testunsafe.example.com',
'site_url': 'http://monitoripv6testunsafe.example.com',
'secure_access': 'https://monitoripv6testunsafe.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
result = fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqual(httplib.SERVICE_UNAVAILABLE, result.status_code)
result_http = fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(httplib.FOUND, result_http.status_code)
monitor_file = glob.glob(
os.path.join(
self.instance_path, '*', 'etc', 'plugin',
'check-_monitor-ipv6-test-unsafe-ipv6-packet-list-test.py'))[0]
# get promise module and check that parameters are ok
self.assertEqual(
getPromisePluginParameterDict(monitor_file),
{
'frequency': '720',
'address': '${section:option}\nafternewline ipv6'
}
)
def test_site_1(self):
parameter_dict = self.parseSlaveParameterDict('site_1')
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict)
self.assertEqual(
{
'domain': 'duplicate.example.com',
'replication_number': '1',
'url': 'http://duplicate.example.com',
'site_url': 'http://duplicate.example.com',
'secure_access': 'https://duplicate.example.com',
'public-ipv4': self._ipv4_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
},
parameter_dict
)
def test_site_2(self):
parameter_dict = self.parseSlaveParameterDict('site_2')
self.assertEqual(
{
'request-error-list': ["custom_domain 'duplicate.example.com' clashes"]
},
parameter_dict
)
def test_site_3(self):
parameter_dict = self.parseSlaveParameterDict('site_3')
self.assertEqual(
{
'request-error-list': ["server-alias 'duplicate.example.com' clashes"]
},
parameter_dict,
)
def test_site_4(self):
parameter_dict = self.parseSlaveParameterDict('site_4')
self.assertEqual(
{
'request-error-list': ["custom_domain 'duplicate.example.com' clashes"]
},
parameter_dict
)
def test_ssl_ca_crt_only(self):
parameter_dict = self.parseSlaveParameterDict('ssl_ca_crt_only')
self.assertEqual(
parameter_dict,
{
'request-error-list': [
"ssl_ca_crt is present, so ssl_crt and ssl_key are required"],
'warning-list': [
'ssl_ca_crt is obsolete, please use key-upload-url',
],
}
)
def test_ssl_key_ssl_crt_unsafe(self):
parameter_dict = self.parseSlaveParameterDict('ssl_key-ssl_crt-unsafe')
self.assertEqual(
{
'request-error-list': ["slave ssl_key and ssl_crt does not match"],
'warning-list': [
'ssl_key is obsolete, please use key-upload-url',
'ssl_crt is obsolete, please use key-upload-url']
},
parameter_dict
)
def test_bad_backend(self):
parameter_dict = self.parseSlaveParameterDict('bad-backend')
self.assertEqual(
{
'request-error-list': [
"slave url 'http://1:2:3:4' invalid",
"slave https-url 'http://host.domain:badport' invalid"],
},
parameter_dict
)
def test_empty_backend(self):
parameter_dict = self.parseSlaveParameterDict('empty-backend')
self.assertEqual(
{
'request-error-list': [
"slave url '' invalid",
"slave https-url '' invalid"],
},
parameter_dict
)
test_data/ 0000775 0000000 0000000 00000000000 13723117434 0034351 5 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test test.TestEnableHttp2ByDefaultDefaultSlave.test_file_list_etc_cron_d-CADDY.txt 0000664 0000000 0000000 00000000644 13723117434 0053155 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/cron.d/logrotate
T-0/etc/cron.d/monitor-configurator
T-0/etc/cron.d/monitor-globalstate
T-0/etc/cron.d/monitor_collect
T-1/etc/cron.d/logrotate
T-1/etc/cron.d/monitor-configurator
T-1/etc/cron.d/monitor-globalstate
T-1/etc/cron.d/monitor_collect
T-2/etc/cron.d/logrotate
T-2/etc/cron.d/monitor-configurator
T-2/etc/cron.d/monitor-globalstate
T-2/etc/cron.d/monitor_collect
T-2/etc/cron.d/trafficserver-logrotate
test.TestEnableHttp2ByDefaultDefaultSlave.test_file_list_log-CADDY.txt 0000664 0000000 0000000 00000002106 13723117434 0051632 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/log/monitor-httpd-access.log
T-0/var/log/monitor-httpd-error.log
T-0/var/log/slapgrid-T-0-error.log
T-1/var/log/expose-csr_id.log
T-1/var/log/kedifa.log
T-1/var/log/monitor-httpd-access.log
T-1/var/log/monitor-httpd-error.log
T-2/var/log/backend-haproxy.log
T-2/var/log/frontend-access.log
T-2/var/log/frontend-error.log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/httpd/_dummy-cached_access_log
T-2/var/log/httpd/_dummy-cached_backend_log
T-2/var/log/httpd/_dummy-cached_error_log
T-2/var/log/httpd/_enable-http2-default_access_log
T-2/var/log/httpd/_enable-http2-default_backend_log
T-2/var/log/httpd/_enable-http2-default_error_log
T-2/var/log/httpd/_enable-http2-false_access_log
T-2/var/log/httpd/_enable-http2-false_backend_log
T-2/var/log/httpd/_enable-http2-false_error_log
T-2/var/log/httpd/_enable-http2-true_access_log
T-2/var/log/httpd/_enable-http2-true_backend_log
T-2/var/log/httpd/_enable-http2-true_error_log
T-2/var/log/monitor-httpd-access.log
T-2/var/log/monitor-httpd-error.log
T-2/var/log/trafficserver/manager.log
T-2/var/log/trafficserver/traffic.out
test.TestEnableHttp2ByDefaultDefaultSlave.test_file_list_plugin-CADDY.txt 0000664 0000000 0000000 00000003207 13723117434 0052352 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/plugin/__init__.py
T-0/etc/plugin/aibcc-user-caucase-updater.py
T-0/etc/plugin/aikc-user-caucase-updater.py
T-0/etc/plugin/buildout-T-0-status.py
T-0/etc/plugin/caucased-backend-client.py
T-0/etc/plugin/check-free-disk-space.py
T-0/etc/plugin/monitor-bootstrap-status.py
T-0/etc/plugin/monitor-http-frontend.py
T-0/etc/plugin/monitor-httpd-listening-on-tcp.py
T-0/etc/plugin/rejected-slave-publish-ip-port-listening.py
T-0/etc/plugin/rejected-slave.py
T-1/etc/plugin/__init__.py
T-1/etc/plugin/buildout-T-1-status.py
T-1/etc/plugin/caucased.py
T-1/etc/plugin/check-free-disk-space.py
T-1/etc/plugin/expose-csr_id-ip-port-listening.py
T-1/etc/plugin/kedifa-http-reply.py
T-1/etc/plugin/monitor-bootstrap-status.py
T-1/etc/plugin/monitor-http-frontend.py
T-1/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/__init__.py
T-2/etc/plugin/backend-client-caucase-updater.py
T-2/etc/plugin/backend-haproxy-configuration.py
T-2/etc/plugin/backend_haproxy_http.py
T-2/etc/plugin/backend_haproxy_https.py
T-2/etc/plugin/buildout-T-2-status.py
T-2/etc/plugin/caddy_frontend_ipv4_http.py
T-2/etc/plugin/caddy_frontend_ipv4_https.py
T-2/etc/plugin/caddy_frontend_ipv6_http.py
T-2/etc/plugin/caddy_frontend_ipv6_https.py
T-2/etc/plugin/caucase-updater.py
T-2/etc/plugin/check-free-disk-space.py
T-2/etc/plugin/expose-csr_id-ip-port-listening.py
T-2/etc/plugin/frontend-caddy-configuration-promise.py
T-2/etc/plugin/monitor-bootstrap-status.py
T-2/etc/plugin/monitor-http-frontend.py
T-2/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/re6st-connectivity.py
T-2/etc/plugin/trafficserver-cache-availability.py
T-2/etc/plugin/trafficserver-port-listening.py
test.TestEnableHttp2ByDefaultDefaultSlave.test_file_list_run-CADDY.txt 0000664 0000000 0000000 00000000621 13723117434 0051655 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/run/monitor-httpd.pid
T-1/var/run/kedifa.pid
T-1/var/run/monitor-httpd.pid
T-2/var/run/backend-haproxy-rsyslogd.pid
T-2/var/run/backend-haproxy.pid
T-2/var/run/backend_haproxy_configuration_last_state
T-2/var/run/backend_haproxy_graceful_configuration_state_signature
T-2/var/run/bhlog.sck
T-2/var/run/graceful_configuration_state_signature
T-2/var/run/httpd.pid
T-2/var/run/monitor-httpd.pid
test.TestEnableHttp2ByDefaultDefaultSlave.test_supervisor_state-CADDY.txt 0000664 0000000 0000000 00000003304 13723117434 0052441 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0:aibcc-user-caucase-updater-on-watch RUNNING
T-0:aikc-user-caucase-updater-on-watch RUNNING
T-0:bootstrap-monitor EXITED
T-0:caucased-backend-client-{hash-generic}-on-watch RUNNING
T-0:certificate_authority-{hash-generic}-on-watch RUNNING
T-0:crond-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-graceful EXITED
T-0:rejected-slave-publish-{hash-rejected-slave-publish}-on-watch RUNNING
T-1:bootstrap-monitor EXITED
T-1:caucase-updater-on-watch RUNNING
T-1:caucased-{hash-generic}-on-watch RUNNING
T-1:certificate_authority-{hash-generic}-on-watch RUNNING
T-1:crond-{hash-generic}-on-watch RUNNING
T-1:expose-csr_id-{hash-generic}-on-watch RUNNING
T-1:kedifa-{hash-generic}-on-watch RUNNING
T-1:kedifa-reloader EXITED
T-1:monitor-httpd-{hash-generic}-on-watch RUNNING
T-1:monitor-httpd-graceful EXITED
T-2:6tunnel-11080-{hash-generic}-on-watch RUNNING
T-2:6tunnel-11443-{hash-generic}-on-watch RUNNING
T-2:backend-client-login-certificate-caucase-updater-on-watch RUNNING
T-2:backend-haproxy-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-rsyslogd-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-safe-graceful EXITED
T-2:bootstrap-monitor EXITED
T-2:certificate_authority-{hash-generic}-on-watch RUNNING
T-2:crond-{hash-generic}-on-watch RUNNING
T-2:expose-csr_id-{hash-generic}-on-watch RUNNING
T-2:frontend-caddy-safe-graceful EXITED
T-2:frontend_caddy-{hash-caddy-T-2}-on-watch RUNNING
T-2:kedifa-login-certificate-caucase-updater-on-watch RUNNING
T-2:kedifa-updater-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-graceful EXITED
T-2:trafficserver-{hash-generic}-on-watch RUNNING
T-2:trafficserver-reload EXITED
test.TestEnableHttp2ByDefaultDefaultSlaveGlobalDisableHttp2.test_file_list_etc_cron_d-CADDY.txt 0000664 0000000 0000000 00000000644 13723117434 0056504 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/cron.d/logrotate
T-0/etc/cron.d/monitor-configurator
T-0/etc/cron.d/monitor-globalstate
T-0/etc/cron.d/monitor_collect
T-1/etc/cron.d/logrotate
T-1/etc/cron.d/monitor-configurator
T-1/etc/cron.d/monitor-globalstate
T-1/etc/cron.d/monitor_collect
T-2/etc/cron.d/logrotate
T-2/etc/cron.d/monitor-configurator
T-2/etc/cron.d/monitor-globalstate
T-2/etc/cron.d/monitor_collect
T-2/etc/cron.d/trafficserver-logrotate
test.TestEnableHttp2ByDefaultDefaultSlaveGlobalDisableHttp2.test_file_list_log-CADDY.txt 0000664 0000000 0000000 00000002106 13723117434 0055161 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/log/monitor-httpd-access.log
T-0/var/log/monitor-httpd-error.log
T-0/var/log/slapgrid-T-0-error.log
T-1/var/log/expose-csr_id.log
T-1/var/log/kedifa.log
T-1/var/log/monitor-httpd-access.log
T-1/var/log/monitor-httpd-error.log
T-2/var/log/backend-haproxy.log
T-2/var/log/frontend-access.log
T-2/var/log/frontend-error.log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/httpd/_dummy-cached_access_log
T-2/var/log/httpd/_dummy-cached_backend_log
T-2/var/log/httpd/_dummy-cached_error_log
T-2/var/log/httpd/_enable-http2-default_access_log
T-2/var/log/httpd/_enable-http2-default_backend_log
T-2/var/log/httpd/_enable-http2-default_error_log
T-2/var/log/httpd/_enable-http2-false_access_log
T-2/var/log/httpd/_enable-http2-false_backend_log
T-2/var/log/httpd/_enable-http2-false_error_log
T-2/var/log/httpd/_enable-http2-true_access_log
T-2/var/log/httpd/_enable-http2-true_backend_log
T-2/var/log/httpd/_enable-http2-true_error_log
T-2/var/log/monitor-httpd-access.log
T-2/var/log/monitor-httpd-error.log
T-2/var/log/trafficserver/manager.log
T-2/var/log/trafficserver/traffic.out
test.TestEnableHttp2ByDefaultDefaultSlaveGlobalDisableHttp2.test_file_list_plugin-CADDY.txt 0000664 0000000 0000000 00000003207 13723117434 0055701 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/plugin/__init__.py
T-0/etc/plugin/aibcc-user-caucase-updater.py
T-0/etc/plugin/aikc-user-caucase-updater.py
T-0/etc/plugin/buildout-T-0-status.py
T-0/etc/plugin/caucased-backend-client.py
T-0/etc/plugin/check-free-disk-space.py
T-0/etc/plugin/monitor-bootstrap-status.py
T-0/etc/plugin/monitor-http-frontend.py
T-0/etc/plugin/monitor-httpd-listening-on-tcp.py
T-0/etc/plugin/rejected-slave-publish-ip-port-listening.py
T-0/etc/plugin/rejected-slave.py
T-1/etc/plugin/__init__.py
T-1/etc/plugin/buildout-T-1-status.py
T-1/etc/plugin/caucased.py
T-1/etc/plugin/check-free-disk-space.py
T-1/etc/plugin/expose-csr_id-ip-port-listening.py
T-1/etc/plugin/kedifa-http-reply.py
T-1/etc/plugin/monitor-bootstrap-status.py
T-1/etc/plugin/monitor-http-frontend.py
T-1/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/__init__.py
T-2/etc/plugin/backend-client-caucase-updater.py
T-2/etc/plugin/backend-haproxy-configuration.py
T-2/etc/plugin/backend_haproxy_http.py
T-2/etc/plugin/backend_haproxy_https.py
T-2/etc/plugin/buildout-T-2-status.py
T-2/etc/plugin/caddy_frontend_ipv4_http.py
T-2/etc/plugin/caddy_frontend_ipv4_https.py
T-2/etc/plugin/caddy_frontend_ipv6_http.py
T-2/etc/plugin/caddy_frontend_ipv6_https.py
T-2/etc/plugin/caucase-updater.py
T-2/etc/plugin/check-free-disk-space.py
T-2/etc/plugin/expose-csr_id-ip-port-listening.py
T-2/etc/plugin/frontend-caddy-configuration-promise.py
T-2/etc/plugin/monitor-bootstrap-status.py
T-2/etc/plugin/monitor-http-frontend.py
T-2/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/re6st-connectivity.py
T-2/etc/plugin/trafficserver-cache-availability.py
T-2/etc/plugin/trafficserver-port-listening.py
test.TestEnableHttp2ByDefaultDefaultSlaveGlobalDisableHttp2.test_file_list_run-CADDY.txt 0000664 0000000 0000000 00000000621 13723117434 0055204 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/run/monitor-httpd.pid
T-1/var/run/kedifa.pid
T-1/var/run/monitor-httpd.pid
T-2/var/run/backend-haproxy-rsyslogd.pid
T-2/var/run/backend-haproxy.pid
T-2/var/run/backend_haproxy_configuration_last_state
T-2/var/run/backend_haproxy_graceful_configuration_state_signature
T-2/var/run/bhlog.sck
T-2/var/run/graceful_configuration_state_signature
T-2/var/run/httpd.pid
T-2/var/run/monitor-httpd.pid
test.TestEnableHttp2ByDefaultDefaultSlaveGlobalDisableHttp2.test_supervisor_state-CADDY.txt 0000664 0000000 0000000 00000003304 13723117434 0055770 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0:aibcc-user-caucase-updater-on-watch RUNNING
T-0:aikc-user-caucase-updater-on-watch RUNNING
T-0:bootstrap-monitor EXITED
T-0:caucased-backend-client-{hash-generic}-on-watch RUNNING
T-0:certificate_authority-{hash-generic}-on-watch RUNNING
T-0:crond-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-graceful EXITED
T-0:rejected-slave-publish-{hash-rejected-slave-publish}-on-watch RUNNING
T-1:bootstrap-monitor EXITED
T-1:caucase-updater-on-watch RUNNING
T-1:caucased-{hash-generic}-on-watch RUNNING
T-1:certificate_authority-{hash-generic}-on-watch RUNNING
T-1:crond-{hash-generic}-on-watch RUNNING
T-1:expose-csr_id-{hash-generic}-on-watch RUNNING
T-1:kedifa-{hash-generic}-on-watch RUNNING
T-1:kedifa-reloader EXITED
T-1:monitor-httpd-{hash-generic}-on-watch RUNNING
T-1:monitor-httpd-graceful EXITED
T-2:6tunnel-11080-{hash-generic}-on-watch RUNNING
T-2:6tunnel-11443-{hash-generic}-on-watch RUNNING
T-2:backend-client-login-certificate-caucase-updater-on-watch RUNNING
T-2:backend-haproxy-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-rsyslogd-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-safe-graceful EXITED
T-2:bootstrap-monitor EXITED
T-2:certificate_authority-{hash-generic}-on-watch RUNNING
T-2:crond-{hash-generic}-on-watch RUNNING
T-2:expose-csr_id-{hash-generic}-on-watch RUNNING
T-2:frontend-caddy-safe-graceful EXITED
T-2:frontend_caddy-{hash-caddy-T-2}-on-watch RUNNING
T-2:kedifa-login-certificate-caucase-updater-on-watch RUNNING
T-2:kedifa-updater-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-graceful EXITED
T-2:trafficserver-{hash-generic}-on-watch RUNNING
T-2:trafficserver-reload EXITED
test.TestEnableHttp2ByDefaultFalseSlave.test_file_list_etc_cron_d-CADDY.txt 0000664 0000000 0000000 00000000644 13723117434 0052623 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/cron.d/logrotate
T-0/etc/cron.d/monitor-configurator
T-0/etc/cron.d/monitor-globalstate
T-0/etc/cron.d/monitor_collect
T-1/etc/cron.d/logrotate
T-1/etc/cron.d/monitor-configurator
T-1/etc/cron.d/monitor-globalstate
T-1/etc/cron.d/monitor_collect
T-2/etc/cron.d/logrotate
T-2/etc/cron.d/monitor-configurator
T-2/etc/cron.d/monitor-globalstate
T-2/etc/cron.d/monitor_collect
T-2/etc/cron.d/trafficserver-logrotate
test.TestEnableHttp2ByDefaultFalseSlave.test_file_list_log-CADDY.txt 0000664 0000000 0000000 00000002106 13723117434 0051300 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/log/monitor-httpd-access.log
T-0/var/log/monitor-httpd-error.log
T-0/var/log/slapgrid-T-0-error.log
T-1/var/log/expose-csr_id.log
T-1/var/log/kedifa.log
T-1/var/log/monitor-httpd-access.log
T-1/var/log/monitor-httpd-error.log
T-2/var/log/backend-haproxy.log
T-2/var/log/frontend-access.log
T-2/var/log/frontend-error.log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/httpd/_dummy-cached_access_log
T-2/var/log/httpd/_dummy-cached_backend_log
T-2/var/log/httpd/_dummy-cached_error_log
T-2/var/log/httpd/_enable-http2-default_access_log
T-2/var/log/httpd/_enable-http2-default_backend_log
T-2/var/log/httpd/_enable-http2-default_error_log
T-2/var/log/httpd/_enable-http2-false_access_log
T-2/var/log/httpd/_enable-http2-false_backend_log
T-2/var/log/httpd/_enable-http2-false_error_log
T-2/var/log/httpd/_enable-http2-true_access_log
T-2/var/log/httpd/_enable-http2-true_backend_log
T-2/var/log/httpd/_enable-http2-true_error_log
T-2/var/log/monitor-httpd-access.log
T-2/var/log/monitor-httpd-error.log
T-2/var/log/trafficserver/manager.log
T-2/var/log/trafficserver/traffic.out
test.TestEnableHttp2ByDefaultFalseSlave.test_file_list_plugin-CADDY.txt 0000664 0000000 0000000 00000003207 13723117434 0052020 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/plugin/__init__.py
T-0/etc/plugin/aibcc-user-caucase-updater.py
T-0/etc/plugin/aikc-user-caucase-updater.py
T-0/etc/plugin/buildout-T-0-status.py
T-0/etc/plugin/caucased-backend-client.py
T-0/etc/plugin/check-free-disk-space.py
T-0/etc/plugin/monitor-bootstrap-status.py
T-0/etc/plugin/monitor-http-frontend.py
T-0/etc/plugin/monitor-httpd-listening-on-tcp.py
T-0/etc/plugin/rejected-slave-publish-ip-port-listening.py
T-0/etc/plugin/rejected-slave.py
T-1/etc/plugin/__init__.py
T-1/etc/plugin/buildout-T-1-status.py
T-1/etc/plugin/caucased.py
T-1/etc/plugin/check-free-disk-space.py
T-1/etc/plugin/expose-csr_id-ip-port-listening.py
T-1/etc/plugin/kedifa-http-reply.py
T-1/etc/plugin/monitor-bootstrap-status.py
T-1/etc/plugin/monitor-http-frontend.py
T-1/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/__init__.py
T-2/etc/plugin/backend-client-caucase-updater.py
T-2/etc/plugin/backend-haproxy-configuration.py
T-2/etc/plugin/backend_haproxy_http.py
T-2/etc/plugin/backend_haproxy_https.py
T-2/etc/plugin/buildout-T-2-status.py
T-2/etc/plugin/caddy_frontend_ipv4_http.py
T-2/etc/plugin/caddy_frontend_ipv4_https.py
T-2/etc/plugin/caddy_frontend_ipv6_http.py
T-2/etc/plugin/caddy_frontend_ipv6_https.py
T-2/etc/plugin/caucase-updater.py
T-2/etc/plugin/check-free-disk-space.py
T-2/etc/plugin/expose-csr_id-ip-port-listening.py
T-2/etc/plugin/frontend-caddy-configuration-promise.py
T-2/etc/plugin/monitor-bootstrap-status.py
T-2/etc/plugin/monitor-http-frontend.py
T-2/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/re6st-connectivity.py
T-2/etc/plugin/trafficserver-cache-availability.py
T-2/etc/plugin/trafficserver-port-listening.py
test.TestEnableHttp2ByDefaultFalseSlave.test_file_list_run-CADDY.txt 0000664 0000000 0000000 00000000621 13723117434 0051323 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/run/monitor-httpd.pid
T-1/var/run/kedifa.pid
T-1/var/run/monitor-httpd.pid
T-2/var/run/backend-haproxy-rsyslogd.pid
T-2/var/run/backend-haproxy.pid
T-2/var/run/backend_haproxy_configuration_last_state
T-2/var/run/backend_haproxy_graceful_configuration_state_signature
T-2/var/run/bhlog.sck
T-2/var/run/graceful_configuration_state_signature
T-2/var/run/httpd.pid
T-2/var/run/monitor-httpd.pid
test.TestEnableHttp2ByDefaultFalseSlave.test_supervisor_state-CADDY.txt 0000664 0000000 0000000 00000003304 13723117434 0052107 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0:aibcc-user-caucase-updater-on-watch RUNNING
T-0:aikc-user-caucase-updater-on-watch RUNNING
T-0:bootstrap-monitor EXITED
T-0:caucased-backend-client-{hash-generic}-on-watch RUNNING
T-0:certificate_authority-{hash-generic}-on-watch RUNNING
T-0:crond-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-graceful EXITED
T-0:rejected-slave-publish-{hash-rejected-slave-publish}-on-watch RUNNING
T-1:bootstrap-monitor EXITED
T-1:caucase-updater-on-watch RUNNING
T-1:caucased-{hash-generic}-on-watch RUNNING
T-1:certificate_authority-{hash-generic}-on-watch RUNNING
T-1:crond-{hash-generic}-on-watch RUNNING
T-1:expose-csr_id-{hash-generic}-on-watch RUNNING
T-1:kedifa-{hash-generic}-on-watch RUNNING
T-1:kedifa-reloader EXITED
T-1:monitor-httpd-{hash-generic}-on-watch RUNNING
T-1:monitor-httpd-graceful EXITED
T-2:6tunnel-11080-{hash-generic}-on-watch RUNNING
T-2:6tunnel-11443-{hash-generic}-on-watch RUNNING
T-2:backend-client-login-certificate-caucase-updater-on-watch RUNNING
T-2:backend-haproxy-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-rsyslogd-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-safe-graceful EXITED
T-2:bootstrap-monitor EXITED
T-2:certificate_authority-{hash-generic}-on-watch RUNNING
T-2:crond-{hash-generic}-on-watch RUNNING
T-2:expose-csr_id-{hash-generic}-on-watch RUNNING
T-2:frontend-caddy-safe-graceful EXITED
T-2:frontend_caddy-{hash-caddy-T-2}-on-watch RUNNING
T-2:kedifa-login-certificate-caucase-updater-on-watch RUNNING
T-2:kedifa-updater-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-graceful EXITED
T-2:trafficserver-{hash-generic}-on-watch RUNNING
T-2:trafficserver-reload EXITED
test.TestEnableHttp2ByDefaultFalseSlaveGlobalDisableHttp2.test_file_list_etc_cron_d-CADDY.txt 0000664 0000000 0000000 00000000644 13723117434 0056152 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/cron.d/logrotate
T-0/etc/cron.d/monitor-configurator
T-0/etc/cron.d/monitor-globalstate
T-0/etc/cron.d/monitor_collect
T-1/etc/cron.d/logrotate
T-1/etc/cron.d/monitor-configurator
T-1/etc/cron.d/monitor-globalstate
T-1/etc/cron.d/monitor_collect
T-2/etc/cron.d/logrotate
T-2/etc/cron.d/monitor-configurator
T-2/etc/cron.d/monitor-globalstate
T-2/etc/cron.d/monitor_collect
T-2/etc/cron.d/trafficserver-logrotate
test.TestEnableHttp2ByDefaultFalseSlaveGlobalDisableHttp2.test_file_list_log-CADDY.txt 0000664 0000000 0000000 00000002106 13723117434 0054627 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/log/monitor-httpd-access.log
T-0/var/log/monitor-httpd-error.log
T-0/var/log/slapgrid-T-0-error.log
T-1/var/log/expose-csr_id.log
T-1/var/log/kedifa.log
T-1/var/log/monitor-httpd-access.log
T-1/var/log/monitor-httpd-error.log
T-2/var/log/backend-haproxy.log
T-2/var/log/frontend-access.log
T-2/var/log/frontend-error.log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/httpd/_dummy-cached_access_log
T-2/var/log/httpd/_dummy-cached_backend_log
T-2/var/log/httpd/_dummy-cached_error_log
T-2/var/log/httpd/_enable-http2-default_access_log
T-2/var/log/httpd/_enable-http2-default_backend_log
T-2/var/log/httpd/_enable-http2-default_error_log
T-2/var/log/httpd/_enable-http2-false_access_log
T-2/var/log/httpd/_enable-http2-false_backend_log
T-2/var/log/httpd/_enable-http2-false_error_log
T-2/var/log/httpd/_enable-http2-true_access_log
T-2/var/log/httpd/_enable-http2-true_backend_log
T-2/var/log/httpd/_enable-http2-true_error_log
T-2/var/log/monitor-httpd-access.log
T-2/var/log/monitor-httpd-error.log
T-2/var/log/trafficserver/manager.log
T-2/var/log/trafficserver/traffic.out
test.TestEnableHttp2ByDefaultFalseSlaveGlobalDisableHttp2.test_file_list_plugin-CADDY.txt 0000664 0000000 0000000 00000003207 13723117434 0055347 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/plugin/__init__.py
T-0/etc/plugin/aibcc-user-caucase-updater.py
T-0/etc/plugin/aikc-user-caucase-updater.py
T-0/etc/plugin/buildout-T-0-status.py
T-0/etc/plugin/caucased-backend-client.py
T-0/etc/plugin/check-free-disk-space.py
T-0/etc/plugin/monitor-bootstrap-status.py
T-0/etc/plugin/monitor-http-frontend.py
T-0/etc/plugin/monitor-httpd-listening-on-tcp.py
T-0/etc/plugin/rejected-slave-publish-ip-port-listening.py
T-0/etc/plugin/rejected-slave.py
T-1/etc/plugin/__init__.py
T-1/etc/plugin/buildout-T-1-status.py
T-1/etc/plugin/caucased.py
T-1/etc/plugin/check-free-disk-space.py
T-1/etc/plugin/expose-csr_id-ip-port-listening.py
T-1/etc/plugin/kedifa-http-reply.py
T-1/etc/plugin/monitor-bootstrap-status.py
T-1/etc/plugin/monitor-http-frontend.py
T-1/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/__init__.py
T-2/etc/plugin/backend-client-caucase-updater.py
T-2/etc/plugin/backend-haproxy-configuration.py
T-2/etc/plugin/backend_haproxy_http.py
T-2/etc/plugin/backend_haproxy_https.py
T-2/etc/plugin/buildout-T-2-status.py
T-2/etc/plugin/caddy_frontend_ipv4_http.py
T-2/etc/plugin/caddy_frontend_ipv4_https.py
T-2/etc/plugin/caddy_frontend_ipv6_http.py
T-2/etc/plugin/caddy_frontend_ipv6_https.py
T-2/etc/plugin/caucase-updater.py
T-2/etc/plugin/check-free-disk-space.py
T-2/etc/plugin/expose-csr_id-ip-port-listening.py
T-2/etc/plugin/frontend-caddy-configuration-promise.py
T-2/etc/plugin/monitor-bootstrap-status.py
T-2/etc/plugin/monitor-http-frontend.py
T-2/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/re6st-connectivity.py
T-2/etc/plugin/trafficserver-cache-availability.py
T-2/etc/plugin/trafficserver-port-listening.py
test.TestEnableHttp2ByDefaultFalseSlaveGlobalDisableHttp2.test_file_list_run-CADDY.txt 0000664 0000000 0000000 00000000621 13723117434 0054652 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/run/monitor-httpd.pid
T-1/var/run/kedifa.pid
T-1/var/run/monitor-httpd.pid
T-2/var/run/backend-haproxy-rsyslogd.pid
T-2/var/run/backend-haproxy.pid
T-2/var/run/backend_haproxy_configuration_last_state
T-2/var/run/backend_haproxy_graceful_configuration_state_signature
T-2/var/run/bhlog.sck
T-2/var/run/graceful_configuration_state_signature
T-2/var/run/httpd.pid
T-2/var/run/monitor-httpd.pid
test.TestEnableHttp2ByDefaultFalseSlaveGlobalDisableHttp2.test_supervisor_state-CADDY.txt 0000664 0000000 0000000 00000003304 13723117434 0055436 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0:aibcc-user-caucase-updater-on-watch RUNNING
T-0:aikc-user-caucase-updater-on-watch RUNNING
T-0:bootstrap-monitor EXITED
T-0:caucased-backend-client-{hash-generic}-on-watch RUNNING
T-0:certificate_authority-{hash-generic}-on-watch RUNNING
T-0:crond-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-graceful EXITED
T-0:rejected-slave-publish-{hash-rejected-slave-publish}-on-watch RUNNING
T-1:bootstrap-monitor EXITED
T-1:caucase-updater-on-watch RUNNING
T-1:caucased-{hash-generic}-on-watch RUNNING
T-1:certificate_authority-{hash-generic}-on-watch RUNNING
T-1:crond-{hash-generic}-on-watch RUNNING
T-1:expose-csr_id-{hash-generic}-on-watch RUNNING
T-1:kedifa-{hash-generic}-on-watch RUNNING
T-1:kedifa-reloader EXITED
T-1:monitor-httpd-{hash-generic}-on-watch RUNNING
T-1:monitor-httpd-graceful EXITED
T-2:6tunnel-11080-{hash-generic}-on-watch RUNNING
T-2:6tunnel-11443-{hash-generic}-on-watch RUNNING
T-2:backend-client-login-certificate-caucase-updater-on-watch RUNNING
T-2:backend-haproxy-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-rsyslogd-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-safe-graceful EXITED
T-2:bootstrap-monitor EXITED
T-2:certificate_authority-{hash-generic}-on-watch RUNNING
T-2:crond-{hash-generic}-on-watch RUNNING
T-2:expose-csr_id-{hash-generic}-on-watch RUNNING
T-2:frontend-caddy-safe-graceful EXITED
T-2:frontend_caddy-{hash-caddy-T-2}-on-watch RUNNING
T-2:kedifa-login-certificate-caucase-updater-on-watch RUNNING
T-2:kedifa-updater-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-graceful EXITED
T-2:trafficserver-{hash-generic}-on-watch RUNNING
T-2:trafficserver-reload EXITED
test.TestMasterRequest.test_file_list_etc_cron_d-CADDY.txt 0000664 0000000 0000000 00000000644 13723117434 0047551 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/cron.d/logrotate
T-0/etc/cron.d/monitor-configurator
T-0/etc/cron.d/monitor-globalstate
T-0/etc/cron.d/monitor_collect
T-1/etc/cron.d/logrotate
T-1/etc/cron.d/monitor-configurator
T-1/etc/cron.d/monitor-globalstate
T-1/etc/cron.d/monitor_collect
T-2/etc/cron.d/logrotate
T-2/etc/cron.d/monitor-configurator
T-2/etc/cron.d/monitor-globalstate
T-2/etc/cron.d/monitor_collect
T-2/etc/cron.d/trafficserver-logrotate
test.TestMasterRequest.test_file_list_log-CADDY.txt 0000664 0000000 0000000 00000001011 13723117434 0046220 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/log/monitor-httpd-access.log
T-0/var/log/monitor-httpd-error.log
T-0/var/log/slapgrid-T-0-error.log
T-1/var/log/expose-csr_id.log
T-1/var/log/kedifa.log
T-1/var/log/monitor-httpd-access.log
T-1/var/log/monitor-httpd-error.log
T-2/var/log/backend-haproxy.log
T-2/var/log/frontend-access.log
T-2/var/log/frontend-error.log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/monitor-httpd-access.log
T-2/var/log/monitor-httpd-error.log
T-2/var/log/trafficserver/manager.log
T-2/var/log/trafficserver/traffic.out
test.TestMasterRequest.test_file_list_plugin-CADDY.txt 0000664 0000000 0000000 00000003207 13723117434 0046746 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/plugin/__init__.py
T-0/etc/plugin/aibcc-user-caucase-updater.py
T-0/etc/plugin/aikc-user-caucase-updater.py
T-0/etc/plugin/buildout-T-0-status.py
T-0/etc/plugin/caucased-backend-client.py
T-0/etc/plugin/check-free-disk-space.py
T-0/etc/plugin/monitor-bootstrap-status.py
T-0/etc/plugin/monitor-http-frontend.py
T-0/etc/plugin/monitor-httpd-listening-on-tcp.py
T-0/etc/plugin/rejected-slave-publish-ip-port-listening.py
T-0/etc/plugin/rejected-slave.py
T-1/etc/plugin/__init__.py
T-1/etc/plugin/buildout-T-1-status.py
T-1/etc/plugin/caucased.py
T-1/etc/plugin/check-free-disk-space.py
T-1/etc/plugin/expose-csr_id-ip-port-listening.py
T-1/etc/plugin/kedifa-http-reply.py
T-1/etc/plugin/monitor-bootstrap-status.py
T-1/etc/plugin/monitor-http-frontend.py
T-1/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/__init__.py
T-2/etc/plugin/backend-client-caucase-updater.py
T-2/etc/plugin/backend-haproxy-configuration.py
T-2/etc/plugin/backend_haproxy_http.py
T-2/etc/plugin/backend_haproxy_https.py
T-2/etc/plugin/buildout-T-2-status.py
T-2/etc/plugin/caddy_frontend_ipv4_http.py
T-2/etc/plugin/caddy_frontend_ipv4_https.py
T-2/etc/plugin/caddy_frontend_ipv6_http.py
T-2/etc/plugin/caddy_frontend_ipv6_https.py
T-2/etc/plugin/caucase-updater.py
T-2/etc/plugin/check-free-disk-space.py
T-2/etc/plugin/expose-csr_id-ip-port-listening.py
T-2/etc/plugin/frontend-caddy-configuration-promise.py
T-2/etc/plugin/monitor-bootstrap-status.py
T-2/etc/plugin/monitor-http-frontend.py
T-2/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/re6st-connectivity.py
T-2/etc/plugin/trafficserver-cache-availability.py
T-2/etc/plugin/trafficserver-port-listening.py
test.TestMasterRequest.test_file_list_run-CADDY.txt 0000664 0000000 0000000 00000000621 13723117434 0046251 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/run/monitor-httpd.pid
T-1/var/run/kedifa.pid
T-1/var/run/monitor-httpd.pid
T-2/var/run/backend-haproxy-rsyslogd.pid
T-2/var/run/backend-haproxy.pid
T-2/var/run/backend_haproxy_configuration_last_state
T-2/var/run/backend_haproxy_graceful_configuration_state_signature
T-2/var/run/bhlog.sck
T-2/var/run/graceful_configuration_state_signature
T-2/var/run/httpd.pid
T-2/var/run/monitor-httpd.pid
test.TestMasterRequest.test_supervisor_state-CADDY.txt 0000664 0000000 0000000 00000003304 13723117434 0047035 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0:aibcc-user-caucase-updater-on-watch RUNNING
T-0:aikc-user-caucase-updater-on-watch RUNNING
T-0:bootstrap-monitor EXITED
T-0:caucased-backend-client-{hash-generic}-on-watch RUNNING
T-0:certificate_authority-{hash-generic}-on-watch RUNNING
T-0:crond-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-graceful EXITED
T-0:rejected-slave-publish-{hash-rejected-slave-publish}-on-watch RUNNING
T-1:bootstrap-monitor EXITED
T-1:caucase-updater-on-watch RUNNING
T-1:caucased-{hash-generic}-on-watch RUNNING
T-1:certificate_authority-{hash-generic}-on-watch RUNNING
T-1:crond-{hash-generic}-on-watch RUNNING
T-1:expose-csr_id-{hash-generic}-on-watch RUNNING
T-1:kedifa-{hash-generic}-on-watch RUNNING
T-1:kedifa-reloader EXITED
T-1:monitor-httpd-{hash-generic}-on-watch RUNNING
T-1:monitor-httpd-graceful EXITED
T-2:6tunnel-11080-{hash-generic}-on-watch RUNNING
T-2:6tunnel-11443-{hash-generic}-on-watch RUNNING
T-2:backend-client-login-certificate-caucase-updater-on-watch RUNNING
T-2:backend-haproxy-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-rsyslogd-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-safe-graceful EXITED
T-2:bootstrap-monitor EXITED
T-2:certificate_authority-{hash-generic}-on-watch RUNNING
T-2:crond-{hash-generic}-on-watch RUNNING
T-2:expose-csr_id-{hash-generic}-on-watch RUNNING
T-2:frontend-caddy-safe-graceful EXITED
T-2:frontend_caddy-{hash-caddy-T-2}-on-watch RUNNING
T-2:kedifa-login-certificate-caucase-updater-on-watch RUNNING
T-2:kedifa-updater-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-graceful EXITED
T-2:trafficserver-{hash-generic}-on-watch RUNNING
T-2:trafficserver-reload EXITED
test.TestMasterRequestDomain.test_file_list_etc_cron_d-CADDY.txt 0000664 0000000 0000000 00000000644 13723117434 0050701 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/cron.d/logrotate
T-0/etc/cron.d/monitor-configurator
T-0/etc/cron.d/monitor-globalstate
T-0/etc/cron.d/monitor_collect
T-1/etc/cron.d/logrotate
T-1/etc/cron.d/monitor-configurator
T-1/etc/cron.d/monitor-globalstate
T-1/etc/cron.d/monitor_collect
T-2/etc/cron.d/logrotate
T-2/etc/cron.d/monitor-configurator
T-2/etc/cron.d/monitor-globalstate
T-2/etc/cron.d/monitor_collect
T-2/etc/cron.d/trafficserver-logrotate
test.TestMasterRequestDomain.test_file_list_log-CADDY.txt 0000664 0000000 0000000 00000001011 13723117434 0047350 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/log/monitor-httpd-access.log
T-0/var/log/monitor-httpd-error.log
T-0/var/log/slapgrid-T-0-error.log
T-1/var/log/expose-csr_id.log
T-1/var/log/kedifa.log
T-1/var/log/monitor-httpd-access.log
T-1/var/log/monitor-httpd-error.log
T-2/var/log/backend-haproxy.log
T-2/var/log/frontend-access.log
T-2/var/log/frontend-error.log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/monitor-httpd-access.log
T-2/var/log/monitor-httpd-error.log
T-2/var/log/trafficserver/manager.log
T-2/var/log/trafficserver/traffic.out
test.TestMasterRequestDomain.test_file_list_plugin-CADDY.txt 0000664 0000000 0000000 00000003207 13723117434 0050076 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/plugin/__init__.py
T-0/etc/plugin/aibcc-user-caucase-updater.py
T-0/etc/plugin/aikc-user-caucase-updater.py
T-0/etc/plugin/buildout-T-0-status.py
T-0/etc/plugin/caucased-backend-client.py
T-0/etc/plugin/check-free-disk-space.py
T-0/etc/plugin/monitor-bootstrap-status.py
T-0/etc/plugin/monitor-http-frontend.py
T-0/etc/plugin/monitor-httpd-listening-on-tcp.py
T-0/etc/plugin/rejected-slave-publish-ip-port-listening.py
T-0/etc/plugin/rejected-slave.py
T-1/etc/plugin/__init__.py
T-1/etc/plugin/buildout-T-1-status.py
T-1/etc/plugin/caucased.py
T-1/etc/plugin/check-free-disk-space.py
T-1/etc/plugin/expose-csr_id-ip-port-listening.py
T-1/etc/plugin/kedifa-http-reply.py
T-1/etc/plugin/monitor-bootstrap-status.py
T-1/etc/plugin/monitor-http-frontend.py
T-1/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/__init__.py
T-2/etc/plugin/backend-client-caucase-updater.py
T-2/etc/plugin/backend-haproxy-configuration.py
T-2/etc/plugin/backend_haproxy_http.py
T-2/etc/plugin/backend_haproxy_https.py
T-2/etc/plugin/buildout-T-2-status.py
T-2/etc/plugin/caddy_frontend_ipv4_http.py
T-2/etc/plugin/caddy_frontend_ipv4_https.py
T-2/etc/plugin/caddy_frontend_ipv6_http.py
T-2/etc/plugin/caddy_frontend_ipv6_https.py
T-2/etc/plugin/caucase-updater.py
T-2/etc/plugin/check-free-disk-space.py
T-2/etc/plugin/expose-csr_id-ip-port-listening.py
T-2/etc/plugin/frontend-caddy-configuration-promise.py
T-2/etc/plugin/monitor-bootstrap-status.py
T-2/etc/plugin/monitor-http-frontend.py
T-2/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/re6st-connectivity.py
T-2/etc/plugin/trafficserver-cache-availability.py
T-2/etc/plugin/trafficserver-port-listening.py
test.TestMasterRequestDomain.test_file_list_run-CADDY.txt 0000664 0000000 0000000 00000000621 13723117434 0047401 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/run/monitor-httpd.pid
T-1/var/run/kedifa.pid
T-1/var/run/monitor-httpd.pid
T-2/var/run/backend-haproxy-rsyslogd.pid
T-2/var/run/backend-haproxy.pid
T-2/var/run/backend_haproxy_configuration_last_state
T-2/var/run/backend_haproxy_graceful_configuration_state_signature
T-2/var/run/bhlog.sck
T-2/var/run/graceful_configuration_state_signature
T-2/var/run/httpd.pid
T-2/var/run/monitor-httpd.pid
test.TestMasterRequestDomain.test_supervisor_state-CADDY.txt 0000664 0000000 0000000 00000003304 13723117434 0050165 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0:aibcc-user-caucase-updater-on-watch RUNNING
T-0:aikc-user-caucase-updater-on-watch RUNNING
T-0:bootstrap-monitor EXITED
T-0:caucased-backend-client-{hash-generic}-on-watch RUNNING
T-0:certificate_authority-{hash-generic}-on-watch RUNNING
T-0:crond-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-graceful EXITED
T-0:rejected-slave-publish-{hash-rejected-slave-publish}-on-watch RUNNING
T-1:bootstrap-monitor EXITED
T-1:caucase-updater-on-watch RUNNING
T-1:caucased-{hash-generic}-on-watch RUNNING
T-1:certificate_authority-{hash-generic}-on-watch RUNNING
T-1:crond-{hash-generic}-on-watch RUNNING
T-1:expose-csr_id-{hash-generic}-on-watch RUNNING
T-1:kedifa-{hash-generic}-on-watch RUNNING
T-1:kedifa-reloader EXITED
T-1:monitor-httpd-{hash-generic}-on-watch RUNNING
T-1:monitor-httpd-graceful EXITED
T-2:6tunnel-11080-{hash-generic}-on-watch RUNNING
T-2:6tunnel-11443-{hash-generic}-on-watch RUNNING
T-2:backend-client-login-certificate-caucase-updater-on-watch RUNNING
T-2:backend-haproxy-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-rsyslogd-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-safe-graceful EXITED
T-2:bootstrap-monitor EXITED
T-2:certificate_authority-{hash-generic}-on-watch RUNNING
T-2:crond-{hash-generic}-on-watch RUNNING
T-2:expose-csr_id-{hash-generic}-on-watch RUNNING
T-2:frontend-caddy-safe-graceful EXITED
T-2:frontend_caddy-{hash-caddy-T-2}-on-watch RUNNING
T-2:kedifa-login-certificate-caucase-updater-on-watch RUNNING
T-2:kedifa-updater-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-graceful EXITED
T-2:trafficserver-{hash-generic}-on-watch RUNNING
T-2:trafficserver-reload EXITED
test.TestRe6stVerificationUrlDefaultSlave.test_file_list_etc_cron_d-CADDY.txt 0000664 0000000 0000000 00000000644 13723117434 0053276 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/cron.d/logrotate
T-0/etc/cron.d/monitor-configurator
T-0/etc/cron.d/monitor-globalstate
T-0/etc/cron.d/monitor_collect
T-1/etc/cron.d/logrotate
T-1/etc/cron.d/monitor-configurator
T-1/etc/cron.d/monitor-globalstate
T-1/etc/cron.d/monitor_collect
T-2/etc/cron.d/logrotate
T-2/etc/cron.d/monitor-configurator
T-2/etc/cron.d/monitor-globalstate
T-2/etc/cron.d/monitor_collect
T-2/etc/cron.d/trafficserver-logrotate
test.TestRe6stVerificationUrlDefaultSlave.test_file_list_log-CADDY.txt 0000664 0000000 0000000 00000001124 13723117434 0051752 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/log/monitor-httpd-access.log
T-0/var/log/monitor-httpd-error.log
T-0/var/log/slapgrid-T-0-error.log
T-1/var/log/expose-csr_id.log
T-1/var/log/kedifa.log
T-1/var/log/monitor-httpd-access.log
T-1/var/log/monitor-httpd-error.log
T-2/var/log/backend-haproxy.log
T-2/var/log/frontend-access.log
T-2/var/log/frontend-error.log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/httpd/_default_access_log
T-2/var/log/httpd/_default_error_log
T-2/var/log/monitor-httpd-access.log
T-2/var/log/monitor-httpd-error.log
T-2/var/log/trafficserver/manager.log
T-2/var/log/trafficserver/traffic.out
test.TestRe6stVerificationUrlDefaultSlave.test_file_list_plugin-CADDY.txt 0000664 0000000 0000000 00000003207 13723117434 0052473 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/plugin/__init__.py
T-0/etc/plugin/aibcc-user-caucase-updater.py
T-0/etc/plugin/aikc-user-caucase-updater.py
T-0/etc/plugin/buildout-T-0-status.py
T-0/etc/plugin/caucased-backend-client.py
T-0/etc/plugin/check-free-disk-space.py
T-0/etc/plugin/monitor-bootstrap-status.py
T-0/etc/plugin/monitor-http-frontend.py
T-0/etc/plugin/monitor-httpd-listening-on-tcp.py
T-0/etc/plugin/rejected-slave-publish-ip-port-listening.py
T-0/etc/plugin/rejected-slave.py
T-1/etc/plugin/__init__.py
T-1/etc/plugin/buildout-T-1-status.py
T-1/etc/plugin/caucased.py
T-1/etc/plugin/check-free-disk-space.py
T-1/etc/plugin/expose-csr_id-ip-port-listening.py
T-1/etc/plugin/kedifa-http-reply.py
T-1/etc/plugin/monitor-bootstrap-status.py
T-1/etc/plugin/monitor-http-frontend.py
T-1/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/__init__.py
T-2/etc/plugin/backend-client-caucase-updater.py
T-2/etc/plugin/backend-haproxy-configuration.py
T-2/etc/plugin/backend_haproxy_http.py
T-2/etc/plugin/backend_haproxy_https.py
T-2/etc/plugin/buildout-T-2-status.py
T-2/etc/plugin/caddy_frontend_ipv4_http.py
T-2/etc/plugin/caddy_frontend_ipv4_https.py
T-2/etc/plugin/caddy_frontend_ipv6_http.py
T-2/etc/plugin/caddy_frontend_ipv6_https.py
T-2/etc/plugin/caucase-updater.py
T-2/etc/plugin/check-free-disk-space.py
T-2/etc/plugin/expose-csr_id-ip-port-listening.py
T-2/etc/plugin/frontend-caddy-configuration-promise.py
T-2/etc/plugin/monitor-bootstrap-status.py
T-2/etc/plugin/monitor-http-frontend.py
T-2/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/re6st-connectivity.py
T-2/etc/plugin/trafficserver-cache-availability.py
T-2/etc/plugin/trafficserver-port-listening.py
test.TestRe6stVerificationUrlDefaultSlave.test_file_list_run-CADDY.txt 0000664 0000000 0000000 00000000621 13723117434 0051776 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/run/monitor-httpd.pid
T-1/var/run/kedifa.pid
T-1/var/run/monitor-httpd.pid
T-2/var/run/backend-haproxy-rsyslogd.pid
T-2/var/run/backend-haproxy.pid
T-2/var/run/backend_haproxy_configuration_last_state
T-2/var/run/backend_haproxy_graceful_configuration_state_signature
T-2/var/run/bhlog.sck
T-2/var/run/graceful_configuration_state_signature
T-2/var/run/httpd.pid
T-2/var/run/monitor-httpd.pid
test.TestRe6stVerificationUrlDefaultSlave.test_supervisor_state-CADDY.txt 0000664 0000000 0000000 00000003304 13723117434 0052562 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0:aibcc-user-caucase-updater-on-watch RUNNING
T-0:aikc-user-caucase-updater-on-watch RUNNING
T-0:bootstrap-monitor EXITED
T-0:caucased-backend-client-{hash-generic}-on-watch RUNNING
T-0:certificate_authority-{hash-generic}-on-watch RUNNING
T-0:crond-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-graceful EXITED
T-0:rejected-slave-publish-{hash-rejected-slave-publish}-on-watch RUNNING
T-1:bootstrap-monitor EXITED
T-1:caucase-updater-on-watch RUNNING
T-1:caucased-{hash-generic}-on-watch RUNNING
T-1:certificate_authority-{hash-generic}-on-watch RUNNING
T-1:crond-{hash-generic}-on-watch RUNNING
T-1:expose-csr_id-{hash-generic}-on-watch RUNNING
T-1:kedifa-{hash-generic}-on-watch RUNNING
T-1:kedifa-reloader EXITED
T-1:monitor-httpd-{hash-generic}-on-watch RUNNING
T-1:monitor-httpd-graceful EXITED
T-2:6tunnel-11080-{hash-generic}-on-watch RUNNING
T-2:6tunnel-11443-{hash-generic}-on-watch RUNNING
T-2:backend-client-login-certificate-caucase-updater-on-watch RUNNING
T-2:backend-haproxy-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-rsyslogd-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-safe-graceful EXITED
T-2:bootstrap-monitor EXITED
T-2:certificate_authority-{hash-generic}-on-watch RUNNING
T-2:crond-{hash-generic}-on-watch RUNNING
T-2:expose-csr_id-{hash-generic}-on-watch RUNNING
T-2:frontend-caddy-safe-graceful EXITED
T-2:frontend_caddy-{hash-caddy-T-2}-on-watch RUNNING
T-2:kedifa-login-certificate-caucase-updater-on-watch RUNNING
T-2:kedifa-updater-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-graceful EXITED
T-2:trafficserver-{hash-generic}-on-watch RUNNING
T-2:trafficserver-reload EXITED
test.TestSlave.test_file_list_etc_cron_d-CADDY.txt 0000664 0000000 0000000 00000000644 13723117434 0046017 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/cron.d/logrotate
T-0/etc/cron.d/monitor-configurator
T-0/etc/cron.d/monitor-globalstate
T-0/etc/cron.d/monitor_collect
T-1/etc/cron.d/logrotate
T-1/etc/cron.d/monitor-configurator
T-1/etc/cron.d/monitor-globalstate
T-1/etc/cron.d/monitor_collect
T-2/etc/cron.d/logrotate
T-2/etc/cron.d/monitor-configurator
T-2/etc/cron.d/monitor-globalstate
T-2/etc/cron.d/monitor_collect
T-2/etc/cron.d/trafficserver-logrotate
test.TestSlave.test_file_list_log-CADDY.txt 0000664 0000000 0000000 00000023626 13723117434 0044506 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/log/monitor-httpd-access.log
T-0/var/log/monitor-httpd-error.log
T-0/var/log/slapgrid-T-0-error.log
T-1/var/log/expose-csr_id.log
T-1/var/log/kedifa.log
T-1/var/log/monitor-httpd-access.log
T-1/var/log/monitor-httpd-error.log
T-2/var/log/backend-haproxy.log
T-2/var/log/frontend-access.log
T-2/var/log/frontend-error.log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/httpd/_Url_access_log
T-2/var/log/httpd/_Url_backend_log
T-2/var/log/httpd/_Url_error_log
T-2/var/log/httpd/_auth-to-backend-backend-ignore_access_log
T-2/var/log/httpd/_auth-to-backend-backend-ignore_backend_log
T-2/var/log/httpd/_auth-to-backend-backend-ignore_error_log
T-2/var/log/httpd/_auth-to-backend-not-configured_access_log
T-2/var/log/httpd/_auth-to-backend-not-configured_backend_log
T-2/var/log/httpd/_auth-to-backend-not-configured_error_log
T-2/var/log/httpd/_auth-to-backend_access_log
T-2/var/log/httpd/_auth-to-backend_backend_log
T-2/var/log/httpd/_auth-to-backend_error_log
T-2/var/log/httpd/_ciphers_access_log
T-2/var/log/httpd/_ciphers_backend_log
T-2/var/log/httpd/_ciphers_error_log
T-2/var/log/httpd/_custom_domain_access_log
T-2/var/log/httpd/_custom_domain_backend_log
T-2/var/log/httpd/_custom_domain_error_log
T-2/var/log/httpd/_custom_domain_server_alias_access_log
T-2/var/log/httpd/_custom_domain_server_alias_backend_log
T-2/var/log/httpd/_custom_domain_server_alias_error_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_access_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_backend_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_error_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_ssl_ca_crt_access_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_ssl_ca_crt_backend_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_ssl_ca_crt_error_log
T-2/var/log/httpd/_custom_domain_wildcard_access_log
T-2/var/log/httpd/_custom_domain_wildcard_backend_log
T-2/var/log/httpd/_custom_domain_wildcard_error_log
T-2/var/log/httpd/_disabled-cookie-list_access_log
T-2/var/log/httpd/_disabled-cookie-list_backend_log
T-2/var/log/httpd/_disabled-cookie-list_error_log
T-2/var/log/httpd/_empty_access_log
T-2/var/log/httpd/_empty_backend_log
T-2/var/log/httpd/_empty_error_log
T-2/var/log/httpd/_enable-http2-default_access_log
T-2/var/log/httpd/_enable-http2-default_backend_log
T-2/var/log/httpd/_enable-http2-default_error_log
T-2/var/log/httpd/_enable-http2-false_access_log
T-2/var/log/httpd/_enable-http2-false_backend_log
T-2/var/log/httpd/_enable-http2-false_error_log
T-2/var/log/httpd/_enable_cache-disable-no-cache-request_access_log
T-2/var/log/httpd/_enable_cache-disable-no-cache-request_backend_log
T-2/var/log/httpd/_enable_cache-disable-no-cache-request_error_log
T-2/var/log/httpd/_enable_cache-disable-via-header_access_log
T-2/var/log/httpd/_enable_cache-disable-via-header_backend_log
T-2/var/log/httpd/_enable_cache-disable-via-header_error_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify-unverified_access_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify-unverified_backend_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify-unverified_error_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt-unverified_access_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt-unverified_backend_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt-unverified_error_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt_access_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt_backend_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt_error_log
T-2/var/log/httpd/_enable_cache_access_log
T-2/var/log/httpd/_enable_cache_backend_log
T-2/var/log/httpd/_enable_cache_custom_domain_access_log
T-2/var/log/httpd/_enable_cache_custom_domain_backend_log
T-2/var/log/httpd/_enable_cache_custom_domain_error_log
T-2/var/log/httpd/_enable_cache_error_log
T-2/var/log/httpd/_enable_cache_server_alias_access_log
T-2/var/log/httpd/_enable_cache_server_alias_backend_log
T-2/var/log/httpd/_enable_cache_server_alias_error_log
T-2/var/log/httpd/_https-only_access_log
T-2/var/log/httpd/_https-only_backend_log
T-2/var/log/httpd/_https-only_error_log
T-2/var/log/httpd/_monitor-ipv4-test_access_log
T-2/var/log/httpd/_monitor-ipv4-test_backend_log
T-2/var/log/httpd/_monitor-ipv4-test_error_log
T-2/var/log/httpd/_monitor-ipv6-test_access_log
T-2/var/log/httpd/_monitor-ipv6-test_backend_log
T-2/var/log/httpd/_monitor-ipv6-test_error_log
T-2/var/log/httpd/_prefer-gzip-encoding-to-backend-https-only_access_log
T-2/var/log/httpd/_prefer-gzip-encoding-to-backend-https-only_backend_log
T-2/var/log/httpd/_prefer-gzip-encoding-to-backend-https-only_error_log
T-2/var/log/httpd/_prefer-gzip-encoding-to-backend_access_log
T-2/var/log/httpd/_prefer-gzip-encoding-to-backend_backend_log
T-2/var/log/httpd/_prefer-gzip-encoding-to-backend_error_log
T-2/var/log/httpd/_server-alias-duplicated_access_log
T-2/var/log/httpd/_server-alias-duplicated_backend_log
T-2/var/log/httpd/_server-alias-duplicated_error_log
T-2/var/log/httpd/_server-alias-empty_access_log
T-2/var/log/httpd/_server-alias-empty_backend_log
T-2/var/log/httpd/_server-alias-empty_error_log
T-2/var/log/httpd/_server-alias-wildcard_access_log
T-2/var/log/httpd/_server-alias-wildcard_backend_log
T-2/var/log/httpd/_server-alias-wildcard_error_log
T-2/var/log/httpd/_server-alias_access_log
T-2/var/log/httpd/_server-alias_backend_log
T-2/var/log/httpd/_server-alias_custom_domain-duplicated_access_log
T-2/var/log/httpd/_server-alias_custom_domain-duplicated_backend_log
T-2/var/log/httpd/_server-alias_custom_domain-duplicated_error_log
T-2/var/log/httpd/_server-alias_error_log
T-2/var/log/httpd/_ssl-proxy-verify-unverified_access_log
T-2/var/log/httpd/_ssl-proxy-verify-unverified_backend_log
T-2/var/log/httpd/_ssl-proxy-verify-unverified_error_log
T-2/var/log/httpd/_ssl-proxy-verify_ssl_proxy_ca_crt-unverified_access_log
T-2/var/log/httpd/_ssl-proxy-verify_ssl_proxy_ca_crt-unverified_backend_log
T-2/var/log/httpd/_ssl-proxy-verify_ssl_proxy_ca_crt-unverified_error_log
T-2/var/log/httpd/_ssl-proxy-verify_ssl_proxy_ca_crt_access_log
T-2/var/log/httpd/_ssl-proxy-verify_ssl_proxy_ca_crt_backend_log
T-2/var/log/httpd/_ssl-proxy-verify_ssl_proxy_ca_crt_error_log
T-2/var/log/httpd/_ssl_ca_crt_does_not_match_access_log
T-2/var/log/httpd/_ssl_ca_crt_does_not_match_backend_log
T-2/var/log/httpd/_ssl_ca_crt_does_not_match_error_log
T-2/var/log/httpd/_ssl_ca_crt_garbage_access_log
T-2/var/log/httpd/_ssl_ca_crt_garbage_backend_log
T-2/var/log/httpd/_ssl_ca_crt_garbage_error_log
T-2/var/log/httpd/_ssl_ca_crt_only_access_log
T-2/var/log/httpd/_ssl_ca_crt_only_backend_log
T-2/var/log/httpd/_ssl_ca_crt_only_error_log
T-2/var/log/httpd/_type-notebook_access_log
T-2/var/log/httpd/_type-notebook_backend_log
T-2/var/log/httpd/_type-notebook_error_log
T-2/var/log/httpd/_type-redirect-custom_domain_access_log
T-2/var/log/httpd/_type-redirect-custom_domain_error_log
T-2/var/log/httpd/_type-redirect_access_log
T-2/var/log/httpd/_type-redirect_error_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_access_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_backend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_error_log
T-2/var/log/httpd/_type-websocket-websocket-path-list_access_log
T-2/var/log/httpd/_type-websocket-websocket-path-list_backend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list_error_log
T-2/var/log/httpd/_type-websocket-websocket-transparent-false_access_log
T-2/var/log/httpd/_type-websocket-websocket-transparent-false_backend_log
T-2/var/log/httpd/_type-websocket-websocket-transparent-false_error_log
T-2/var/log/httpd/_type-websocket_access_log
T-2/var/log/httpd/_type-websocket_backend_log
T-2/var/log/httpd/_type-websocket_error_log
T-2/var/log/httpd/_type-zope-default-path_access_log
T-2/var/log/httpd/_type-zope-default-path_backend_log
T-2/var/log/httpd/_type-zope-default-path_error_log
T-2/var/log/httpd/_type-zope-path_access_log
T-2/var/log/httpd/_type-zope-path_backend_log
T-2/var/log/httpd/_type-zope-path_error_log
T-2/var/log/httpd/_type-zope-prefer-gzip-encoding-to-backend-https-only_access_log
T-2/var/log/httpd/_type-zope-prefer-gzip-encoding-to-backend-https-only_backend_log
T-2/var/log/httpd/_type-zope-prefer-gzip-encoding-to-backend-https-only_error_log
T-2/var/log/httpd/_type-zope-prefer-gzip-encoding-to-backend_access_log
T-2/var/log/httpd/_type-zope-prefer-gzip-encoding-to-backend_backend_log
T-2/var/log/httpd/_type-zope-prefer-gzip-encoding-to-backend_error_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify-unverified_access_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify-unverified_backend_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify-unverified_error_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify_ssl_proxy_ca_crt-unverified_access_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify_ssl_proxy_ca_crt-unverified_backend_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify_ssl_proxy_ca_crt-unverified_error_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify_ssl_proxy_ca_crt_access_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify_ssl_proxy_ca_crt_backend_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify_ssl_proxy_ca_crt_error_log
T-2/var/log/httpd/_type-zope-virtualhostroot-http-port_access_log
T-2/var/log/httpd/_type-zope-virtualhostroot-http-port_backend_log
T-2/var/log/httpd/_type-zope-virtualhostroot-http-port_error_log
T-2/var/log/httpd/_type-zope-virtualhostroot-https-port_access_log
T-2/var/log/httpd/_type-zope-virtualhostroot-https-port_backend_log
T-2/var/log/httpd/_type-zope-virtualhostroot-https-port_error_log
T-2/var/log/httpd/_type-zope_access_log
T-2/var/log/httpd/_type-zope_backend_log
T-2/var/log/httpd/_type-zope_error_log
T-2/var/log/httpd/_url_https-url_access_log
T-2/var/log/httpd/_url_https-url_backend_log
T-2/var/log/httpd/_url_https-url_error_log
T-2/var/log/monitor-httpd-access.log
T-2/var/log/monitor-httpd-error.log
T-2/var/log/trafficserver/manager.log
T-2/var/log/trafficserver/traffic.out
test.TestSlave.test_file_list_plugin-CADDY.txt 0000664 0000000 0000000 00000003411 13723117434 0045211 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/plugin/__init__.py
T-0/etc/plugin/aibcc-user-caucase-updater.py
T-0/etc/plugin/aikc-user-caucase-updater.py
T-0/etc/plugin/buildout-T-0-status.py
T-0/etc/plugin/caucased-backend-client.py
T-0/etc/plugin/check-free-disk-space.py
T-0/etc/plugin/monitor-bootstrap-status.py
T-0/etc/plugin/monitor-http-frontend.py
T-0/etc/plugin/monitor-httpd-listening-on-tcp.py
T-0/etc/plugin/rejected-slave-publish-ip-port-listening.py
T-0/etc/plugin/rejected-slave.py
T-1/etc/plugin/__init__.py
T-1/etc/plugin/buildout-T-1-status.py
T-1/etc/plugin/caucased.py
T-1/etc/plugin/check-free-disk-space.py
T-1/etc/plugin/expose-csr_id-ip-port-listening.py
T-1/etc/plugin/kedifa-http-reply.py
T-1/etc/plugin/monitor-bootstrap-status.py
T-1/etc/plugin/monitor-http-frontend.py
T-1/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/__init__.py
T-2/etc/plugin/backend-client-caucase-updater.py
T-2/etc/plugin/backend-haproxy-configuration.py
T-2/etc/plugin/backend_haproxy_http.py
T-2/etc/plugin/backend_haproxy_https.py
T-2/etc/plugin/buildout-T-2-status.py
T-2/etc/plugin/caddy_frontend_ipv4_http.py
T-2/etc/plugin/caddy_frontend_ipv4_https.py
T-2/etc/plugin/caddy_frontend_ipv6_http.py
T-2/etc/plugin/caddy_frontend_ipv6_https.py
T-2/etc/plugin/caucase-updater.py
T-2/etc/plugin/check-_monitor-ipv4-test-ipv4-packet-list-test.py
T-2/etc/plugin/check-_monitor-ipv6-test-ipv6-packet-list-test.py
T-2/etc/plugin/check-free-disk-space.py
T-2/etc/plugin/expose-csr_id-ip-port-listening.py
T-2/etc/plugin/frontend-caddy-configuration-promise.py
T-2/etc/plugin/monitor-bootstrap-status.py
T-2/etc/plugin/monitor-http-frontend.py
T-2/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/re6st-connectivity.py
T-2/etc/plugin/trafficserver-cache-availability.py
T-2/etc/plugin/trafficserver-port-listening.py
test.TestSlave.test_file_list_run-CADDY.txt 0000664 0000000 0000000 00000000621 13723117434 0044517 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/run/monitor-httpd.pid
T-1/var/run/kedifa.pid
T-1/var/run/monitor-httpd.pid
T-2/var/run/backend-haproxy-rsyslogd.pid
T-2/var/run/backend-haproxy.pid
T-2/var/run/backend_haproxy_configuration_last_state
T-2/var/run/backend_haproxy_graceful_configuration_state_signature
T-2/var/run/bhlog.sck
T-2/var/run/graceful_configuration_state_signature
T-2/var/run/httpd.pid
T-2/var/run/monitor-httpd.pid
test.TestSlave.test_master_partition_state-CADDY.txt 0000664 0000000 0000000 00000001302 13723117434 0046442 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data SetEnvIf Origin "^http(s)?://(.+\.)?(monitor\.app\.officejs\.com)$" ORIGIN_DOMAIN=$0
Header always set Access-Control-Allow-Origin "%{ORIGIN_DOMAIN}e" env=ORIGIN_DOMAIN
Header always set Access-Control-Allow-Credentials "true" env=ORIGIN_DOMAIN
Header always set Access-Control-Allow-Methods "PROPFIND, PROPPATCH, COPY, MOVE, DELETE, MKCOL, LOCK, UNLOCK, PUT, GETLIB, VERSION-CONTROL, CHECKIN, CHECKOUT, UNCHECKOUT, REPORT, UPDATE, CANCELUPLOAD, HEAD, OPTIONS, GET, POST" env=ORIGIN_DOMAIN
Header always set Access-Control-Allow-Headers "Overwrite, Destination, Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Authorization" env=ORIGIN_DOMAIN
test.TestSlave.test_supervisor_state-CADDY.txt 0000664 0000000 0000000 00000003304 13723117434 0045303 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0:aibcc-user-caucase-updater-on-watch RUNNING
T-0:aikc-user-caucase-updater-on-watch RUNNING
T-0:bootstrap-monitor EXITED
T-0:caucased-backend-client-{hash-generic}-on-watch RUNNING
T-0:certificate_authority-{hash-generic}-on-watch RUNNING
T-0:crond-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-graceful EXITED
T-0:rejected-slave-publish-{hash-rejected-slave-publish}-on-watch RUNNING
T-1:bootstrap-monitor EXITED
T-1:caucase-updater-on-watch RUNNING
T-1:caucased-{hash-generic}-on-watch RUNNING
T-1:certificate_authority-{hash-generic}-on-watch RUNNING
T-1:crond-{hash-generic}-on-watch RUNNING
T-1:expose-csr_id-{hash-generic}-on-watch RUNNING
T-1:kedifa-{hash-generic}-on-watch RUNNING
T-1:kedifa-reloader EXITED
T-1:monitor-httpd-{hash-generic}-on-watch RUNNING
T-1:monitor-httpd-graceful EXITED
T-2:6tunnel-11080-{hash-generic}-on-watch RUNNING
T-2:6tunnel-11443-{hash-generic}-on-watch RUNNING
T-2:backend-client-login-certificate-caucase-updater-on-watch RUNNING
T-2:backend-haproxy-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-rsyslogd-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-safe-graceful EXITED
T-2:bootstrap-monitor EXITED
T-2:certificate_authority-{hash-generic}-on-watch RUNNING
T-2:crond-{hash-generic}-on-watch RUNNING
T-2:expose-csr_id-{hash-generic}-on-watch RUNNING
T-2:frontend-caddy-safe-graceful EXITED
T-2:frontend_caddy-{hash-caddy-T-2}-on-watch RUNNING
T-2:kedifa-login-certificate-caucase-updater-on-watch RUNNING
T-2:kedifa-updater-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-graceful EXITED
T-2:trafficserver-{hash-generic}-on-watch RUNNING
T-2:trafficserver-reload EXITED
test.TestSlaveCiphers.test_file_list_etc_cron_d-CADDY.txt 0000664 0000000 0000000 00000000644 13723117434 0047335 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/cron.d/logrotate
T-0/etc/cron.d/monitor-configurator
T-0/etc/cron.d/monitor-globalstate
T-0/etc/cron.d/monitor_collect
T-1/etc/cron.d/logrotate
T-1/etc/cron.d/monitor-configurator
T-1/etc/cron.d/monitor-globalstate
T-1/etc/cron.d/monitor_collect
T-2/etc/cron.d/logrotate
T-2/etc/cron.d/monitor-configurator
T-2/etc/cron.d/monitor-globalstate
T-2/etc/cron.d/monitor_collect
T-2/etc/cron.d/trafficserver-logrotate
test.TestSlaveCiphers.test_file_list_log-CADDY.txt 0000664 0000000 0000000 00000001421 13723117434 0046011 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/log/monitor-httpd-access.log
T-0/var/log/monitor-httpd-error.log
T-0/var/log/slapgrid-T-0-error.log
T-1/var/log/expose-csr_id.log
T-1/var/log/kedifa.log
T-1/var/log/monitor-httpd-access.log
T-1/var/log/monitor-httpd-error.log
T-2/var/log/backend-haproxy.log
T-2/var/log/frontend-access.log
T-2/var/log/frontend-error.log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/httpd/_default_ciphers_access_log
T-2/var/log/httpd/_default_ciphers_backend_log
T-2/var/log/httpd/_default_ciphers_error_log
T-2/var/log/httpd/_own_ciphers_access_log
T-2/var/log/httpd/_own_ciphers_backend_log
T-2/var/log/httpd/_own_ciphers_error_log
T-2/var/log/monitor-httpd-access.log
T-2/var/log/monitor-httpd-error.log
T-2/var/log/trafficserver/manager.log
T-2/var/log/trafficserver/traffic.out
test.TestSlaveCiphers.test_file_list_plugin-CADDY.txt 0000664 0000000 0000000 00000003207 13723117434 0046532 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/plugin/__init__.py
T-0/etc/plugin/aibcc-user-caucase-updater.py
T-0/etc/plugin/aikc-user-caucase-updater.py
T-0/etc/plugin/buildout-T-0-status.py
T-0/etc/plugin/caucased-backend-client.py
T-0/etc/plugin/check-free-disk-space.py
T-0/etc/plugin/monitor-bootstrap-status.py
T-0/etc/plugin/monitor-http-frontend.py
T-0/etc/plugin/monitor-httpd-listening-on-tcp.py
T-0/etc/plugin/rejected-slave-publish-ip-port-listening.py
T-0/etc/plugin/rejected-slave.py
T-1/etc/plugin/__init__.py
T-1/etc/plugin/buildout-T-1-status.py
T-1/etc/plugin/caucased.py
T-1/etc/plugin/check-free-disk-space.py
T-1/etc/plugin/expose-csr_id-ip-port-listening.py
T-1/etc/plugin/kedifa-http-reply.py
T-1/etc/plugin/monitor-bootstrap-status.py
T-1/etc/plugin/monitor-http-frontend.py
T-1/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/__init__.py
T-2/etc/plugin/backend-client-caucase-updater.py
T-2/etc/plugin/backend-haproxy-configuration.py
T-2/etc/plugin/backend_haproxy_http.py
T-2/etc/plugin/backend_haproxy_https.py
T-2/etc/plugin/buildout-T-2-status.py
T-2/etc/plugin/caddy_frontend_ipv4_http.py
T-2/etc/plugin/caddy_frontend_ipv4_https.py
T-2/etc/plugin/caddy_frontend_ipv6_http.py
T-2/etc/plugin/caddy_frontend_ipv6_https.py
T-2/etc/plugin/caucase-updater.py
T-2/etc/plugin/check-free-disk-space.py
T-2/etc/plugin/expose-csr_id-ip-port-listening.py
T-2/etc/plugin/frontend-caddy-configuration-promise.py
T-2/etc/plugin/monitor-bootstrap-status.py
T-2/etc/plugin/monitor-http-frontend.py
T-2/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/re6st-connectivity.py
T-2/etc/plugin/trafficserver-cache-availability.py
T-2/etc/plugin/trafficserver-port-listening.py
test.TestSlaveCiphers.test_file_list_run-CADDY.txt 0000664 0000000 0000000 00000000621 13723117434 0046035 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/run/monitor-httpd.pid
T-1/var/run/kedifa.pid
T-1/var/run/monitor-httpd.pid
T-2/var/run/backend-haproxy-rsyslogd.pid
T-2/var/run/backend-haproxy.pid
T-2/var/run/backend_haproxy_configuration_last_state
T-2/var/run/backend_haproxy_graceful_configuration_state_signature
T-2/var/run/bhlog.sck
T-2/var/run/graceful_configuration_state_signature
T-2/var/run/httpd.pid
T-2/var/run/monitor-httpd.pid
test.TestSlaveCiphers.test_supervisor_state-CADDY.txt 0000664 0000000 0000000 00000003304 13723117434 0046621 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0:aibcc-user-caucase-updater-on-watch RUNNING
T-0:aikc-user-caucase-updater-on-watch RUNNING
T-0:bootstrap-monitor EXITED
T-0:caucased-backend-client-{hash-generic}-on-watch RUNNING
T-0:certificate_authority-{hash-generic}-on-watch RUNNING
T-0:crond-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-graceful EXITED
T-0:rejected-slave-publish-{hash-rejected-slave-publish}-on-watch RUNNING
T-1:bootstrap-monitor EXITED
T-1:caucase-updater-on-watch RUNNING
T-1:caucased-{hash-generic}-on-watch RUNNING
T-1:certificate_authority-{hash-generic}-on-watch RUNNING
T-1:crond-{hash-generic}-on-watch RUNNING
T-1:expose-csr_id-{hash-generic}-on-watch RUNNING
T-1:kedifa-{hash-generic}-on-watch RUNNING
T-1:kedifa-reloader EXITED
T-1:monitor-httpd-{hash-generic}-on-watch RUNNING
T-1:monitor-httpd-graceful EXITED
T-2:6tunnel-11080-{hash-generic}-on-watch RUNNING
T-2:6tunnel-11443-{hash-generic}-on-watch RUNNING
T-2:backend-client-login-certificate-caucase-updater-on-watch RUNNING
T-2:backend-haproxy-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-rsyslogd-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-safe-graceful EXITED
T-2:bootstrap-monitor EXITED
T-2:certificate_authority-{hash-generic}-on-watch RUNNING
T-2:crond-{hash-generic}-on-watch RUNNING
T-2:expose-csr_id-{hash-generic}-on-watch RUNNING
T-2:frontend-caddy-safe-graceful EXITED
T-2:frontend_caddy-{hash-caddy-T-2}-on-watch RUNNING
T-2:kedifa-login-certificate-caucase-updater-on-watch RUNNING
T-2:kedifa-updater-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-graceful EXITED
T-2:trafficserver-{hash-generic}-on-watch RUNNING
T-2:trafficserver-reload EXITED
test.TestSlaveGlobalDisableHttp2.test_file_list_etc_cron_d-CADDY.txt 0000664 0000000 0000000 00000000644 13723117434 0051346 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/cron.d/logrotate
T-0/etc/cron.d/monitor-configurator
T-0/etc/cron.d/monitor-globalstate
T-0/etc/cron.d/monitor_collect
T-1/etc/cron.d/logrotate
T-1/etc/cron.d/monitor-configurator
T-1/etc/cron.d/monitor-globalstate
T-1/etc/cron.d/monitor_collect
T-2/etc/cron.d/logrotate
T-2/etc/cron.d/monitor-configurator
T-2/etc/cron.d/monitor-globalstate
T-2/etc/cron.d/monitor_collect
T-2/etc/cron.d/trafficserver-logrotate
test.TestSlaveGlobalDisableHttp2.test_file_list_log-CADDY.txt 0000664 0000000 0000000 00000023626 13723117434 0050035 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/log/monitor-httpd-access.log
T-0/var/log/monitor-httpd-error.log
T-0/var/log/slapgrid-T-0-error.log
T-1/var/log/expose-csr_id.log
T-1/var/log/kedifa.log
T-1/var/log/monitor-httpd-access.log
T-1/var/log/monitor-httpd-error.log
T-2/var/log/backend-haproxy.log
T-2/var/log/frontend-access.log
T-2/var/log/frontend-error.log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/httpd/_Url_access_log
T-2/var/log/httpd/_Url_backend_log
T-2/var/log/httpd/_Url_error_log
T-2/var/log/httpd/_auth-to-backend-backend-ignore_access_log
T-2/var/log/httpd/_auth-to-backend-backend-ignore_backend_log
T-2/var/log/httpd/_auth-to-backend-backend-ignore_error_log
T-2/var/log/httpd/_auth-to-backend-not-configured_access_log
T-2/var/log/httpd/_auth-to-backend-not-configured_backend_log
T-2/var/log/httpd/_auth-to-backend-not-configured_error_log
T-2/var/log/httpd/_auth-to-backend_access_log
T-2/var/log/httpd/_auth-to-backend_backend_log
T-2/var/log/httpd/_auth-to-backend_error_log
T-2/var/log/httpd/_ciphers_access_log
T-2/var/log/httpd/_ciphers_backend_log
T-2/var/log/httpd/_ciphers_error_log
T-2/var/log/httpd/_custom_domain_access_log
T-2/var/log/httpd/_custom_domain_backend_log
T-2/var/log/httpd/_custom_domain_error_log
T-2/var/log/httpd/_custom_domain_server_alias_access_log
T-2/var/log/httpd/_custom_domain_server_alias_backend_log
T-2/var/log/httpd/_custom_domain_server_alias_error_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_access_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_backend_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_error_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_ssl_ca_crt_access_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_ssl_ca_crt_backend_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_ssl_ca_crt_error_log
T-2/var/log/httpd/_custom_domain_wildcard_access_log
T-2/var/log/httpd/_custom_domain_wildcard_backend_log
T-2/var/log/httpd/_custom_domain_wildcard_error_log
T-2/var/log/httpd/_disabled-cookie-list_access_log
T-2/var/log/httpd/_disabled-cookie-list_backend_log
T-2/var/log/httpd/_disabled-cookie-list_error_log
T-2/var/log/httpd/_empty_access_log
T-2/var/log/httpd/_empty_backend_log
T-2/var/log/httpd/_empty_error_log
T-2/var/log/httpd/_enable-http2-default_access_log
T-2/var/log/httpd/_enable-http2-default_backend_log
T-2/var/log/httpd/_enable-http2-default_error_log
T-2/var/log/httpd/_enable-http2-false_access_log
T-2/var/log/httpd/_enable-http2-false_backend_log
T-2/var/log/httpd/_enable-http2-false_error_log
T-2/var/log/httpd/_enable_cache-disable-no-cache-request_access_log
T-2/var/log/httpd/_enable_cache-disable-no-cache-request_backend_log
T-2/var/log/httpd/_enable_cache-disable-no-cache-request_error_log
T-2/var/log/httpd/_enable_cache-disable-via-header_access_log
T-2/var/log/httpd/_enable_cache-disable-via-header_backend_log
T-2/var/log/httpd/_enable_cache-disable-via-header_error_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify-unverified_access_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify-unverified_backend_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify-unverified_error_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt-unverified_access_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt-unverified_backend_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt-unverified_error_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt_access_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt_backend_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt_error_log
T-2/var/log/httpd/_enable_cache_access_log
T-2/var/log/httpd/_enable_cache_backend_log
T-2/var/log/httpd/_enable_cache_custom_domain_access_log
T-2/var/log/httpd/_enable_cache_custom_domain_backend_log
T-2/var/log/httpd/_enable_cache_custom_domain_error_log
T-2/var/log/httpd/_enable_cache_error_log
T-2/var/log/httpd/_enable_cache_server_alias_access_log
T-2/var/log/httpd/_enable_cache_server_alias_backend_log
T-2/var/log/httpd/_enable_cache_server_alias_error_log
T-2/var/log/httpd/_https-only_access_log
T-2/var/log/httpd/_https-only_backend_log
T-2/var/log/httpd/_https-only_error_log
T-2/var/log/httpd/_monitor-ipv4-test_access_log
T-2/var/log/httpd/_monitor-ipv4-test_backend_log
T-2/var/log/httpd/_monitor-ipv4-test_error_log
T-2/var/log/httpd/_monitor-ipv6-test_access_log
T-2/var/log/httpd/_monitor-ipv6-test_backend_log
T-2/var/log/httpd/_monitor-ipv6-test_error_log
T-2/var/log/httpd/_prefer-gzip-encoding-to-backend-https-only_access_log
T-2/var/log/httpd/_prefer-gzip-encoding-to-backend-https-only_backend_log
T-2/var/log/httpd/_prefer-gzip-encoding-to-backend-https-only_error_log
T-2/var/log/httpd/_prefer-gzip-encoding-to-backend_access_log
T-2/var/log/httpd/_prefer-gzip-encoding-to-backend_backend_log
T-2/var/log/httpd/_prefer-gzip-encoding-to-backend_error_log
T-2/var/log/httpd/_server-alias-duplicated_access_log
T-2/var/log/httpd/_server-alias-duplicated_backend_log
T-2/var/log/httpd/_server-alias-duplicated_error_log
T-2/var/log/httpd/_server-alias-empty_access_log
T-2/var/log/httpd/_server-alias-empty_backend_log
T-2/var/log/httpd/_server-alias-empty_error_log
T-2/var/log/httpd/_server-alias-wildcard_access_log
T-2/var/log/httpd/_server-alias-wildcard_backend_log
T-2/var/log/httpd/_server-alias-wildcard_error_log
T-2/var/log/httpd/_server-alias_access_log
T-2/var/log/httpd/_server-alias_backend_log
T-2/var/log/httpd/_server-alias_custom_domain-duplicated_access_log
T-2/var/log/httpd/_server-alias_custom_domain-duplicated_backend_log
T-2/var/log/httpd/_server-alias_custom_domain-duplicated_error_log
T-2/var/log/httpd/_server-alias_error_log
T-2/var/log/httpd/_ssl-proxy-verify-unverified_access_log
T-2/var/log/httpd/_ssl-proxy-verify-unverified_backend_log
T-2/var/log/httpd/_ssl-proxy-verify-unverified_error_log
T-2/var/log/httpd/_ssl-proxy-verify_ssl_proxy_ca_crt-unverified_access_log
T-2/var/log/httpd/_ssl-proxy-verify_ssl_proxy_ca_crt-unverified_backend_log
T-2/var/log/httpd/_ssl-proxy-verify_ssl_proxy_ca_crt-unverified_error_log
T-2/var/log/httpd/_ssl-proxy-verify_ssl_proxy_ca_crt_access_log
T-2/var/log/httpd/_ssl-proxy-verify_ssl_proxy_ca_crt_backend_log
T-2/var/log/httpd/_ssl-proxy-verify_ssl_proxy_ca_crt_error_log
T-2/var/log/httpd/_ssl_ca_crt_does_not_match_access_log
T-2/var/log/httpd/_ssl_ca_crt_does_not_match_backend_log
T-2/var/log/httpd/_ssl_ca_crt_does_not_match_error_log
T-2/var/log/httpd/_ssl_ca_crt_garbage_access_log
T-2/var/log/httpd/_ssl_ca_crt_garbage_backend_log
T-2/var/log/httpd/_ssl_ca_crt_garbage_error_log
T-2/var/log/httpd/_ssl_ca_crt_only_access_log
T-2/var/log/httpd/_ssl_ca_crt_only_backend_log
T-2/var/log/httpd/_ssl_ca_crt_only_error_log
T-2/var/log/httpd/_type-notebook_access_log
T-2/var/log/httpd/_type-notebook_backend_log
T-2/var/log/httpd/_type-notebook_error_log
T-2/var/log/httpd/_type-redirect-custom_domain_access_log
T-2/var/log/httpd/_type-redirect-custom_domain_error_log
T-2/var/log/httpd/_type-redirect_access_log
T-2/var/log/httpd/_type-redirect_error_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_access_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_backend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_error_log
T-2/var/log/httpd/_type-websocket-websocket-path-list_access_log
T-2/var/log/httpd/_type-websocket-websocket-path-list_backend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list_error_log
T-2/var/log/httpd/_type-websocket-websocket-transparent-false_access_log
T-2/var/log/httpd/_type-websocket-websocket-transparent-false_backend_log
T-2/var/log/httpd/_type-websocket-websocket-transparent-false_error_log
T-2/var/log/httpd/_type-websocket_access_log
T-2/var/log/httpd/_type-websocket_backend_log
T-2/var/log/httpd/_type-websocket_error_log
T-2/var/log/httpd/_type-zope-default-path_access_log
T-2/var/log/httpd/_type-zope-default-path_backend_log
T-2/var/log/httpd/_type-zope-default-path_error_log
T-2/var/log/httpd/_type-zope-path_access_log
T-2/var/log/httpd/_type-zope-path_backend_log
T-2/var/log/httpd/_type-zope-path_error_log
T-2/var/log/httpd/_type-zope-prefer-gzip-encoding-to-backend-https-only_access_log
T-2/var/log/httpd/_type-zope-prefer-gzip-encoding-to-backend-https-only_backend_log
T-2/var/log/httpd/_type-zope-prefer-gzip-encoding-to-backend-https-only_error_log
T-2/var/log/httpd/_type-zope-prefer-gzip-encoding-to-backend_access_log
T-2/var/log/httpd/_type-zope-prefer-gzip-encoding-to-backend_backend_log
T-2/var/log/httpd/_type-zope-prefer-gzip-encoding-to-backend_error_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify-unverified_access_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify-unverified_backend_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify-unverified_error_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify_ssl_proxy_ca_crt-unverified_access_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify_ssl_proxy_ca_crt-unverified_backend_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify_ssl_proxy_ca_crt-unverified_error_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify_ssl_proxy_ca_crt_access_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify_ssl_proxy_ca_crt_backend_log
T-2/var/log/httpd/_type-zope-ssl-proxy-verify_ssl_proxy_ca_crt_error_log
T-2/var/log/httpd/_type-zope-virtualhostroot-http-port_access_log
T-2/var/log/httpd/_type-zope-virtualhostroot-http-port_backend_log
T-2/var/log/httpd/_type-zope-virtualhostroot-http-port_error_log
T-2/var/log/httpd/_type-zope-virtualhostroot-https-port_access_log
T-2/var/log/httpd/_type-zope-virtualhostroot-https-port_backend_log
T-2/var/log/httpd/_type-zope-virtualhostroot-https-port_error_log
T-2/var/log/httpd/_type-zope_access_log
T-2/var/log/httpd/_type-zope_backend_log
T-2/var/log/httpd/_type-zope_error_log
T-2/var/log/httpd/_url_https-url_access_log
T-2/var/log/httpd/_url_https-url_backend_log
T-2/var/log/httpd/_url_https-url_error_log
T-2/var/log/monitor-httpd-access.log
T-2/var/log/monitor-httpd-error.log
T-2/var/log/trafficserver/manager.log
T-2/var/log/trafficserver/traffic.out
test.TestSlaveGlobalDisableHttp2.test_file_list_plugin-CADDY.txt 0000664 0000000 0000000 00000003411 13723117434 0050540 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/plugin/__init__.py
T-0/etc/plugin/aibcc-user-caucase-updater.py
T-0/etc/plugin/aikc-user-caucase-updater.py
T-0/etc/plugin/buildout-T-0-status.py
T-0/etc/plugin/caucased-backend-client.py
T-0/etc/plugin/check-free-disk-space.py
T-0/etc/plugin/monitor-bootstrap-status.py
T-0/etc/plugin/monitor-http-frontend.py
T-0/etc/plugin/monitor-httpd-listening-on-tcp.py
T-0/etc/plugin/rejected-slave-publish-ip-port-listening.py
T-0/etc/plugin/rejected-slave.py
T-1/etc/plugin/__init__.py
T-1/etc/plugin/buildout-T-1-status.py
T-1/etc/plugin/caucased.py
T-1/etc/plugin/check-free-disk-space.py
T-1/etc/plugin/expose-csr_id-ip-port-listening.py
T-1/etc/plugin/kedifa-http-reply.py
T-1/etc/plugin/monitor-bootstrap-status.py
T-1/etc/plugin/monitor-http-frontend.py
T-1/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/__init__.py
T-2/etc/plugin/backend-client-caucase-updater.py
T-2/etc/plugin/backend-haproxy-configuration.py
T-2/etc/plugin/backend_haproxy_http.py
T-2/etc/plugin/backend_haproxy_https.py
T-2/etc/plugin/buildout-T-2-status.py
T-2/etc/plugin/caddy_frontend_ipv4_http.py
T-2/etc/plugin/caddy_frontend_ipv4_https.py
T-2/etc/plugin/caddy_frontend_ipv6_http.py
T-2/etc/plugin/caddy_frontend_ipv6_https.py
T-2/etc/plugin/caucase-updater.py
T-2/etc/plugin/check-_monitor-ipv4-test-ipv4-packet-list-test.py
T-2/etc/plugin/check-_monitor-ipv6-test-ipv6-packet-list-test.py
T-2/etc/plugin/check-free-disk-space.py
T-2/etc/plugin/expose-csr_id-ip-port-listening.py
T-2/etc/plugin/frontend-caddy-configuration-promise.py
T-2/etc/plugin/monitor-bootstrap-status.py
T-2/etc/plugin/monitor-http-frontend.py
T-2/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/re6st-connectivity.py
T-2/etc/plugin/trafficserver-cache-availability.py
T-2/etc/plugin/trafficserver-port-listening.py
test.TestSlaveGlobalDisableHttp2.test_file_list_run-CADDY.txt 0000664 0000000 0000000 00000000621 13723117434 0050046 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/run/monitor-httpd.pid
T-1/var/run/kedifa.pid
T-1/var/run/monitor-httpd.pid
T-2/var/run/backend-haproxy-rsyslogd.pid
T-2/var/run/backend-haproxy.pid
T-2/var/run/backend_haproxy_configuration_last_state
T-2/var/run/backend_haproxy_graceful_configuration_state_signature
T-2/var/run/bhlog.sck
T-2/var/run/graceful_configuration_state_signature
T-2/var/run/httpd.pid
T-2/var/run/monitor-httpd.pid
test.TestSlaveGlobalDisableHttp2.test_master_partition_state-CADDY.txt 0000664 0000000 0000000 00000001302 13723117434 0051771 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data SetEnvIf Origin "^http(s)?://(.+\.)?(monitor\.app\.officejs\.com)$" ORIGIN_DOMAIN=$0
Header always set Access-Control-Allow-Origin "%{ORIGIN_DOMAIN}e" env=ORIGIN_DOMAIN
Header always set Access-Control-Allow-Credentials "true" env=ORIGIN_DOMAIN
Header always set Access-Control-Allow-Methods "PROPFIND, PROPPATCH, COPY, MOVE, DELETE, MKCOL, LOCK, UNLOCK, PUT, GETLIB, VERSION-CONTROL, CHECKIN, CHECKOUT, UNCHECKOUT, REPORT, UPDATE, CANCELUPLOAD, HEAD, OPTIONS, GET, POST" env=ORIGIN_DOMAIN
Header always set Access-Control-Allow-Headers "Overwrite, Destination, Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Authorization" env=ORIGIN_DOMAIN
test.TestSlaveGlobalDisableHttp2.test_supervisor_state-CADDY.txt 0000664 0000000 0000000 00000003304 13723117434 0050632 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0:aibcc-user-caucase-updater-on-watch RUNNING
T-0:aikc-user-caucase-updater-on-watch RUNNING
T-0:bootstrap-monitor EXITED
T-0:caucased-backend-client-{hash-generic}-on-watch RUNNING
T-0:certificate_authority-{hash-generic}-on-watch RUNNING
T-0:crond-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-graceful EXITED
T-0:rejected-slave-publish-{hash-rejected-slave-publish}-on-watch RUNNING
T-1:bootstrap-monitor EXITED
T-1:caucase-updater-on-watch RUNNING
T-1:caucased-{hash-generic}-on-watch RUNNING
T-1:certificate_authority-{hash-generic}-on-watch RUNNING
T-1:crond-{hash-generic}-on-watch RUNNING
T-1:expose-csr_id-{hash-generic}-on-watch RUNNING
T-1:kedifa-{hash-generic}-on-watch RUNNING
T-1:kedifa-reloader EXITED
T-1:monitor-httpd-{hash-generic}-on-watch RUNNING
T-1:monitor-httpd-graceful EXITED
T-2:6tunnel-11080-{hash-generic}-on-watch RUNNING
T-2:6tunnel-11443-{hash-generic}-on-watch RUNNING
T-2:backend-client-login-certificate-caucase-updater-on-watch RUNNING
T-2:backend-haproxy-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-rsyslogd-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-safe-graceful EXITED
T-2:bootstrap-monitor EXITED
T-2:certificate_authority-{hash-generic}-on-watch RUNNING
T-2:crond-{hash-generic}-on-watch RUNNING
T-2:expose-csr_id-{hash-generic}-on-watch RUNNING
T-2:frontend-caddy-safe-graceful EXITED
T-2:frontend_caddy-{hash-caddy-T-2}-on-watch RUNNING
T-2:kedifa-login-certificate-caucase-updater-on-watch RUNNING
T-2:kedifa-updater-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-graceful EXITED
T-2:trafficserver-{hash-generic}-on-watch RUNNING
T-2:trafficserver-reload EXITED
test.TestSlaveSlapOSMasterCertificateCompatibility.test_file_list_etc_cron_d-CADDY.txt 0000664 0000000 0000000 00000000644 13723117434 0055152 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/cron.d/logrotate
T-0/etc/cron.d/monitor-configurator
T-0/etc/cron.d/monitor-globalstate
T-0/etc/cron.d/monitor_collect
T-1/etc/cron.d/logrotate
T-1/etc/cron.d/monitor-configurator
T-1/etc/cron.d/monitor-globalstate
T-1/etc/cron.d/monitor_collect
T-2/etc/cron.d/logrotate
T-2/etc/cron.d/monitor-configurator
T-2/etc/cron.d/monitor-globalstate
T-2/etc/cron.d/monitor_collect
T-2/etc/cron.d/trafficserver-logrotate
test.TestSlaveSlapOSMasterCertificateCompatibility.test_file_list_log-CADDY.txt 0000664 0000000 0000000 00000005205 13723117434 0053632 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/log/monitor-httpd-access.log
T-0/var/log/monitor-httpd-error.log
T-0/var/log/slapgrid-T-0-error.log
T-1/var/log/expose-csr_id.log
T-1/var/log/kedifa.log
T-1/var/log/monitor-httpd-access.log
T-1/var/log/monitor-httpd-error.log
T-2/var/log/backend-haproxy.log
T-2/var/log/frontend-access.log
T-2/var/log/frontend-error.log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_access_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_backend_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_error_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_ssl_ca_crt_access_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_ssl_ca_crt_backend_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_ssl_ca_crt_error_log
T-2/var/log/httpd/_ssl_ca_crt_does_not_match_access_log
T-2/var/log/httpd/_ssl_ca_crt_does_not_match_backend_log
T-2/var/log/httpd/_ssl_ca_crt_does_not_match_error_log
T-2/var/log/httpd/_ssl_ca_crt_garbage_access_log
T-2/var/log/httpd/_ssl_ca_crt_garbage_backend_log
T-2/var/log/httpd/_ssl_ca_crt_garbage_error_log
T-2/var/log/httpd/_ssl_from_master_access_log
T-2/var/log/httpd/_ssl_from_master_backend_log
T-2/var/log/httpd/_ssl_from_master_error_log
T-2/var/log/httpd/_ssl_from_master_kedifa_overrides_access_log
T-2/var/log/httpd/_ssl_from_master_kedifa_overrides_backend_log
T-2/var/log/httpd/_ssl_from_master_kedifa_overrides_error_log
T-2/var/log/httpd/_ssl_from_slave_access_log
T-2/var/log/httpd/_ssl_from_slave_backend_log
T-2/var/log/httpd/_ssl_from_slave_error_log
T-2/var/log/httpd/_ssl_from_slave_kedifa_overrides_access_log
T-2/var/log/httpd/_ssl_from_slave_kedifa_overrides_backend_log
T-2/var/log/httpd/_ssl_from_slave_kedifa_overrides_error_log
T-2/var/log/httpd/_type-notebook-ssl_from_master_access_log
T-2/var/log/httpd/_type-notebook-ssl_from_master_backend_log
T-2/var/log/httpd/_type-notebook-ssl_from_master_error_log
T-2/var/log/httpd/_type-notebook-ssl_from_master_kedifa_overrides_access_log
T-2/var/log/httpd/_type-notebook-ssl_from_master_kedifa_overrides_backend_log
T-2/var/log/httpd/_type-notebook-ssl_from_master_kedifa_overrides_error_log
T-2/var/log/httpd/_type-notebook-ssl_from_slave_access_log
T-2/var/log/httpd/_type-notebook-ssl_from_slave_backend_log
T-2/var/log/httpd/_type-notebook-ssl_from_slave_error_log
T-2/var/log/httpd/_type-notebook-ssl_from_slave_kedifa_overrides_access_log
T-2/var/log/httpd/_type-notebook-ssl_from_slave_kedifa_overrides_backend_log
T-2/var/log/httpd/_type-notebook-ssl_from_slave_kedifa_overrides_error_log
T-2/var/log/monitor-httpd-access.log
T-2/var/log/monitor-httpd-error.log
T-2/var/log/trafficserver/manager.log
T-2/var/log/trafficserver/traffic.out
test.TestSlaveSlapOSMasterCertificateCompatibility.test_file_list_plugin-CADDY.txt 0000664 0000000 0000000 00000003207 13723117434 0054347 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/plugin/__init__.py
T-0/etc/plugin/aibcc-user-caucase-updater.py
T-0/etc/plugin/aikc-user-caucase-updater.py
T-0/etc/plugin/buildout-T-0-status.py
T-0/etc/plugin/caucased-backend-client.py
T-0/etc/plugin/check-free-disk-space.py
T-0/etc/plugin/monitor-bootstrap-status.py
T-0/etc/plugin/monitor-http-frontend.py
T-0/etc/plugin/monitor-httpd-listening-on-tcp.py
T-0/etc/plugin/rejected-slave-publish-ip-port-listening.py
T-0/etc/plugin/rejected-slave.py
T-1/etc/plugin/__init__.py
T-1/etc/plugin/buildout-T-1-status.py
T-1/etc/plugin/caucased.py
T-1/etc/plugin/check-free-disk-space.py
T-1/etc/plugin/expose-csr_id-ip-port-listening.py
T-1/etc/plugin/kedifa-http-reply.py
T-1/etc/plugin/monitor-bootstrap-status.py
T-1/etc/plugin/monitor-http-frontend.py
T-1/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/__init__.py
T-2/etc/plugin/backend-client-caucase-updater.py
T-2/etc/plugin/backend-haproxy-configuration.py
T-2/etc/plugin/backend_haproxy_http.py
T-2/etc/plugin/backend_haproxy_https.py
T-2/etc/plugin/buildout-T-2-status.py
T-2/etc/plugin/caddy_frontend_ipv4_http.py
T-2/etc/plugin/caddy_frontend_ipv4_https.py
T-2/etc/plugin/caddy_frontend_ipv6_http.py
T-2/etc/plugin/caddy_frontend_ipv6_https.py
T-2/etc/plugin/caucase-updater.py
T-2/etc/plugin/check-free-disk-space.py
T-2/etc/plugin/expose-csr_id-ip-port-listening.py
T-2/etc/plugin/frontend-caddy-configuration-promise.py
T-2/etc/plugin/monitor-bootstrap-status.py
T-2/etc/plugin/monitor-http-frontend.py
T-2/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/re6st-connectivity.py
T-2/etc/plugin/trafficserver-cache-availability.py
T-2/etc/plugin/trafficserver-port-listening.py
test.TestSlaveSlapOSMasterCertificateCompatibility.test_file_list_run-CADDY.txt 0000664 0000000 0000000 00000000621 13723117434 0053652 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/run/monitor-httpd.pid
T-1/var/run/kedifa.pid
T-1/var/run/monitor-httpd.pid
T-2/var/run/backend-haproxy-rsyslogd.pid
T-2/var/run/backend-haproxy.pid
T-2/var/run/backend_haproxy_configuration_last_state
T-2/var/run/backend_haproxy_graceful_configuration_state_signature
T-2/var/run/bhlog.sck
T-2/var/run/graceful_configuration_state_signature
T-2/var/run/httpd.pid
T-2/var/run/monitor-httpd.pid
test.TestSlaveSlapOSMasterCertificateCompatibility.test_supervisor_state-CADDY.txt 0000664 0000000 0000000 00000003304 13723117434 0054436 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0:aibcc-user-caucase-updater-on-watch RUNNING
T-0:aikc-user-caucase-updater-on-watch RUNNING
T-0:bootstrap-monitor EXITED
T-0:caucased-backend-client-{hash-generic}-on-watch RUNNING
T-0:certificate_authority-{hash-generic}-on-watch RUNNING
T-0:crond-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-graceful EXITED
T-0:rejected-slave-publish-{hash-rejected-slave-publish}-on-watch RUNNING
T-1:bootstrap-monitor EXITED
T-1:caucase-updater-on-watch RUNNING
T-1:caucased-{hash-generic}-on-watch RUNNING
T-1:certificate_authority-{hash-generic}-on-watch RUNNING
T-1:crond-{hash-generic}-on-watch RUNNING
T-1:expose-csr_id-{hash-generic}-on-watch RUNNING
T-1:kedifa-{hash-generic}-on-watch RUNNING
T-1:kedifa-reloader EXITED
T-1:monitor-httpd-{hash-generic}-on-watch RUNNING
T-1:monitor-httpd-graceful EXITED
T-2:6tunnel-11080-{hash-generic}-on-watch RUNNING
T-2:6tunnel-11443-{hash-generic}-on-watch RUNNING
T-2:backend-client-login-certificate-caucase-updater-on-watch RUNNING
T-2:backend-haproxy-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-rsyslogd-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-safe-graceful EXITED
T-2:bootstrap-monitor EXITED
T-2:certificate_authority-{hash-generic}-on-watch RUNNING
T-2:crond-{hash-generic}-on-watch RUNNING
T-2:expose-csr_id-{hash-generic}-on-watch RUNNING
T-2:frontend-caddy-safe-graceful EXITED
T-2:frontend_caddy-{hash-caddy-T-2}-on-watch RUNNING
T-2:kedifa-login-certificate-caucase-updater-on-watch RUNNING
T-2:kedifa-updater-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-graceful EXITED
T-2:trafficserver-{hash-generic}-on-watch RUNNING
T-2:trafficserver-reload EXITED
test.TestSlaveSlapOSMasterCertificateCompatibilityOverrideMaster.test_file_list_etc_cron_d-CADDY.txt0000664 0000000 0000000 00000000644 13723117434 0060026 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/cron.d/logrotate
T-0/etc/cron.d/monitor-configurator
T-0/etc/cron.d/monitor-globalstate
T-0/etc/cron.d/monitor_collect
T-1/etc/cron.d/logrotate
T-1/etc/cron.d/monitor-configurator
T-1/etc/cron.d/monitor-globalstate
T-1/etc/cron.d/monitor_collect
T-2/etc/cron.d/logrotate
T-2/etc/cron.d/monitor-configurator
T-2/etc/cron.d/monitor-globalstate
T-2/etc/cron.d/monitor_collect
T-2/etc/cron.d/trafficserver-logrotate
test.TestSlaveSlapOSMasterCertificateCompatibilityOverrideMaster.test_file_list_log-CADDY.txt 0000664 0000000 0000000 00000001377 13723117434 0056514 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/log/monitor-httpd-access.log
T-0/var/log/monitor-httpd-error.log
T-0/var/log/slapgrid-T-0-error.log
T-1/var/log/expose-csr_id.log
T-1/var/log/kedifa.log
T-1/var/log/monitor-httpd-access.log
T-1/var/log/monitor-httpd-error.log
T-2/var/log/backend-haproxy.log
T-2/var/log/frontend-access.log
T-2/var/log/frontend-error.log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/httpd/_ssl_from_master_kedifa_overrides_master_certificate_access_log
T-2/var/log/httpd/_ssl_from_master_kedifa_overrides_master_certificate_backend_log
T-2/var/log/httpd/_ssl_from_master_kedifa_overrides_master_certificate_error_log
T-2/var/log/monitor-httpd-access.log
T-2/var/log/monitor-httpd-error.log
T-2/var/log/trafficserver/manager.log
T-2/var/log/trafficserver/traffic.out
test.TestSlaveSlapOSMasterCertificateCompatibilityOverrideMaster.test_file_list_plugin-CADDY.txt 0000664 0000000 0000000 00000003207 13723117434 0057223 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/plugin/__init__.py
T-0/etc/plugin/aibcc-user-caucase-updater.py
T-0/etc/plugin/aikc-user-caucase-updater.py
T-0/etc/plugin/buildout-T-0-status.py
T-0/etc/plugin/caucased-backend-client.py
T-0/etc/plugin/check-free-disk-space.py
T-0/etc/plugin/monitor-bootstrap-status.py
T-0/etc/plugin/monitor-http-frontend.py
T-0/etc/plugin/monitor-httpd-listening-on-tcp.py
T-0/etc/plugin/rejected-slave-publish-ip-port-listening.py
T-0/etc/plugin/rejected-slave.py
T-1/etc/plugin/__init__.py
T-1/etc/plugin/buildout-T-1-status.py
T-1/etc/plugin/caucased.py
T-1/etc/plugin/check-free-disk-space.py
T-1/etc/plugin/expose-csr_id-ip-port-listening.py
T-1/etc/plugin/kedifa-http-reply.py
T-1/etc/plugin/monitor-bootstrap-status.py
T-1/etc/plugin/monitor-http-frontend.py
T-1/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/__init__.py
T-2/etc/plugin/backend-client-caucase-updater.py
T-2/etc/plugin/backend-haproxy-configuration.py
T-2/etc/plugin/backend_haproxy_http.py
T-2/etc/plugin/backend_haproxy_https.py
T-2/etc/plugin/buildout-T-2-status.py
T-2/etc/plugin/caddy_frontend_ipv4_http.py
T-2/etc/plugin/caddy_frontend_ipv4_https.py
T-2/etc/plugin/caddy_frontend_ipv6_http.py
T-2/etc/plugin/caddy_frontend_ipv6_https.py
T-2/etc/plugin/caucase-updater.py
T-2/etc/plugin/check-free-disk-space.py
T-2/etc/plugin/expose-csr_id-ip-port-listening.py
T-2/etc/plugin/frontend-caddy-configuration-promise.py
T-2/etc/plugin/monitor-bootstrap-status.py
T-2/etc/plugin/monitor-http-frontend.py
T-2/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/re6st-connectivity.py
T-2/etc/plugin/trafficserver-cache-availability.py
T-2/etc/plugin/trafficserver-port-listening.py
test.TestSlaveSlapOSMasterCertificateCompatibilityOverrideMaster.test_file_list_run-CADDY.txt 0000664 0000000 0000000 00000000621 13723117434 0056526 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/run/monitor-httpd.pid
T-1/var/run/kedifa.pid
T-1/var/run/monitor-httpd.pid
T-2/var/run/backend-haproxy-rsyslogd.pid
T-2/var/run/backend-haproxy.pid
T-2/var/run/backend_haproxy_configuration_last_state
T-2/var/run/backend_haproxy_graceful_configuration_state_signature
T-2/var/run/bhlog.sck
T-2/var/run/graceful_configuration_state_signature
T-2/var/run/httpd.pid
T-2/var/run/monitor-httpd.pid
test.TestSlaveSlapOSMasterCertificateCompatibilityOverrideMaster.test_supervisor_state-CADDY.txt 0000664 0000000 0000000 00000003304 13723117434 0057312 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0:aibcc-user-caucase-updater-on-watch RUNNING
T-0:aikc-user-caucase-updater-on-watch RUNNING
T-0:bootstrap-monitor EXITED
T-0:caucased-backend-client-{hash-generic}-on-watch RUNNING
T-0:certificate_authority-{hash-generic}-on-watch RUNNING
T-0:crond-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-graceful EXITED
T-0:rejected-slave-publish-{hash-rejected-slave-publish}-on-watch RUNNING
T-1:bootstrap-monitor EXITED
T-1:caucase-updater-on-watch RUNNING
T-1:caucased-{hash-generic}-on-watch RUNNING
T-1:certificate_authority-{hash-generic}-on-watch RUNNING
T-1:crond-{hash-generic}-on-watch RUNNING
T-1:expose-csr_id-{hash-generic}-on-watch RUNNING
T-1:kedifa-{hash-generic}-on-watch RUNNING
T-1:kedifa-reloader EXITED
T-1:monitor-httpd-{hash-generic}-on-watch RUNNING
T-1:monitor-httpd-graceful EXITED
T-2:6tunnel-11080-{hash-generic}-on-watch RUNNING
T-2:6tunnel-11443-{hash-generic}-on-watch RUNNING
T-2:backend-client-login-certificate-caucase-updater-on-watch RUNNING
T-2:backend-haproxy-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-rsyslogd-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-safe-graceful EXITED
T-2:bootstrap-monitor EXITED
T-2:certificate_authority-{hash-generic}-on-watch RUNNING
T-2:crond-{hash-generic}-on-watch RUNNING
T-2:expose-csr_id-{hash-generic}-on-watch RUNNING
T-2:frontend-caddy-safe-graceful EXITED
T-2:frontend_caddy-{hash-caddy-T-2}-on-watch RUNNING
T-2:kedifa-login-certificate-caucase-updater-on-watch RUNNING
T-2:kedifa-updater-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-graceful EXITED
T-2:trafficserver-{hash-generic}-on-watch RUNNING
T-2:trafficserver-reload EXITED
test.TestSlaveSlapOSMasterCertificateCompatibilityUpdate.test_file_list_etc_cron_d-CADDY.txt 0000664 0000000 0000000 00000000644 13723117434 0056315 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/cron.d/logrotate
T-0/etc/cron.d/monitor-configurator
T-0/etc/cron.d/monitor-globalstate
T-0/etc/cron.d/monitor_collect
T-1/etc/cron.d/logrotate
T-1/etc/cron.d/monitor-configurator
T-1/etc/cron.d/monitor-globalstate
T-1/etc/cron.d/monitor_collect
T-2/etc/cron.d/logrotate
T-2/etc/cron.d/monitor-configurator
T-2/etc/cron.d/monitor-globalstate
T-2/etc/cron.d/monitor_collect
T-2/etc/cron.d/trafficserver-logrotate
test.TestSlaveSlapOSMasterCertificateCompatibilityUpdate.test_file_list_log-CADDY.txt 0000664 0000000 0000000 00000001223 13723117434 0054771 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/log/monitor-httpd-access.log
T-0/var/log/monitor-httpd-error.log
T-0/var/log/slapgrid-T-0-error.log
T-1/var/log/expose-csr_id.log
T-1/var/log/kedifa.log
T-1/var/log/monitor-httpd-access.log
T-1/var/log/monitor-httpd-error.log
T-2/var/log/backend-haproxy.log
T-2/var/log/frontend-access.log
T-2/var/log/frontend-error.log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/httpd/_ssl_from_master_access_log
T-2/var/log/httpd/_ssl_from_master_backend_log
T-2/var/log/httpd/_ssl_from_master_error_log
T-2/var/log/monitor-httpd-access.log
T-2/var/log/monitor-httpd-error.log
T-2/var/log/trafficserver/manager.log
T-2/var/log/trafficserver/traffic.out
test.TestSlaveSlapOSMasterCertificateCompatibilityUpdate.test_file_list_plugin-CADDY.txt 0000664 0000000 0000000 00000003207 13723117434 0055512 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/etc/plugin/__init__.py
T-0/etc/plugin/aibcc-user-caucase-updater.py
T-0/etc/plugin/aikc-user-caucase-updater.py
T-0/etc/plugin/buildout-T-0-status.py
T-0/etc/plugin/caucased-backend-client.py
T-0/etc/plugin/check-free-disk-space.py
T-0/etc/plugin/monitor-bootstrap-status.py
T-0/etc/plugin/monitor-http-frontend.py
T-0/etc/plugin/monitor-httpd-listening-on-tcp.py
T-0/etc/plugin/rejected-slave-publish-ip-port-listening.py
T-0/etc/plugin/rejected-slave.py
T-1/etc/plugin/__init__.py
T-1/etc/plugin/buildout-T-1-status.py
T-1/etc/plugin/caucased.py
T-1/etc/plugin/check-free-disk-space.py
T-1/etc/plugin/expose-csr_id-ip-port-listening.py
T-1/etc/plugin/kedifa-http-reply.py
T-1/etc/plugin/monitor-bootstrap-status.py
T-1/etc/plugin/monitor-http-frontend.py
T-1/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/__init__.py
T-2/etc/plugin/backend-client-caucase-updater.py
T-2/etc/plugin/backend-haproxy-configuration.py
T-2/etc/plugin/backend_haproxy_http.py
T-2/etc/plugin/backend_haproxy_https.py
T-2/etc/plugin/buildout-T-2-status.py
T-2/etc/plugin/caddy_frontend_ipv4_http.py
T-2/etc/plugin/caddy_frontend_ipv4_https.py
T-2/etc/plugin/caddy_frontend_ipv6_http.py
T-2/etc/plugin/caddy_frontend_ipv6_https.py
T-2/etc/plugin/caucase-updater.py
T-2/etc/plugin/check-free-disk-space.py
T-2/etc/plugin/expose-csr_id-ip-port-listening.py
T-2/etc/plugin/frontend-caddy-configuration-promise.py
T-2/etc/plugin/monitor-bootstrap-status.py
T-2/etc/plugin/monitor-http-frontend.py
T-2/etc/plugin/monitor-httpd-listening-on-tcp.py
T-2/etc/plugin/re6st-connectivity.py
T-2/etc/plugin/trafficserver-cache-availability.py
T-2/etc/plugin/trafficserver-port-listening.py
test.TestSlaveSlapOSMasterCertificateCompatibilityUpdate.test_file_list_run-CADDY.txt 0000664 0000000 0000000 00000000621 13723117434 0055015 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0/var/run/monitor-httpd.pid
T-1/var/run/kedifa.pid
T-1/var/run/monitor-httpd.pid
T-2/var/run/backend-haproxy-rsyslogd.pid
T-2/var/run/backend-haproxy.pid
T-2/var/run/backend_haproxy_configuration_last_state
T-2/var/run/backend_haproxy_graceful_configuration_state_signature
T-2/var/run/bhlog.sck
T-2/var/run/graceful_configuration_state_signature
T-2/var/run/httpd.pid
T-2/var/run/monitor-httpd.pid
test.TestSlaveSlapOSMasterCertificateCompatibilityUpdate.test_supervisor_state-CADDY.txt 0000664 0000000 0000000 00000003304 13723117434 0055601 0 ustar 00root root 0000000 0000000 slapos-23eb542d21c9b6e811cbda22245c6e706ec1bcef-software-caddy-frontend/software/caddy-frontend/test/test_data T-0:aibcc-user-caucase-updater-on-watch RUNNING
T-0:aikc-user-caucase-updater-on-watch RUNNING
T-0:bootstrap-monitor EXITED
T-0:caucased-backend-client-{hash-generic}-on-watch RUNNING
T-0:certificate_authority-{hash-generic}-on-watch RUNNING
T-0:crond-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-{hash-generic}-on-watch RUNNING
T-0:monitor-httpd-graceful EXITED
T-0:rejected-slave-publish-{hash-rejected-slave-publish}-on-watch RUNNING
T-1:bootstrap-monitor EXITED
T-1:caucase-updater-on-watch RUNNING
T-1:caucased-{hash-generic}-on-watch RUNNING
T-1:certificate_authority-{hash-generic}-on-watch RUNNING
T-1:crond-{hash-generic}-on-watch RUNNING
T-1:expose-csr_id-{hash-generic}-on-watch RUNNING
T-1:kedifa-{hash-generic}-on-watch RUNNING
T-1:kedifa-reloader EXITED
T-1:monitor-httpd-{hash-generic}-on-watch RUNNING
T-1:monitor-httpd-graceful EXITED
T-2:6tunnel-11080-{hash-generic}-on-watch RUNNING
T-2:6tunnel-11443-{hash-generic}-on-watch RUNNING
T-2:backend-client-login-certificate-caucase-updater-on-watch RUNNING
T-2:backend-haproxy-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-rsyslogd-{hash-generic}-on-watch RUNNING
T-2:backend-haproxy-safe-graceful EXITED
T-2:bootstrap-monitor EXITED
T-2:certificate_authority-{hash-generic}-on-watch RUNNING
T-2:crond-{hash-generic}-on-watch RUNNING
T-2:expose-csr_id-{hash-generic}-on-watch RUNNING
T-2:frontend-caddy-safe-graceful EXITED
T-2:frontend_caddy-{hash-caddy-T-2}-on-watch RUNNING
T-2:kedifa-login-certificate-caucase-updater-on-watch RUNNING
T-2:kedifa-updater-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-{hash-generic}-on-watch RUNNING
T-2:monitor-httpd-graceful EXITED
T-2:trafficserver-{hash-generic}-on-watch RUNNING
T-2:trafficserver-reload EXITED