Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
slapos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
slapos
Commits
7a2cfab1
Commit
7a2cfab1
authored
Oct 08, 2015
by
Tristan Cavelier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
monitor2: add monitor password interface
parent
dc578acb
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
271 additions
and
1 deletion
+271
-1
stack/monitor2/buildout.cfg
stack/monitor2/buildout.cfg
+7
-1
stack/monitor2/instance-monitor.cfg.jinja2.in
stack/monitor2/instance-monitor.cfg.jinja2.in
+11
-0
stack/monitor2/monitor-password-interface.html
stack/monitor2/monitor-password-interface.html
+253
-0
No files found.
stack/monitor2/buildout.cfg
View file @
7a2cfab1
...
...
@@ -106,7 +106,7 @@ recipe = slapos.recipe.template:jinja2
filename = template-monitor.cfg
template = ${:_profile_base_location_}/instance-monitor.cfg.jinja2.in
rendered = ${buildout:directory}/template-monitor.cfg
md5sum =
f0356d4a0048dc22de4f61191f7caa7e
md5sum =
c3438660ae33d0049fceaf45ddb781bf
context =
key apache_location apache:location
key gzip_location gzip:location
...
...
@@ -114,6 +114,7 @@ context =
raw monitor_conf_template ${monitor-conf:location}/${monitor-conf:filename}
raw monitor_password_promise_template ${monitor-password-promise:location}/${monitor-password-promise:filename}
raw monitor_password_cgi_template ${monitor-password-cgi:location}/${monitor-password-cgi:filename}
raw monitor_password_promise_interface_template ${monitor-password-promise-interface:location}/${monitor-password-promise-interface:filename}
raw monitor_web_default_promise_interface ${monitor-web-default-promise-interface:location}/${monitor-web-default-promise-interface: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}
...
...
@@ -213,6 +214,11 @@ md5sum = 0a9a42551ed6bdb973fd1f0dd1d4ec86
md5sum = 04fc7e6d892d29a601cfd43d1700eeda
filename = monitor-password.py.cgi
[monitor-password-promise-interface]
<= monitor-download-base
filename = monitor-password-interface.html
md5sum = 04b664dfb47bfd3d01502768311aa239
[rss-bin]
recipe = hexagonit.recipe.download
url = ${:_profile_base_location_}/${:filename}
...
...
stack/monitor2/instance-monitor.cfg.jinja2.in
View file @
7a2cfab1
...
...
@@ -66,6 +66,9 @@ www = ${directory:monitor}/web
web-dir = ${directory:monitor}/web
log = ${directory:log}/monitor
promise-wrapper = ${directory:var}/monitor-promise-wrapper
monitor-var = ${directory:var}/monitor
monitor-password-var = ${monitor-directory:monitor-var}/password
monitor-password-interface = ${monitor-directory:monitor-password-var}/password/interface
[logrotate-directory]
recipe = slapos.cookbook:mkdirectory
...
...
@@ -287,6 +290,7 @@ context =
[monitor-password-promise-conf-parameter]
title = Monitor password
frequency = */5 * * * *
private-path-list = ${monitor-directory:monitor-password-interface}
[monitor-password-promise-conf]
recipe = slapos.recipe.template:jinja2
...
...
@@ -305,6 +309,12 @@ context =
raw htpasswd_executable {{ apache_location }}/bin/htpasswd
key htpasswd_path httpd-monitor-htpasswd:htpasswd-path
[monitor-password-promise-interface]
recipe = slapos.recipe.template:jinja2
template = {{ monitor_password_promise_interface_template }}
rendered = ${monitor-directory:monitor-password-interface}/index.html
context =
[publish]
recipe = slapos.cookbook:publish
monitor-url = ${monitor-httpd-conf-parameter:url}
...
...
@@ -331,4 +341,5 @@ parts =
monitor-password-promise
monitor-password-promise-conf
monitor-password-cgi
monitor-password-promise-interface
publish
stack/monitor2/monitor-password-interface.html
0 → 100644
View file @
7a2cfab1
<!DOCTYPE html>
<html>
<head>
<meta
charset=
"utf-8"
/>
<title>
Monitor password
</title>
<style>
input
,
button
{
min-height
:
10mm
;
min-width
:
10mm
;
}
</style>
<script>
var
service_name
=
"
monitor-password
"
,
// XXX hardcoded
monitor_json_url
=
"
/monitor.haljson
"
,
status_json_url
=
"
/public/
"
+
service_name
+
"
.status.json
"
,
rerun_cgi_url
=
"
/cgi-bin/monitor-run-promise.cgi?service=
"
+
service_name
,
password_cgi_url_part
=
"
/cgi-bin/monitor-password.cgi?password=
"
;
function
newDeferred
()
{
var
d
=
{
"
promise
"
:
undefined
,
"
resolve
"
:
undefined
,
"
reject
"
:
undefined
};
d
.
promise
=
new
Promise
(
function
(
resolve
,
reject
)
{
d
.
resolve
=
resolve
;
d
.
reject
=
reject
;
});
return
d
;
}
function
xhr
(
param
)
{
/*global XMLHttpRequest */
var
d
=
newDeferred
(),
xhr
=
new
XMLHttpRequest
(),
k
,
i
,
l
,
a
;
d
.
promise
.
cancel
=
function
()
{
xhr
.
abort
();
};
if
(
param
.
username
)
{
xhr
.
open
((
param
.
method
||
"
GET
"
).
toUpperCase
(),
param
.
url
,
true
,
param
.
username
,
param
.
password
);
}
else
{
xhr
.
open
((
param
.
method
||
"
GET
"
).
toUpperCase
(),
param
.
url
,
true
);
}
xhr
.
responseType
=
param
.
responseType
||
""
;
if
(
param
.
withCredentials
!==
undefined
)
{
xhr
.
withCredentials
=
param
.
withCredentials
;
}
if
(
param
.
headers
)
{
a
=
Object
.
keys
(
param
.
headers
);
l
=
a
.
length
;
for
(
i
=
0
;
i
<
l
;
i
+=
1
)
{
k
=
a
[
i
];
xhr
.
setRequestHeader
(
k
,
param
.
headers
[
k
]);
}
}
xhr
.
addEventListener
(
"
load
"
,
function
(
e
)
{
var
r
,
t
=
e
.
target
,
callback
;
if
(
param
.
noStatusCheck
)
{
d
.
resolve
(
t
);
}
else
if
(
t
.
status
<
400
)
{
d
.
resolve
(
t
);
}
else
{
r
=
new
Error
(
"
HTTP:
"
+
(
t
.
status
?
t
.
status
+
"
"
:
""
)
+
(
t
.
statusText
||
"
Unknown
"
));
r
.
target
=
t
;
d
.
reject
(
r
);
}
},
false
);
xhr
.
addEventListener
(
"
error
"
,
function
(
e
)
{
return
d
.
reject
(
new
Error
(
"
HTTP: Error
"
));
},
false
);
xhr
.
addEventListener
(
"
abort
"
,
function
(
e
)
{
return
d
.
reject
(
new
Error
(
"
HTTP: Aborted
"
));
},
false
);
xhr
.
send
(
param
.
data
);
return
d
.
promise
;
}
function
unexpectedError
(
reason
)
{
console
.
error
(
reason
);
alert
(
reason
);
}
function
MonitorPasswordInterface
(
config
)
{
var
it
=
this
,
statusP
=
document
.
createElement
(
"
p
"
),
descriptionP
=
document
.
createElement
(
"
p
"
),
form
=
document
.
createElement
(
"
form
"
),
formPassword1Input
=
document
.
createElement
(
"
input
"
),
formPassword2Input
=
document
.
createElement
(
"
input
"
),
formChangePasswordButton
=
document
.
createElement
(
"
button
"
),
errorH2
=
document
.
createElement
(
"
h2
"
),
errorPre
=
document
.
createElement
(
"
pre
"
),
header
=
document
.
createElement
(
"
header
"
),
h1
=
document
.
createElement
(
"
h1
"
),
h2
=
document
.
createElement
(
"
h2
"
),
a
=
document
.
createElement
(
"
a
"
),
button
=
document
.
createElement
(
"
button
"
);
this
.
element
=
config
.
rootElement
||
document
.
createElement
(
"
div
"
);
this
.
statusP
=
statusP
;
this
.
descriptionP
=
descriptionP
;
this
.
formPassword1Input
=
formPassword1Input
;
this
.
formPassword2Input
=
formPassword2Input
;
this
.
formChangePasswordButton
=
formChangePasswordButton
;
this
.
errorH2
=
errorH2
;
this
.
errorPre
=
errorPre
;
this
.
element
.
appendChild
(
header
);
header
.
appendChild
(
a
);
a
.
setAttribute
(
"
tabindex
"
,
"
-1
"
);
a
.
setAttribute
(
"
href
"
,
"
/
"
);
a
.
appendChild
(
button
);
button
.
textContent
=
"
Home
"
;
a
=
document
.
createElement
(
"
a
"
);
button
=
document
.
createElement
(
"
button
"
);
header
.
appendChild
(
a
);
a
.
setAttribute
(
"
tabindex
"
,
"
-1
"
);
a
.
setAttribute
(
"
href
"
,
""
);
a
.
appendChild
(
button
);
button
.
textContent
=
"
Refresh
"
;
this
.
element
.
appendChild
(
h1
);
h1
.
textContent
=
"
Monitor password
"
;
this
.
element
.
appendChild
(
statusP
);
this
.
element
.
appendChild
(
descriptionP
);
this
.
element
.
appendChild
(
form
);
form
.
appendChild
(
formPassword1Input
);
formPassword1Input
.
setAttribute
(
"
type
"
,
"
password
"
);
form
.
onsubmit
=
this
.
onFormSubmit
.
bind
(
this
);
form
.
appendChild
(
document
.
createElement
(
"
br
"
));
form
.
appendChild
(
formPassword2Input
);
formPassword2Input
.
setAttribute
(
"
type
"
,
"
password
"
);
form
.
appendChild
(
document
.
createElement
(
"
br
"
));
form
.
appendChild
(
formChangePasswordButton
);
formChangePasswordButton
.
setAttribute
(
"
type
"
,
"
submit
"
);
formChangePasswordButton
.
textContent
=
"
Change password
"
;
this
.
element
.
appendChild
(
errorH2
);
errorH2
.
textContent
=
"
Operational error
"
;
errorH2
.
style
.
display
=
"
none
"
;
this
.
element
.
appendChild
(
errorPre
);
errorPre
.
style
.
display
=
"
none
"
;
this
.
loadStatusUi
();
this
.
loadDescriptionUi
();
this
.
loadErrorUi
();
}
MonitorPasswordInterface
.
prototype
.
loadStatusJson
=
function
()
{
if
(
this
.
status_json_promise
)
{
return
;
}
this
.
status_json_promise
=
Promise
.
resolve
().
then
(
function
()
{
return
xhr
({
url
:
status_json_url
,
withCredentials
:
true
,
responseType
:
"
json
"
});
}).
then
(
function
(
xhr
)
{
return
xhr
.
response
;
});
this
.
status_json_promise
.
catch
(
function
()
{
return
;
}).
then
(
function
()
{
setTimeout
(
function
()
{
delete
this
.
status_json_promise
;
}.
bind
(
this
),
1000
);
}.
bind
(
this
));
return
this
.
status_json_promise
;
};
MonitorPasswordInterface
.
prototype
.
loadStatusUi
=
function
()
{
this
.
loadStatusJson
();
this
.
statusP
.
textContent
=
"
Loading status...
"
;
return
this
.
status_json_promise
.
then
(
function
(
status_json
)
{
if
(
status_json
.
status
===
"
OK
"
)
{
this
.
statusP
.
innerHTML
=
"
"
;
}
else
{
this
.
statusP
.
textContent
=
"
/!
\\
The password needs to be changed at least once! /!
\\
"
;
}
}.
bind
(
this
),
function
(
reason
)
{
if
(
reason
&&
reason
.
target
&&
reason
.
target
.
status
===
404
)
{
this
.
statusP
.
textContent
=
"
/!
\\
The password needs to be changed at least once! /!
\\
"
;
return
;
}
var
message
=
reason
&&
(
reason
.
target
&&
(
reason
.
target
.
statusText
||
"
Unknown
"
)
||
reason
.
message
);
this
.
statusP
.
textContent
=
"
Status Json Error:
"
+
(
message
||
"
Unknown error
"
);
}.
bind
(
this
)).
catch
(
unexpectedError
);
};
MonitorPasswordInterface
.
prototype
.
loadDescriptionUi
=
function
()
{
this
.
descriptionP
.
textContent
=
[
"
The monitor password is the password used to connect to this interface.
"
,
"
Here you can change the monitor password by filling the formular just below.
"
].
join
(
"
\n
"
);
};
MonitorPasswordInterface
.
prototype
.
loadErrorUi
=
function
()
{
this
.
loadStatusJson
();
this
.
errorPre
.
textContent
=
"
Loading error output...
"
;
return
this
.
status_json_promise
.
then
(
function
(
status_json
)
{
if
(
status_json
.
error
)
{
this
.
errorH2
.
style
.
display
=
""
;
this
.
errorPre
.
style
.
display
=
""
;
this
.
errorPre
.
textContent
=
status_json
.
error
;
}
else
{
this
.
errorH2
.
style
.
display
=
"
none
"
;
this
.
errorPre
.
style
.
display
=
"
none
"
;
this
.
errorPre
.
textContent
=
""
;
}
}.
bind
(
this
),
function
(
reason
)
{
var
message
=
reason
&&
(
reason
.
target
&&
(
reason
.
target
.
statusText
||
"
Unknown
"
)
||
reason
.
message
);
this
.
errorPre
.
textContent
=
"
Status Json Error:
"
+
(
message
||
"
Unknown error
"
);
}.
bind
(
this
)).
catch
(
unexpectedError
);
};
MonitorPasswordInterface
.
prototype
.
onFormSubmit
=
function
(
event
)
{
event
.
preventDefault
();
event
.
stopPropagation
();
this
.
execForm
();
};
MonitorPasswordInterface
.
prototype
.
execForm
=
function
()
{
if
(
this
.
formPassword1Input
.
value
!==
this
.
formPassword2Input
.
value
)
{
this
.
statusP
.
textContent
=
"
The two typed passwords should match!
"
;
return
;
}
this
.
statusP
.
textContent
=
"
Changing password...
"
;
var
password
=
this
.
formPassword1Input
.
value
;
return
Promise
.
resolve
().
then
(
function
()
{
return
xhr
({
url
:
password_cgi_url_part
+
password
,
method
:
"
POST
"
,
withCredentials
:
true
});
}).
then
(
function
()
{
this
.
statusP
.
textContent
=
"
Password changed succesfully!
"
;
this
.
formPassword1Input
.
value
=
this
.
formPassword2Input
.
value
=
""
;
// rerun promise with new login (also does the relogin)
xhr
({
url
:
rerun_cgi_url
,
method
:
"
POST
"
,
withCredentials
:
true
,
username
:
"
admin
"
,
password
:
password
});
}.
bind
(
this
),
function
(
reason
)
{
var
message
=
reason
&&
(
reason
.
target
&&
(
reason
.
target
.
statusText
||
"
Unknown
"
)
||
reason
.
message
);
this
.
statusP
.
textContent
=
"
Status Json Error:
"
+
(
message
||
"
Unknown error
"
);
}.
bind
(
this
));
};
MonitorPasswordInterface
.
prototype
.
runPromiseNow
=
function
()
{
this
.
runPromiseNowButton
.
disabled
=
true
;
var
original_text
=
this
.
runPromiseNowButton
.
textContent
;
this
.
runPromiseNowButton
.
textContent
=
"
Sending message...
"
;
return
Promise
.
resolve
().
then
(
function
()
{
return
xhr
({
url
:
rerun_cgi_url
,
method
:
"
POST
"
,
withCredentials
:
true
});
}).
catch
(
unexpectedError
).
then
(
function
()
{
this
.
runPromiseNowButton
.
textContent
=
original_text
;
}.
bind
(
this
));
};
/*global setTimeout */
setTimeout
(
function
()
{
/*global document */
document
.
body
.
innerHTML
=
""
;
return
new
MonitorPasswordInterface
({
rootElement
:
document
.
body
});
});
</script>
</head>
<body>
<h1>
Monitor password
</h1>
<noscript>
Javascript should be enabled
</noscript>
</body>
</html>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment