Commit cc32ff06 authored by Tristan Cavelier's avatar Tristan Cavelier

monitor: add logout feature

parent 01d7f0be
...@@ -17,6 +17,8 @@ parts = ...@@ -17,6 +17,8 @@ parts =
monitor-web-index-html monitor-web-index-html
monitor-web-monitor-css monitor-web-monitor-css
monitor-web-monitor-js monitor-web-monitor-js
monitor-web-monitor-logout-cgi
monitor-web-monitor-logout-page
monitor-template monitor-template
rss-bin rss-bin
...@@ -69,14 +71,25 @@ md5sum = a18ab932e5e2e656995f47c7d4a7853a ...@@ -69,14 +71,25 @@ md5sum = a18ab932e5e2e656995f47c7d4a7853a
[monitor-web-monitor-js] [monitor-web-monitor-js]
<= monitor-download-base <= monitor-download-base
filename = monitor.js.in filename = monitor.js.in
md5sum = 4f8f1f7f26f589bfdae8fbfee74fc1cc md5sum = 89ca4da3a1895014a052f114605ed527
[monitor-web-monitor-logout-cgi]
<= monitor-download-base
filename = monitor-logout.sh.cgi
md5sum = 1daf20f1d6c025e33c608fd9c390e057
mode = 0755
[monitor-web-monitor-logout-page]
<= monitor-download-base
filename = monitor-logout.html
md5sum = b210c6842df541305d299081bc1bf81e
[monitor-template] [monitor-template]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template:jinja2
filename = template-monitor.cfg filename = template-monitor.cfg
template = ${:_profile_base_location_}/instance-monitor.cfg.jinja2.in template = ${:_profile_base_location_}/instance-monitor.cfg.jinja2.in
rendered = ${buildout:directory}/template-monitor.cfg rendered = ${buildout:directory}/template-monitor.cfg
md5sum = c9bcc845671f78bc3e4c544aa84313e3 md5sum = 80527d09711810f74cfc2a8c2c9be880
context = context =
key apache_location apache:location key apache_location apache:location
key gzip_location gzip:location key gzip_location gzip:location
...@@ -84,6 +97,8 @@ context = ...@@ -84,6 +97,8 @@ context =
raw monitor_conf_template ${monitor-conf:location}/${monitor-conf:filename} raw monitor_conf_template ${monitor-conf:location}/${monitor-conf:filename}
raw monitor_web_index_html ${monitor-web-index-html:location}/${monitor-web-index-html:filename} raw monitor_web_index_html ${monitor-web-index-html:location}/${monitor-web-index-html:filename}
raw monitor_web_monitor_css ${monitor-web-monitor-css:location}/${monitor-web-monitor-css:filename} raw monitor_web_monitor_css ${monitor-web-monitor-css:location}/${monitor-web-monitor-css:filename}
raw monitor_web_monitor_logout_cgi ${monitor-web-monitor-logout-cgi:location}/${monitor-web-monitor-logout-cgi:filename}
raw monitor_web_monitor_logout_page ${monitor-web-monitor-logout-page:location}/${monitor-web-monitor-logout-page:filename}
raw monitor_web_monitor_js ${monitor-web-monitor-js:location}/${monitor-web-monitor-js:filename} raw monitor_web_monitor_js ${monitor-web-monitor-js:location}/${monitor-web-monitor-js:filename}
raw curl_executable_location ${curl:location}/bin/curl raw curl_executable_location ${curl:location}/bin/curl
raw dash_executable_location ${dash:location}/bin/dash raw dash_executable_location ${dash:location}/bin/dash
...@@ -101,7 +116,7 @@ context = ...@@ -101,7 +116,7 @@ context =
recipe = hexagonit.recipe.download recipe = hexagonit.recipe.download
url = ${:_profile_base_location_}/templates/${:filename} url = ${:_profile_base_location_}/templates/${:filename}
download-only = true download-only = true
md5sum = f24951a2de34d3f3675e8712944a70a0 md5sum = 5be55c3918daa9cc9f8425bfc40e70b1
filename = monitor-httpd.conf.in filename = monitor-httpd.conf.in
mode = 0644 mode = 0644
......
...@@ -103,8 +103,8 @@ ca-crl = ${ca-directory:crl} ...@@ -103,8 +103,8 @@ ca-crl = ${ca-directory:crl}
[ca-httpd] [ca-httpd]
<= certificate-authority <= certificate-authority
recipe = slapos.cookbook:certificate_authority.request recipe = slapos.cookbook:certificate_authority.request
key-file = ${monitor-httpd-conf:key-file} key-file = ${monitor-httpd-conf-parameter:key-file}
cert-file = ${monitor-httpd-conf:cert-file} cert-file = ${monitor-httpd-conf-parameter:cert-file}
executable = ${httpd-wrapper:wrapper-path} executable = ${httpd-wrapper:wrapper-path}
wrapper = ${directory:services}/monitor-httpd wrapper = ${directory:services}/monitor-httpd
...@@ -131,15 +131,15 @@ rendered = ${directory:etc}/${:filename} ...@@ -131,15 +131,15 @@ rendered = ${directory:etc}/${:filename}
filename = monitor.conf filename = monitor.conf
context = section parameter_dict monitor-conf-parameters context = section parameter_dict monitor-conf-parameters
[httpd-monitor-htaccess] [httpd-monitor-htpasswd]
recipe = plone.recipe.command recipe = plone.recipe.command
stop-on-error = true stop-on-error = true
htaccess-path = ${monitor-directory:etc}/.htaccess htpasswd-path = ${monitor-directory:etc}/monitor-htpasswd
command = {{ apache_location }}/bin/htpasswd -cb ${:htaccess-path} ${:user} ${:password} command = {{ apache_location }}/bin/htpasswd -cb ${:htpasswd-path} ${:user} ${:password}
user = admin user = admin
password = admin password = admin
[monitor-httpd-conf] [monitor-httpd-conf-parameter]
listening-ip = ${monitor-instance-parameter:monitor-httpd-ipv6} listening-ip = ${monitor-instance-parameter:monitor-httpd-ipv6}
port = ${monitor-instance-parameter:monitor-httpd-port} port = ${monitor-instance-parameter:monitor-httpd-port}
pid-file = ${directory:run}/httpd.pid pid-file = ${directory:run}/httpd.pid
...@@ -148,7 +148,7 @@ access-log = ${monitor-directory:log}/httpd-access.log ...@@ -148,7 +148,7 @@ access-log = ${monitor-directory:log}/httpd-access.log
error-log = ${monitor-directory:log}/httpd-error.log error-log = ${monitor-directory:log}/httpd-error.log
cert-file = ${ca-directory:certs}/httpd.crt cert-file = ${ca-directory:certs}/httpd.crt
key-file = ${ca-directory:certs}/httpd.key key-file = ${ca-directory:certs}/httpd.key
htaccess-file = ${httpd-monitor-htaccess:htaccess-path} htpasswd-file = ${httpd-monitor-htpasswd:htpasswd-path}
url = https://[${monitor-instance-parameter:monitor-httpd-ipv6}]:${:port}/ url = https://[${monitor-instance-parameter:monitor-httpd-ipv6}]:${:port}/
[monitor-httpd-conf] [monitor-httpd-conf]
...@@ -158,8 +158,7 @@ rendered = ${monitor-directory:etc}/monitor-httpd.conf ...@@ -158,8 +158,7 @@ rendered = ${monitor-directory:etc}/monitor-httpd.conf
mode = 0744 mode = 0744
context = context =
section directory monitor-directory section directory monitor-directory
section monitor_parameters monitor-conf section parameter_dict monitor-httpd-conf-parameter
section monitor_httpd monitor-httpd-conf
[httpd-wrapper] [httpd-wrapper]
recipe = slapos.cookbook:wrapper recipe = slapos.cookbook:wrapper
...@@ -177,7 +176,7 @@ rendered = ${directory:run}/monitor-httpd-graceful ...@@ -177,7 +176,7 @@ rendered = ${directory:run}/monitor-httpd-graceful
mode = 0700 mode = 0700
context = context =
key content :command key content :command
command = kill -USR1 $(cat ${monitor-httpd-conf:pid-file}) command = kill -USR1 $(cat ${monitor-httpd-conf-parameter:pid-file})
[monitor-web-index-html] [monitor-web-index-html]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template:jinja2
...@@ -198,6 +197,19 @@ rendered = ${monitor-directory:web-dir}/monitor.js ...@@ -198,6 +197,19 @@ rendered = ${monitor-directory:web-dir}/monitor.js
context = context =
key monitor_title monitor-instance-parameter:monitor-title key monitor_title monitor-instance-parameter:monitor-title
[monitor-web-monitor-logout-cgi]
recipe = slapos.recipe.template:jinja2
template = {{ monitor_web_monitor_logout_cgi }}
rendered = ${monitor-directory:cgi-bin}/monitor-logout.cgi
mode = 0755
context =
[monitor-web-monitor-logout-page]
recipe = slapos.recipe.template:jinja2
template = {{ monitor_web_monitor_logout_page }}
rendered = ${monitor-directory:web-dir}/logout
context =
[start-monitor] [start-monitor]
recipe = slapos.recipe.template:jinja2 recipe = slapos.recipe.template:jinja2
template = {{ monitor_bin }} template = {{ monitor_bin }}
...@@ -219,7 +231,7 @@ context = ...@@ -219,7 +231,7 @@ context =
[monitor-promise] [monitor-promise]
recipe = slapos.cookbook:check_url_available recipe = slapos.cookbook:check_url_available
path = ${directory:promises}/monitor path = ${directory:promises}/monitor
url = ${monitor-httpd-conf:url} url = ${monitor-httpd-conf-parameter:url}
check-secure = 1 check-secure = 1
dash_path = {{ dash_executable_location }} dash_path = {{ dash_executable_location }}
curl_path = {{ curl_executable_location }} curl_path = {{ curl_executable_location }}
...@@ -261,7 +273,7 @@ frequency = */5 * * * * ...@@ -261,7 +273,7 @@ frequency = */5 * * * *
[monitor-publish] [monitor-publish]
recipe = slapos.cookbook:publish recipe = slapos.cookbook:publish
monitor_url_v6 = ${monitor-httpd-conf:url} monitor_url_v6 = ${monitor-httpd-conf-parameter:url}
[monitor-instance-parameter] [monitor-instance-parameter]
monitor-title = Monitoring interface monitor-title = Monitoring interface
...@@ -271,6 +283,8 @@ parts = ...@@ -271,6 +283,8 @@ parts =
monitor-web-index-html monitor-web-index-html
monitor-web-monitor-css monitor-web-monitor-css
monitor-web-monitor-js monitor-web-monitor-js
monitor-web-monitor-logout-cgi
monitor-web-monitor-logout-page
cron-entry-logrotate cron-entry-logrotate
certificate-authority certificate-authority
monitor-conf monitor-conf
......
<!DOCTYPE html>
<html>
<head><title>Monitor logout</title></head>
<body>
<noscript>Cannot logout without javascript</noscript>
<script>
var logoutURL = "/cgi-bin/monitor-logout.cgi",
xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status === 401) {
document.body.innerHTML = "<p>You are now logged out. You can go back to the monitor interface <a href=\"/\">here</a>.</p>";
} else {
console.error("Cannot logout (" + xhr.status + ")");
document.body.innerHTML = "<p>Cannot logout, retrying in 5 seconds.</p>";
setTimeout(location.reload.bind(location), 5000);
}
};
xhr.onerror = function () {
document.body.innerHTML = "<p>Cannot logout, please try again later.</p>";
};
xhr.open("POST", logoutURL, true, " logout", " password");
xhr.send();
document.body.innerHTML = "<p>Logging out...</p>";
</script>
</body>
</html>
#!/bin/sh
echo -en 'Status: 401 Unauthorized\r\nWWW-Authenticate: Basic realm="Private access"\r\n\r\n'
...@@ -147,7 +147,7 @@ ...@@ -147,7 +147,7 @@
function bootstrap(root) { function bootstrap(root) {
var element_list = htmlToElementList([ var element_list = htmlToElementList([
"<header><a href=\"\" class=\"as-button\">Refresh</a></header>", "<header><a href=\"\" class=\"as-button\">Refresh</a> <a href=\"/logout\" class=\"as-button\">Logout</a></header>",
"<h1>" + monitor_title + "</h1>", "<h1>" + monitor_title + "</h1>",
"<h2>System health status</h2>", "<h2>System health status</h2>",
"<p>This interface allow to see the status of several features, it may show problems and sometimes provides a way to fix them.</p>", "<p>This interface allow to see the status of several features, it may show problems and sometimes provides a way to fix them.</p>",
......
PidFile "{{ monitor_httpd.get('pid-file') }}" PidFile "{{ parameter_dict.get('pid-file') }}"
StartServers 1 StartServers 1
ServerLimit 1 ServerLimit 1
...@@ -8,11 +8,11 @@ ThreadsPerChild 4 ...@@ -8,11 +8,11 @@ ThreadsPerChild 4
ServerName example.com ServerName example.com
ServerAdmin someone@email ServerAdmin someone@email
<IfDefine !MonitorPort> <IfDefine !MonitorPort>
Listen [{{ monitor_httpd.get('listening-ip') }}]:{{ monitor_httpd.get('port') }} Listen [{{ parameter_dict.get('listening-ip') }}]:{{ parameter_dict.get('port') }}
Define MonitorPort Define MonitorPort
</IfDefine> </IfDefine>
DocumentRoot "{{ directory.get('www') }}" DocumentRoot "{{ directory.get('www') }}"
ErrorLog "{{ monitor_httpd.get('error-log') }}" ErrorLog "{{ parameter_dict.get('error-log') }}"
LoadModule unixd_module modules/mod_unixd.so LoadModule unixd_module modules/mod_unixd.so
LoadModule access_compat_module modules/mod_access_compat.so LoadModule access_compat_module modules/mod_access_compat.so
LoadModule authz_core_module modules/mod_authz_core.so LoadModule authz_core_module modules/mod_authz_core.so
...@@ -34,8 +34,8 @@ LoadModule rewrite_module modules/mod_rewrite.so ...@@ -34,8 +34,8 @@ LoadModule rewrite_module modules/mod_rewrite.so
# SSL Configuration # SSL Configuration
<IfDefine !SSLConfigured> <IfDefine !SSLConfigured>
Define SSLConfigured Define SSLConfigured
SSLCertificateFile {{ monitor_httpd.get('cert-file') }} SSLCertificateFile {{ parameter_dict.get('cert-file') }}
SSLCertificateKeyFile {{ monitor_httpd.get('key-file') }} SSLCertificateKeyFile {{ parameter_dict.get('key-file') }}
SSLRandomSeed startup builtin SSLRandomSeed startup builtin
SSLRandomSeed connect builtin SSLRandomSeed connect builtin
SSLRandomSeed startup /dev/urandom 256 SSLRandomSeed startup /dev/urandom 256
...@@ -47,7 +47,7 @@ SSLCipherSuite RC4-SHA:HIGH:!ADH ...@@ -47,7 +47,7 @@ SSLCipherSuite RC4-SHA:HIGH:!ADH
AddType application/hal+json .haljson AddType application/hal+json .haljson
SSLEngine On SSLEngine On
ScriptSock {{ monitor_httpd.get('cgid-pid-file') }} ScriptSock {{ parameter_dict.get('cgid-pid-file') }}
<Directory {{ directory.get('www') }}> <Directory {{ directory.get('www') }}>
SSLVerifyDepth 1 SSLVerifyDepth 1
SSLRequireSSL SSLRequireSSL
...@@ -57,24 +57,27 @@ ScriptSock {{ monitor_httpd.get('cgid-pid-file') }} ...@@ -57,24 +57,27 @@ ScriptSock {{ monitor_httpd.get('cgid-pid-file') }}
#AddHandler cgi-script .cgi #AddHandler cgi-script .cgi
DirectoryIndex index.html DirectoryIndex index.html
Options FollowSymLinks Options FollowSymLinks
Order Allow,Deny Order Deny,Allow
Allow from all AuthType Basic
AuthName "Private access"
AuthUserFile "{{ parameter_dict.get('htpasswd-file') }}"
Require valid-user
</Directory> </Directory>
Alias /private {{ directory.get('private') }}/ Alias /private {{ directory.get('private') }}/
<Directory {{ directory.get('private') }}> <Directory {{ directory.get('private') }}>
Order Deny,Allow Order Deny,Allow
Deny from env=AUTHREQUIRED Deny from env=AUTHREQUIRED
<Files ".??*"> <Files ".??*">
Order Allow,Deny Order Allow,Deny
Deny from all Deny from all
</Files> </Files>
AuthType Basic AuthType Basic
AuthName "Private access" AuthName "Private access"
AuthUserFile "{{ monitor_httpd.get('htaccess-file') }}" AuthUserFile "{{ parameter_dict.get('htpasswd-file') }}"
Require valid-user Require valid-user
Options Indexes FollowSymLinks Options Indexes FollowSymLinks
Satisfy all Satisfy all
</Directory> </Directory>
Alias /public {{ directory.get('public') }}/ Alias /public {{ directory.get('public') }}/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment