Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ntof
daq
DIMon
Commits
bf19d9b1
Commit
bf19d9b1
authored
Sep 20, 2021
by
Gabriele De Blasi
Browse files
extract IPMIConsole handling from DimonServer
parent
9527c08d
Pipeline
#3037071
passed with stages
in 11 minutes and 41 seconds
Changes
10
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/Actions/IPMIConsole.js
0 → 100644
View file @
bf19d9b1
// @ts-check
const
IPMIConsole
=
require
(
'
express
'
).
Router
(),
path
=
require
(
'
path
'
),
pug
=
require
(
'
pug
'
),
{
get
,
isEmpty
,
toString
}
=
require
(
'
lodash
'
),
superagent
=
require
(
'
superagent
'
),
{
DOMParser
}
=
require
(
'
xmldom
'
),
ipmiPath
=
'
/dist/ipmi-console
'
,
// IPMI-JavaWS resources path
iKVMTemplate
=
pug
.
compileFile
(
path
.
join
(
__dirname
,
'
../../www
'
,
`
${
ipmiPath
}
/iKVM.pug`
),
{
pretty
:
true
});
IPMIConsole
.
get
(
'
/ipmi-console/:host
'
,
async
(
req
,
res
,
next
)
=>
{
const
credentials
=
get
(
req
,
[
'
locals
'
,
'
credentials
'
]);
const
host
=
req
.
params
.
host
;
try
{
// fetch session credentials
const
loginUsr
=
get
(
credentials
,
[
`ipmi://
${
host
}
`
,
'
user
'
]);
if
(
!
loginUsr
)
{
throw
new
Error
(
`'
${
host
}
' login error: user missing.`
);
}
const
loginPsw
=
get
(
credentials
,
[
`ipmi://
${
host
}
`
,
'
password
'
]);
if
(
!
loginPsw
)
{
throw
new
Error
(
`'
${
host
}
' login error: password missing.`
);
}
const
agent
=
superagent
.
agent
();
// to save cookies
// login
await
agent
.
post
(
`https://
${
host
}
/cgi/login.cgi`
)
.
disableTLSCerts
()
/* FIXME: update certs and remove this line */
.
send
(
`name=
${
loginUsr
}
&pwd=
${
loginPsw
}
`
);
// check Session ID
const
SID
=
agent
.
jar
.
getCookie
(
'
SID
'
,
{
path
:
'
/
'
,
domain
:
host
,
secure
:
true
,
script
:
false
});
if
(
SID
&&
isEmpty
(
SID
.
value
))
{
throw
new
Error
(
`'
${
host
}
' login error: cannot open a session. `
+
`Please check credentials.`
);
}
// generate the 'iKVM.jnlp' file
const
iKVM
=
await
agent
.
get
(
`https://
${
host
}
/cgi/url_redirect.cgi?url_name=ikvm&url_type=jwsk`
)
.
disableTLSCerts
()
/* FIXME: update certs and remove this line */
.
then
((
/** @type {any} */
res
)
=>
{
const
doc
=
new
DOMParser
().
parseFromString
(
toString
(
res
.
body
));
const
args
=
doc
.
getElementsByTagName
(
'
argument
'
);
return
iKVMTemplate
({
basePath
:
`
${
req
.
protocol
}
://
${
req
.
get
(
'
host
'
)}
`
+
ipmiPath
,
host
,
username
:
args
[
1
].
textContent
,
password
:
args
[
2
].
textContent
});
});
return
res
.
set
(
'
Content-Disposition
'
,
`attachment; filename="iKVM.jnlp"`
)
.
set
(
'
Content-Type
'
,
'
application/x-java-jnlp-file
'
)
.
status
(
200
)
.
send
(
iKVM
);
}
catch
(
err
)
{
return
next
(
err
);
}
});
module
.
exports
=
IPMIConsole
;
src/DimonServer.js
View file @
bf19d9b1
...
...
@@ -3,13 +3,10 @@
const
{
Dimon
,
Status
}
=
require
(
'
./Dimon
'
),
{
ActionRunner
,
ActAllowed
}
=
require
(
'
./Actions/ActionRunner
'
),
IPMIConsole
=
require
(
'
./Actions/IPMIConsole
'
),
path
=
require
(
'
path
'
),
pug
=
require
(
'
pug
'
),
superagent
=
require
(
'
superagent
'
),
{
DOMParser
}
=
require
(
'
xmldom
'
),
{
get
,
forEach
,
throttle
,
has
,
find
,
includes
,
isEmpty
,
toString
}
=
require
(
'
lodash
'
);
bodyParserJson
=
require
(
'
express
'
).
json
,
{
get
,
forEach
,
throttle
,
has
,
find
,
includes
,
set
}
=
require
(
'
lodash
'
);
/**
* @typedef {import('./types').Dimon.Zone} Zone
...
...
@@ -27,6 +24,8 @@ const WS_NORMAL_CLOSURE = 1000;
const
WS_GOING_AWAY
=
1001
;
const
WS_INTERNAL_ERROR
=
1011
;
const
ActionRouters
=
[
IPMIConsole
];
class
DimonServer
{
/**
* @param {Config} config
...
...
@@ -58,10 +57,6 @@ class DimonServer {
throw
new
Error
(
'
WebSocket not supported
'
);
}
const
iKVMTemplate
=
pug
.
compileFile
(
path
.
join
(
__dirname
,
'
..
'
,
'
www/dist/ipmi-console/iKVM.pug
'
),
{
pretty
:
true
});
router
.
ws
(
'
/monitoring
'
,
(
ws
)
=>
{
try
{
/* send menus and current zones */
...
...
@@ -137,71 +132,21 @@ class DimonServer {
ws
.
once
(
'
close
'
,
()
=>
ws
.
removeAllListeners
());
});
router
.
get
(
'
/ipmi-console/:host
'
,
async
(
req
,
res
,
next
)
=>
{
router
.
use
(
'
/action
'
,
bodyParserJson
(),
(
req
,
res
,
next
)
=>
{
try
{
const
action
=
this
.
_getAction
(
/** @type {ActionReq} */
(
req
.
query
));
const
action
=
this
.
_getAction
(
/** @type {ActionReq} */
(
req
.
query
||
req
.
body
));
if
(
!
action
)
{
throw
new
Error
(
'
Action not found
'
);
}
this
.
_checkPermission
(
action
,
get
(
req
.
user
,
[
'
cern_roles
'
]));
// fetch session credentials
const
host
=
req
.
params
.
host
;
const
loginUsr
=
get
(
this
.
credentials
,
[
`ipmi://
${
host
}
`
,
'
user
'
]);
if
(
!
loginUsr
)
{
throw
new
Error
(
`'
${
host
}
' login error: user missing.`
);
}
const
loginPsw
=
get
(
this
.
credentials
,
[
`ipmi://
${
host
}
`
,
'
password
'
]);
if
(
!
loginPsw
)
{
throw
new
Error
(
`'
${
host
}
' login error: password missing.`
);
}
const
agent
=
superagent
.
agent
();
// to save cookies
// login
await
agent
.
post
(
`https://
${
host
}
/cgi/login.cgi`
)
.
disableTLSCerts
()
/* FIXME: update certs and remove this line */
.
send
(
`name=
${
loginUsr
}
&pwd=
${
loginPsw
}
`
);
// check Session ID
const
SID
=
agent
.
jar
.
getCookie
(
'
SID
'
,
{
path
:
'
/
'
,
domain
:
host
,
secure
:
true
,
script
:
false
});
if
(
SID
&&
isEmpty
(
SID
.
value
))
{
throw
new
Error
(
`'
${
host
}
' login error: cannot open a session. `
+
`Please check credentials.`
);
}
// generate the 'iKVM.jnlp' file
const
iKVM
=
await
agent
.
get
(
`https://
${
host
}
/cgi/url_redirect.cgi?url_name=ikvm&url_type=jwsk`
)
.
disableTLSCerts
()
/* FIXME: update certs and remove this line */
.
then
((
/** @type {any} */
res
)
=>
{
const
doc
=
new
DOMParser
().
parseFromString
(
toString
(
res
.
body
));
const
args
=
doc
.
getElementsByTagName
(
'
argument
'
);
return
iKVMTemplate
({
basePath
:
`
${
req
.
protocol
}
://
${
req
.
get
(
'
host
'
)}
/dist/ipmi-console/`
,
host
,
username
:
args
[
1
].
textContent
,
password
:
args
[
2
].
textContent
});
});
res
.
set
(
'
Content-Disposition
'
,
`attachment; filename="iKVM.jnlp"`
)
.
set
(
'
Content-Type
'
,
'
application/x-java-jnlp-file
'
)
.
status
(
200
)
.
send
(
iKVM
);
set
(
req
,
[
'
locals
'
,
'
credentials
'
],
this
.
credentials
);
set
(
req
,
[
'
locals
'
,
'
action
'
],
action
);
return
next
();
}
catch
(
err
)
{
// forward to the server error handler
next
({
status
:
500
,
message
:
err
.
message
});
return
;
return
next
(
err
);
}
});
}
,
...
ActionRouters
);
}
/**
...
...
www/src/components/Actions/Action.d.ts
View file @
bf19d9b1
...
...
@@ -18,5 +18,5 @@ export type ExtendedActionInfo = AppServer.Dimon.ActionInfo &
declare
class
Action
{
getConfig
(
info
?:
ExtendedActionInfo
):
Promise
<
ActionConfig
>
;
runOnServer
():
boolean
;
useWS
():
boolean
;
}
www/src/components/Actions/ActionDialog.vue
View file @
bf19d9b1
...
...
@@ -21,7 +21,7 @@ BaseDialog(ref='dialog' @hidden='onHidden')
|
{{
out
.
data
}}
pre.m-1.h6(v-for='(lnk, lnkIdx) in extLinks')
| Open
a.x-link.mx-2.text-primary(:href='lnk.url' target="_blank"
rel="noopener"
:key='lnkIdx')
a.x-link.mx-2.text-primary(:href='lnk.url' target="_blank" :key='lnkIdx')
|
{{
lnk
.
descr
||
'
external link
'
}}
#[i.fas.fa-external-link-alt]
template(v-slot:footer='{ resolve }')
.d-flex.justify-content-end
...
...
www/src/components/Actions/ActionDialog.vue.js
View file @
bf19d9b1
...
...
@@ -87,7 +87,7 @@ const component = /** @type {V.Constructor<typeof options, Refs>} */(Vue).extend
if
(
config
.
output
)
{
this
.
output
.
push
(
config
.
output
);
}
if
(
config
.
extLink
)
{
this
.
extLinks
.
push
(
config
.
extLink
);
}
this
.
sendActReq
=
this
.
sendActReq
||
Action
.
runOnServer
();
this
.
sendActReq
=
this
.
sendActReq
||
Action
.
useWS
();
}
if
(
isEmpty
(
this
.
warnings
)
&&
(
action
.
allowed
!==
Allowed
.
ALWAYS
))
{
...
...
www/src/components/Actions/BashScript.js
View file @
bf19d9b1
...
...
@@ -9,7 +9,7 @@ class BashScript {
static
async
getConfig
()
{
return
{};
}
// no config
/** @return {boolean} */
static
runOnServer
()
{
return
true
;
}
static
useWS
()
{
return
true
;
}
}
export
default
BashScript
;
www/src/components/Actions/IPMIConsole.js
View file @
bf19d9b1
...
...
@@ -35,13 +35,13 @@ class IPMIConsole {
return
{
extLink
:
{
descr
:
'
Remote Console
'
,
url
:
`
${
currentUrl
()}
/ipmi-console/
${
info
.
host
}
`
+
query
url
:
`
${
currentUrl
()}
/
action/
ipmi-console/
${
info
.
host
}
`
+
query
}
}
}
;
}
/** @return {boolean} */
static
runOnServer
()
{
return
false
;
}
static
useWS
()
{
return
false
;
}
}
export
default
IPMIConsole
;
www/src/components/Actions/OCRollout.js
View file @
bf19d9b1
...
...
@@ -9,7 +9,7 @@ class OCRollout {
static
async
getConfig
()
{
return
{};
}
// no config
/** @return {boolean} */
static
runOnServer
()
{
return
true
;
}
static
useWS
()
{
return
true
;
}
}
export
default
OCRollout
;
www/src/components/Actions/SSHCmd.js
View file @
bf19d9b1
...
...
@@ -9,7 +9,7 @@ class SSHCmd {
static
async
getConfig
()
{
return
{};
}
// no config
/** @return {boolean} */
static
runOnServer
()
{
return
true
;
}
static
useWS
()
{
return
true
;
}
}
export
default
SSHCmd
;
www/src/components/Actions/Systemclt.js
View file @
bf19d9b1
...
...
@@ -9,7 +9,7 @@ class Systemctl {
static
async
getConfig
()
{
return
{};
}
// no config
/** @return {boolean} */
static
runOnServer
()
{
return
true
;
}
static
useWS
()
{
return
true
;
}
}
export
default
Systemctl
;
Write
Preview
Supports
Markdown
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