Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F3942521
salt-config.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
12 KB
Referenced Files
None
Subscribers
None
salt-config.js
View Options
/* -------------------------------------------------------------
Nasqueron infrastructure
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Project: Nasqueron
Author: Sébastien Santoro aka Dereckson
Dependencies: jQuery
Filename: salt-config.js
Licence: CC-BY 4.0, MIT, BSD-2-Clause (multi-licensing)
------------------------------------------------------------- */
/* -------------------------------------------------------------
Table of contents
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
:: Servers list
:: States
:: Code to run when document is ready
*/
const
ServersConfig
=
function
(
container
)
{
/* -------------------------------------------------------------
States
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
const
States
=
function
(
container
,
serverName
,
serverHost
)
{
const
states
=
{
///
/// Constants
///
SALT_BASE_URL
:
"https://devcentral.nasqueron.org/source/operations/browse/main/"
,
SALT_STAGING_URL
:
"https://devcentral.nasqueron.org/source/staging/browse/master/"
,
SALT_DOC_STATES_URL
:
"https://docs.saltproject.io/en/latest/ref/states/all/"
,
///
/// Private properties
///
/**
* A JQuery selector expression to a DOM element to publish to.
*
* @var string
*/
container
:
""
,
server
:
""
,
///
/// Constructor
///
/**
* Initializes an instance of this object.
*
* @param container The DOM element JQuery selector where to write
* @param serverName The name of the server, to display it
* @param serverHost The FQDN of the server, to fetch config data
*/
load
:
function
(
container
,
serverName
,
serverHost
)
{
this
.
container
=
container
;
this
.
server
=
serverName
;
this
.
refreshData
(
serverHost
);
},
///
/// Main methods
///
refreshData
:
function
(
serverHost
)
{
let
url
=
"https://"
+
serverHost
+
"/datasources/infra/all-states.json"
;
$
.
getJSON
(
url
,
function
(
configurationStates
)
{
states
.
refreshUI
(
configurationStates
);
});
},
refreshUI
:
function
(
configurationStates
)
{
$
(
this
.
container
).
html
(
this
.
formatConfig
(
configurationStates
));
$
(
"#config-back-to-server-list"
).
on
(
"click"
,
function
()
{
console
.
log
(
"Back to servers list"
);
new
ServersList
(
container
)
})
},
formatConfig
:
function
(
states
)
{
return
`
<button id="config-back-to-server-list" class="button extra-action">« Back to servers list</button>
<h2 class="config-server">
${
this
.
server
}
</h2>
${
this
.
formatStates
(
states
)
}
`
},
formatState
:
function
(
name
,
state
)
{
let
output
=
'<div class="state">'
output
+=
'<div class="state-name">'
+
name
+
"</div>"
for
(
const
[
key
,
properties
]
of
Object
.
entries
(
state
))
{
if
(
key
.
startsWith
(
"__"
))
{
continue
}
output
+=
`<div class="state-module">
${
this
.
resolveSaltModuleMethod
(
key
,
properties
)
}
</div>`
output
+=
'<div class="state-properties">'
for
(
const
property
of
properties
)
{
if
(
typeof
property
===
"string"
)
{
// Method is already parsed by extractMethod
continue
}
if
(
property
.
order
!==
undefined
)
{
// We're lucky we already receive the states in the
// sorted order, so we can ignore this.
continue
}
output
+=
this
.
dump
(
property
)
}
output
+=
"</div>"
}
output
+=
"</div>"
return
output
},
formatStates
:
function
(
server_states
)
{
let
current_unit
=
""
let
output
=
'<div class="states">'
let
roles_output
=
""
let
roles
=
[]
for
(
const
[
role
,
role_states
]
of
Object
.
entries
(
server_states
))
{
roles
.
push
(
role
)
roles_output
+=
`<div class="config-role">
<h3 id="
${
this
.
makeId
(
role
)
}
" class="config-role-title">
${
role
}
</h3>
<div class="config-role-content">`
if
(
$
.
isEmptyObject
(
role_states
))
{
roles_output
+=
'<p class="config-error">No information gathered for this role. There is probably an error in Salt configuration.</p>'
;
}
for
(
const
[
name
,
individual_state
]
of
Object
.
entries
(
role_states
))
{
// Gets unit from the state source SLS to generate units headings
let
unit
=
individual_state
[
"__sls__"
].
replace
(
role
+
"."
,
""
)
if
(
unit
!==
current_unit
)
{
roles_output
+=
`<h4 class="config-unit">
${
unit
}
</h4>`
current_unit
=
unit
}
roles_output
+=
this
.
formatState
(
name
,
individual_state
)
}
roles_output
+=
"</div></div>"
;
}
roles_output
+=
'</div>'
;
output
+=
`
<div class="config-summary-roles">
<h3 class="config-summary-roles-heading">Roles assigned</h3>
<ul class="config-summary-roles-list">
`
for
(
const
role
of
roles
)
{
output
+=
`
<li class="config-summary-role">
<a href="#
${
this
.
makeId
(
role
)
}
">
${
role
}
</a>
</li>
`
}
output
+=
"</ul></div>"
output
+=
roles_output
;
return
output
;
},
makeId
:
function
(
expression
)
{
return
expression
.
replace
(
"/"
,
"."
)
},
resolveSaltModuleMethod
:
function
(
module
,
properties
)
{
const
method
=
this
.
extractMethod
(
properties
);
const
link
=
`
${
this
.
SALT_DOC_STATES_URL
}
salt.states.
${
module
}
.html#salt.states.
${
module
}
.
${
method
}
`
return
`<a class="salt-link" href="
${
link
}
">
${
module
}
.
${
method
}
</a>`
},
extractMethod
:
function
(
properties
)
{
for
(
const
property
of
properties
)
{
if
(
typeof
property
===
"string"
)
{
return
property
}
}
},
isInStagingRepo
:
url
=>
url
.
startsWith
(
"salt://software/"
)
||
url
.
startsWith
(
"salt://wwwroot/"
),
resolveSaltLink
:
function
(
url
)
{
const
base
=
this
.
isInStagingRepo
(
url
)
?
this
.
SALT_STAGING_URL
:
this
.
SALT_BASE_URL
const
link
=
base
+
url
.
replace
(
"salt://"
,
""
)
return
`<a class="salt-link" href="
${
link
}
">
${
url
}
</a>`
},
// roles/core/rc/files/periodic.conf
dump
:
function
(
data
)
{
if
(
data
===
null
)
{
return
`<span class="null">NULL</span>`
}
if
(
typeof
data
===
"string"
&&
data
.
startsWith
(
"salt://"
))
{
return
this
.
resolveSaltLink
(
data
)
}
if
(
this
.
isScalar
(
data
))
{
return
`<span class="scalar">
${
data
}
</span>`
}
if
(
typeof
data
===
"object"
)
{
if
(
data
.
constructor
.
name
===
"Array"
)
{
return
this
.
dumpArray
(
data
);
}
return
this
.
dumpObject
(
data
);
}
},
dumpArray
:
function
(
values
)
{
let
dumped
=
'<ul class="state-list">'
for
(
const
value
of
values
)
{
dumped
+=
`<li class="state-list-item">
${
this
.
dump
(
value
)
}
</li>`
}
dumped
+=
'</ul>'
return
dumped
},
dumpObject
:
function
(
data
)
{
let
dumped
=
""
for
(
const
[
key
,
value
]
of
Object
.
entries
(
data
))
{
dumped
+=
`
<div class="state-property">
<span class="key">
${
key
}
</span>
<span class="value">
${
this
.
dump
(
value
)
}
</span>
</div>
`
}
return
dumped
},
isScalar
:
value
=>
typeof
value
===
"boolean"
||
typeof
value
===
"number"
||
typeof
value
===
"string"
};
states
.
load
(
container
,
serverName
,
serverHost
)
return
states
;
};
/* -------------------------------------------------------------
Servers list
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
const
ServersList
=
function
(
container
)
{
const
serversList
=
{
///
/// Constants
///
SERVERS_API_URL
:
"https://api.nasqueron.org/infra/servers.json"
,
///
/// Private properties
///
/**
* A JQuery selector expression to a DOM element to publish to.
*
* @var string
*/
container
:
""
,
servers
:
undefined
,
///
/// Constructor
///
/**
* Initializes an instance of this object.
*
* @param container The DOM element JQuery selector where to write
*/
load
:
function
(
container
)
{
this
.
container
=
container
;
this
.
refreshData
();
},
///
/// Data model
///
fetchServers
:
function
()
{
let
that
=
this
$
.
getJSON
(
this
.
SERVERS_API_URL
,
function
(
servers
)
{
that
.
servers
=
servers
that
.
refreshUI
()
})
},
refreshData
:
function
()
{
this
.
fetchServers
();
},
///
/// UI representation
///
refreshUI
:
function
()
{
$
(
this
.
container
).
html
(
this
.
formatData
())
for
(
const
server
of
$
(
".server"
))
{
$
(
server
).
on
(
"click"
,
function
()
{
new
States
(
container
,
server
.
id
,
server
.
dataset
.
hostname
)
})
}
},
formatData
:
function
()
{
let
output
=
'<h2>Servers</h2><ul class="servers">'
;
for
(
const
[
server
,
properties
]
of
Object
.
entries
(
this
.
servers
))
{
if
(
properties
.
configurator
!==
"salt"
)
{
continue
;
}
output
+=
`
<li class="server" id="
${
server
}
" data-hostname="
${
properties
.
hostname
}
">
<span class="server-property server-name">
${
properties
.
name
}
</span>
<span class="server-property server-description">
${
properties
.
description
}
</span>
</li>
`
}
output
+=
"</ul>"
return
output
;
}
};
serversList
.
load
(
container
);
return
serversList
;
};
/* -------------------------------------------------------------
Initialization
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
new
ServersList
(
container
)
}
/* -------------------------------------------------------------
Code to run when document is ready
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
$
(
document
).
ready
(
function
()
{
new
ServersConfig
(
"#config"
);
});
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Dec 26, 16:28 (19 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2315241
Default Alt Text
salt-config.js (12 KB)
Attached To
Mode
rINFRAWWW Nasqueron infrastructure servers website
Attached
Detach File
Event Timeline
Log In to Comment