Merge "Integrating the isogen & doc pull CTL components"

This commit is contained in:
Zuul 2020-06-15 18:24:19 +00:00 committed by Gerrit Code Review
commit 75492296df
16 changed files with 445 additions and 181 deletions

1
go.sum
View File

@ -1019,6 +1019,7 @@ opendev.org/airship/airshipctl v0.0.0-20200501183051-71b06db81924/go.mod h1:ste8
opendev.org/airship/airshipctl v0.0.0-20200518155418-7276dd68d8d0 h1:gMM7Jcb0r9bEa4kYBm9mhDNIjdtLKy3WuA4z/PabpLY=
opendev.org/airship/airshipctl v0.0.0-20200518155418-7276dd68d8d0/go.mod h1:0ywoz1IC0yXQ0XDfcBV/BVeEubkTPPjN7dra8sUrsHs=
opendev.org/airship/airshipctl v0.0.0-20200519134509-98f14aaa9327 h1:wPnsodiekVe1lq/oxbHmk8ZCcJa1xuzPEY+yJG1lMuI=
opendev.org/airship/airshipctl v0.0.0-20200608220007-d31f4f982869 h1:JVshDs4fIvy0Fr8aN3H1xwP9NHedLBEjY+pT9AlHGbw=
opendev.org/airship/go-redfish v0.0.0-20200110185254-3ab47e28bae8/go.mod h1:FEjYcb3bYBWGpQIqtvVM0NrT5eyjlCOCj5JNf4lI+6s=
opendev.org/airship/go-redfish v0.0.0-20200318103738-db034d1d753a h1:4ggAMTwpfu/w3ZXOIJ9tfYF37JIYn+eNCA4O10NduZ0=
opendev.org/airship/go-redfish v0.0.0-20200318103738-db034d1d753a/go.mod h1:FEjYcb3bYBWGpQIqtvVM0NrT5eyjlCOCj5JNf4lI+6s=

View File

@ -99,10 +99,16 @@ const (
SetConfig WsComponentType = "setConfig"
Initialize WsComponentType = "initialize"
Keepalive WsComponentType = "keepalive"
CTLConfig WsComponentType = "config"
Baremetal WsComponentType = "baremetal"
Document WsComponentType = "document"
GetDefaults WsSubComponentType = "getDefaults"
SetContext WsSubComponentType = "context"
SetCluster WsSubComponentType = "cluster"
SetCredential WsSubComponentType = "credential"
GenerateISO WsSubComponentType = "generateISO"
DocPull WsSubComponentType = "docPull"
)
// WsMessage is a request / return structure used for websockets

View File

@ -14,13 +14,22 @@
package ctl
import (
"log"
"bytes"
"text/template"
"opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/pkg/version"
"opendev.org/airship/airshipui/internal/configs"
)
// ctlPage struct is used for templated HTML
type ctlPage struct {
ClusterRows string
ContextRows string
CredentialRows string
Title string
Version string
}
// client provides a library of functions that enable external programs (e.g. Airship UI) to perform airshipctl
// functionality in exactly the same manner as the CLI.
type client struct {
@ -43,21 +52,26 @@ func NewClient() *client {
var c *client = NewClient()
// GetAirshipCTLVersion will kick out what version of airshipctl we're using
func GetAirshipCTLVersion() string {
func getAirshipCTLVersion() string {
return version.Get().GitVersion
}
// GetDefaults will send to the UI the basics of what airshipctl we know about
func GetDefaults(configs.WsMessage) configs.WsMessage {
config, err := getDefaultHTML()
func getHTML(templateFile string, contents ctlPage) (string, error) {
// go templates need an io writer, since we need a string this buffer can be converted
var buff bytes.Buffer
// TODO: make the node path dynamic or setable at compile time
t, err := template.ParseFiles(templateFile)
if err != nil {
config = "Error attempting to get data for AirshipCTL configs: " + err.Error()
log.Println(err)
return "", err
}
return configs.WsMessage{
Type: configs.AirshipCTL,
Component: configs.Info,
HTML: config,
// parse and merge the template
err = template.Must(t, err).Execute(&buff, contents)
if err != nil {
return "", err
}
return buff.String(), nil
}

View File

@ -0,0 +1,68 @@
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package ctl
import (
"fmt"
"opendev.org/airship/airshipctl/pkg/bootstrap/isogen"
"opendev.org/airship/airshipui/internal/configs"
)
// HandleBaremetalRequest will flop between requests so we don't have to have them all mapped as function calls
func HandleBaremetalRequest(request configs.WsMessage) configs.WsMessage {
response := configs.WsMessage{
Type: configs.AirshipCTL,
Component: configs.Baremetal,
SubComponent: request.SubComponent,
}
var err error
var message string
switch request.SubComponent {
case configs.GetDefaults:
response.HTML, err = getBaremetalHTML()
case configs.DocPull:
message, err = c.docPull()
case configs.GenerateISO:
message, err = c.generateIso()
default:
err = fmt.Errorf("Subcomponent %s not found", request.SubComponent)
}
if err != nil {
response.Error = err.Error()
} else {
response.Message = message
}
return response
}
func (c *client) generateIso() (string, error) {
var message string
err := isogen.GenerateBootstrapIso(c.settings)
if err == nil {
message = fmt.Sprintf("Success")
}
return message, err
}
func getBaremetalHTML() (string, error) {
return getHTML("./internal/integrations/ctl/templates/baremetal.html", ctlPage{
Title: "Baremetal",
Version: getAirshipCTLVersion(),
})
}

View File

@ -14,134 +14,25 @@
package ctl
import (
"bytes"
"fmt"
"text/template"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipui/internal/configs"
)
// configPage struct is used for templated HTML
type configPage struct {
ClusterRows string
ContextRows string
CredentialRows string
Title string
Version string
}
// GetCluster gets cluster information from the airshipctl config
func (c *client) GetCluster() []*config.Cluster {
return c.settings.Config.GetClusters()
}
// getClusterTableRows turns an array of cluster into html table rows
func getClusterTableRows() string {
info := c.GetCluster()
var rows string
for _, config := range info {
// TODO: all rows are editable, probably shouldn't be
rows += "<tr><td><div contenteditable=true>" +
config.Bootstrap + "</div></td><td><div contenteditable=true>" +
config.NameInKubeconf + "</div></td><td><div contenteditable=true>" +
config.ManagementConfiguration + "</div></td><td>" +
config.KubeCluster().LocationOfOrigin + "</td><td><div contenteditable=true>" +
config.KubeCluster().Server + "</div></td><td><div contenteditable=true>" +
config.KubeCluster().CertificateAuthority + "</div></td><td>" +
"<button type=\"button\" class=\"btn btn-success\" onclick=\"saveConfig(this)\">Save</button></td></tr>"
}
return rows
}
// GetContext gets cluster information from the airshipctl config
func (c *client) GetContext() []*config.Context {
return c.settings.Config.GetContexts()
}
// getContextTableRows turns an array of contexts into html table rows
func getContextTableRows() string {
info := c.GetContext()
var rows string
for _, context := range info {
// TODO: all rows are editable, probably shouldn't be
rows += "<tr><td><div contenteditable=true>" +
context.NameInKubeconf + "</div></td><td><div contenteditable=true>" +
context.Manifest + "</div></td><td>" +
context.KubeContext().LocationOfOrigin + "</td><td><div contenteditable=true>" +
context.KubeContext().Cluster + "</div></td><td><div contenteditable=true>" +
context.KubeContext().AuthInfo + "</div></td><td>" +
"<button type=\"button\" class=\"btn btn-success\" onclick=\"saveConfig(this)\">Save</button></td></tr>"
}
return rows
}
// GetCredential gets user credentials from the airshipctl config
func (c *client) GetCredential() []*config.AuthInfo {
authinfo, err := c.settings.Config.GetAuthInfos()
if err != nil {
return []*config.AuthInfo{}
}
return authinfo
}
// getContextTableRows turns an array of contexts into html table rows
func getCredentialTableRows() string {
info := c.GetCredential()
var rows string
for _, credential := range info {
// TODO: all rows are editable, probably shouldn't be
rows += "<tr><td>" +
credential.KubeAuthInfo().LocationOfOrigin + "</td><td><div contenteditable=true>" +
credential.KubeAuthInfo().Username + "</div></td><td>" +
"<button type=\"button\" class=\"btn btn-success\" onclick=\"saveConfig(this)\">Save</button></td></tr>"
}
return rows
}
func getDefaultHTML() (string, error) {
// go templates need an io writer, since we need a string this buffer can be converted
var buff bytes.Buffer
// TODO: make the node path dynamic or setable at compile time
t, err := template.ParseFiles("./internal/integrations/ctl/templates/config.html")
if err != nil {
return "", err
}
// add contents to the page
p := configPage{
ClusterRows: getClusterTableRows(),
ContextRows: getContextTableRows(),
CredentialRows: getCredentialTableRows(),
Title: "Config",
Version: GetAirshipCTLVersion(),
}
// parse and merge the template
err = template.Must(t, err).Execute(&buff, p)
if err != nil {
return "", err
}
return buff.String(), nil
}
// SetConfig will flop between requests so we don't have to have them all mapped as function calls
func SetConfig(request configs.WsMessage) configs.WsMessage {
// HandleConfigRequest will flop between requests so we don't have to have them all mapped as function calls
func HandleConfigRequest(request configs.WsMessage) configs.WsMessage {
response := configs.WsMessage{
Type: configs.AirshipCTL,
Component: configs.SetConfig,
Type: configs.AirshipCTL,
Component: configs.CTLConfig,
SubComponent: request.SubComponent,
}
var err error
var message string
switch request.SubComponent {
case configs.GetDefaults:
response.HTML, err = getConfigHTML()
case configs.SetContext:
message, err = setContext(request)
case configs.SetCluster:
@ -161,6 +52,88 @@ func SetConfig(request configs.WsMessage) configs.WsMessage {
return response
}
// GetCluster gets cluster information from the airshipctl config
func (c *client) getCluster() []*config.Cluster {
return c.settings.Config.GetClusters()
}
// getClusterTableRows turns an array of cluster into html table rows
func getClusterTableRows() string {
info := c.getCluster()
var rows string
for _, config := range info {
// TODO: all rows are editable, probably shouldn't be
rows += "<tr><td><div contenteditable=true>" +
config.Bootstrap + "</div></td><td><div contenteditable=true>" +
config.NameInKubeconf + "</div></td><td><div contenteditable=true>" +
config.ManagementConfiguration + "</div></td><td>" +
config.KubeCluster().LocationOfOrigin + "</td><td><div contenteditable=true>" +
config.KubeCluster().Server + "</div></td><td><div contenteditable=true>" +
config.KubeCluster().CertificateAuthority + "</div></td><td>" +
"<button type=\"button\" class=\"btn btn-success\" onclick=\"saveConfig(this)\">Save</button></td></tr>"
}
return rows
}
// GetContext gets cluster information from the airshipctl config
func (c *client) getContext() []*config.Context {
return c.settings.Config.GetContexts()
}
// getContextTableRows turns an array of contexts into html table rows
func getContextTableRows() string {
info := c.getContext()
var rows string
for _, context := range info {
// TODO: all rows are editable, probably shouldn't be
rows += "<tr><td><div contenteditable=true>" +
context.NameInKubeconf + "</div></td><td><div contenteditable=true>" +
context.Manifest + "</div></td><td>" +
context.KubeContext().LocationOfOrigin + "</td><td><div contenteditable=true>" +
context.KubeContext().Cluster + "</div></td><td><div contenteditable=true>" +
context.KubeContext().AuthInfo + "</div></td><td>" +
"<button type=\"button\" class=\"btn btn-success\" onclick=\"saveConfig(this)\">Save</button></td></tr>"
}
return rows
}
// GetCredential gets user credentials from the airshipctl config
func (c *client) getCredential() []*config.AuthInfo {
authinfo, err := c.settings.Config.GetAuthInfos()
if err != nil {
return []*config.AuthInfo{}
}
return authinfo
}
// getContextTableRows turns an array of contexts into html table rows
func getCredentialTableRows() string {
info := c.getCredential()
var rows string
for _, credential := range info {
// TODO: all rows are editable, probably shouldn't be
rows += "<tr><td>" +
credential.KubeAuthInfo().LocationOfOrigin + "</td><td><div contenteditable=true>" +
credential.KubeAuthInfo().Username + "</div></td><td>" +
"<button type=\"button\" class=\"btn btn-success\" onclick=\"saveConfig(this)\">Save</button></td></tr>"
}
return rows
}
func getConfigHTML() (string, error) {
return getHTML("./internal/integrations/ctl/templates/config.html", ctlPage{
ClusterRows: getClusterTableRows(),
ContextRows: getContextTableRows(),
CredentialRows: getCredentialTableRows(),
Title: "Config",
Version: getAirshipCTLVersion(),
})
}
// SetCluster will take ui cluster info, translate them into CTL commands and send a response back to the UI
func setCluster(request configs.WsMessage) (string, error) {
modified, err := config.RunSetCluster(&request.ClusterOptions, c.settings.Config, true)

View File

@ -0,0 +1,67 @@
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package ctl
import (
"fmt"
"opendev.org/airship/airshipctl/pkg/document/pull"
"opendev.org/airship/airshipui/internal/configs"
)
// HandleBaremetalRequest will flop between requests so we don't have to have them all mapped as function calls
func HandleDocumentRequest(request configs.WsMessage) configs.WsMessage {
response := configs.WsMessage{
Type: configs.AirshipCTL,
Component: configs.Document,
SubComponent: request.SubComponent,
}
var err error
var message string
switch request.SubComponent {
case configs.GetDefaults:
response.HTML, err = getDocumentHTML()
case configs.DocPull:
message, err = c.docPull()
default:
err = fmt.Errorf("Subcomponent %s not found", request.SubComponent)
}
if err != nil {
response.Error = err.Error()
} else {
response.Message = message
}
return response
}
func (c *client) docPull() (string, error) {
var message string
settings := pull.Settings{AirshipCTLSettings: c.settings}
err := settings.Pull()
if err == nil {
message = fmt.Sprintf("Success")
}
return message, err
}
func getDocumentHTML() (string, error) {
return getHTML("./internal/integrations/ctl/templates/document.html", ctlPage{
Title: "Document",
Version: getAirshipCTLVersion(),
})
}

View File

@ -0,0 +1,5 @@
<h1>Airship CTL {{.Title}} Base Information</h1>
<p>Version: {{.Version}}</p>
<h2>Generate ISO</h2>
<button type="button" class="btn btn-info" id="GenIsoBtn" onclick="baremetalAction(this)" style="width: 150px;">Generate ISO</button>

View File

@ -21,7 +21,7 @@
{{.ClusterRows}}
</tbody>
</table>
<button type="button" class="btn btn-info" onclick="addClusterModal()">Add</button>
<button type="button" class="btn btn-info" id="ClusterBtn" onclick="addConfigModal(this)">Add</button>
</p>
</div>
@ -77,7 +77,7 @@
</tbody>
</table>
</p>
<button type="button" class="btn btn-info" onclick="addContextModal()">Add</button>
<button type="button" class="btn btn-info" id="ContextBtn" onclick="addConfigModal(this)">Add</button>
</div>
<!-- This is used by the context add modal and is injected into the DOM but not displayed except by the popup -->
@ -130,7 +130,7 @@
{{.CredentialRows}}
</tbody>
</table>
<button type="button" class="btn btn-info" onclick="addCredentialModal()">Add</button>
<button type="button" class="btn btn-info" id="CredentialBtn" onclick="addConfigModal(this)">Add</button>
</p>
</div>

View File

@ -0,0 +1,5 @@
<h1>Airship CTL {{.Title}} Base Information</h1>
<p>Version: {{.Version}}</p>
<h2>Document Pull</h2>
<button type="button" class="btn btn-info" id="DocPullBtn" onclick="documentAction(this)" style="width: 150px;">Document Pull</button>

View File

@ -39,8 +39,9 @@ var functionMap = map[configs.WsRequestType]map[configs.WsComponentType]func(con
configs.Initialize: clientInit,
},
configs.AirshipCTL: {
configs.Info: ctl.GetDefaults,
configs.SetConfig: ctl.SetConfig,
configs.CTLConfig: ctl.HandleConfigRequest,
configs.Baremetal: ctl.HandleBaremetalRequest,
configs.Document: ctl.HandleDocumentRequest,
},
}

View File

@ -12,7 +12,7 @@
<meta name="theme-color" content="#ffffff">
<script src="js/websocket.js"></script>
<script src="js/common.js"></script>
<script src="js/airshipctl.js"></script>
<script src="js/airshipctl/airshipctl.js"></script>
<script src="js/coreui-3.2.0/vendors/@coreui/coreui/js/coreui.bundle.min.js"></script>
<link href="js/coreui-3.2.0/css/style.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
@ -37,7 +37,9 @@
<use xlink:href="js/coreui-3.2.0/vendors/@coreui/icons/svg/free.svg#cil-airplane-mode"></use>
</svg> Airship</a>
<ul id="AirshipDropdown" class="c-sidebar-nav-dropdown-items">
<li><a class="c-sidebar-nav-link" onclick="ctlGetConfig()">Config</a></span></li>
<li><a class="c-sidebar-nav-link" id="LiBaremetal" onclick="ctlGetDefaults(this)">Baremetal</a></span></li>
<li><a class="c-sidebar-nav-link" id="LiConfig" onclick="ctlGetDefaults(this)">Config</a></span></li>
<li><a class="c-sidebar-nav-link" id="LiDocument" onclick="ctlGetDefaults(this)">Document</a></span></li>
</ul>
</li>
<li class="c-sidebar-nav-item c-sidebar-nav-dropdown"><a

66
web/js/airshipctl/airshipctl.js Executable file
View File

@ -0,0 +1,66 @@
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Splitting up scripts into sub components to keep it the functions in logical divisions
var includes = ["js/airshipctl/config.js","js/airshipctl/baremetal.js","js/airshipctl/document.js"];
// append CTL scripts to the page, this is an independent content loaded listener from the one in common.js
document.addEventListener("DOMContentLoaded", () => {
for (let include of includes) {
var script = document.createElement("script");
script.src = include;
document.head.appendChild(script);
}
}, false)
// Displays the alerts from the backend
function handleCTLResponse(json) { // eslint-disable-line no-unused-vars
if (json.hasOwnProperty("error")) {
showDismissableAlert("danger", json["error"], false);
} else {
showDismissableAlert("info", json["message"], false);
}
}
function ctlGetDefaults(element) { // eslint-disable-line no-unused-vars
let id = String(element.id);
var json = { "type": "airshipctl", "subComponent": "getDefaults" };
switch(id) {
case "LiBaremetal": json = Object.assign(json, { "component": "baremetal" }); break;
case "LiConfig": json = Object.assign(json, { "component": "config" }); break;
case "LiDocument": json = Object.assign(json, { "component": "document" }); break;
}
ws.send(JSON.stringify(json));
}
function displayCTLInfo(json) { // eslint-disable-line no-unused-vars
if (json.hasOwnProperty("html")) {
document.getElementById("DashView").style.display = "none";
let div = document.getElementById("ContentDiv");
div.style.display = "";
div.innerHTML = json["html"];
} else {
if (json.hasOwnProperty("error")) {
showDismissableAlert("danger", json["error"], false);
}
}
}
function buttonHelper(id,text,disabled) { // eslint-disable-line no-unused-vars
let button = document.getElementById(id);
button.innerText = text;
button.disabled = disabled;
}

34
web/js/airshipctl/baremetal.js Executable file
View File

@ -0,0 +1,34 @@
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
function baremetalAction(element) { // eslint-disable-line no-unused-vars
let elementId = element.id;
// change text & disable the button while the process happens
buttonHelper(elementId, "In Progress", true);
var json = { "type": "airshipctl", "component": "baremetal" };
switch(elementId) {
case "GenIsoBtn": json = Object.assign(json, { "subComponent": "generateISO" }); break;
}
ws.send(JSON.stringify(json));
}
function ctlParseBaremetal(json) { // eslint-disable-line no-unused-vars
switch(json["subComponent"]) {
case "getDefaults": displayCTLInfo(json); break;
case "generateISO": buttonHelper("GenIsoBtn", "Generate ISO",false); handleCTLResponse(json); break;
default: handleCTLResponse(json)
}
}

View File

@ -13,39 +13,26 @@
*/
function ctlGetConfig() { // eslint-disable-line no-unused-vars
console.log("Requesting airshipctl config info");
var json = { "type": "airshipctl", "component": "info" };
var json = { "type": "airshipctl", "component": "config", "subComponent": "getDefaults" };
ws.send(JSON.stringify(json));
}
function ctlParseConfig(json) { // eslint-disable-line no-unused-vars
switch(json["component"]) {
case "info": displayInfo(json); break;
default: handleCtlResponse(json);
switch(json["subComponent"]) {
case "getDefaults": displayConfigInfo(json); break;
default: handleCTLResponse(json);
}
}
function displayInfo(json) {
document.getElementById("DashView").style.display = "none";
let div = document.getElementById("ContentDiv");
div.style.display = "";
div.innerHTML = json["html"];
function displayConfigInfo(json) {
displayCTLInfo(json);
enableAccordion();
}
function handleCtlResponse(json) {
if (json.hasOwnProperty("error")) {
showDismissableAlert("danger", json["error"], true);
} else {
showDismissableAlert("info", json["message"], true);
}
}
function saveConfig(element) { // eslint-disable-line no-unused-vars
var json = {
"type": "airshipctl",
"component": "setConfig",
"component": "config",
};
tableID = getTableId(element);
@ -59,11 +46,12 @@ function saveConfig(element) { // eslint-disable-line no-unused-vars
case "CredentialTable": json = Object.assign(json, saveCredential(element)); break;
case "CredentialAddTable": json = Object.assign(json, addCredential(element)); break;
}
ws.send(JSON.stringify(json));
break;
}
}
console.log("Save Config Request: ", json);
ws.send(JSON.stringify(json));
}
function addCluster(row) {
@ -124,8 +112,8 @@ function addCredential(row) {
};
}
function saveCredential(row) {
return {
function saveCredential(row) {
return {
"subComponent": "credential",
"authInfoOptions": {
"Name": row.cells[0].textContent,
@ -148,30 +136,20 @@ function saveConfigDialog(element) { // eslint-disable-line no-unused-vars
closeDialog(element);
}
// This will use the cluster modal described in the pagelet that is sent via the websocket from the backend
function addClusterModal() { // eslint-disable-line no-unused-vars
let dialog = document.createElement("DIALOG");
document.body.appendChild(dialog);
dialog.setAttribute("id", "AddCluster");
dialog.innerHTML = document.getElementById("ClusterModalTemplate").innerHTML;
dialog.showModal();
}
// This will use the modal described in the pagelet that is sent via the websocket from the backend
function addConfigModal(element) { // eslint-disable-line no-unused-vars
let elementId = element.id;
var id, template;
switch(elementId) {
case "ClusterBtn": id = "AddCluster"; template = "ClusterModalTemplate"; break;
case "ContextBtn": id = "AddContext"; template = "ContextModalTemplate"; break;
case "CredentialBtn": id = "AddCredential"; template = "CredentialModalTemplate"; break;
}
// This will use the context modal described in the pagelet that is sent via the websocket from the backend
function addContextModal() { // eslint-disable-line no-unused-vars
let dialog = document.createElement("DIALOG");
document.body.appendChild(dialog);
dialog.setAttribute("id", "AddContext");
dialog.innerHTML = document.getElementById("ContextModalTemplate").innerHTML;
dialog.showModal();
}
// This will use the context modal described in the pagelet that is sent via the websocket from the backend
function addCredentialModal() { // eslint-disable-line no-unused-vars
let dialog = document.createElement("DIALOG");
document.body.appendChild(dialog);
dialog.setAttribute("id", "AddCredential");
dialog.innerHTML = document.getElementById("CredentialModalTemplate").innerHTML;
dialog.setAttribute("id", id);
dialog.innerHTML = document.getElementById(template).innerHTML;
dialog.showModal();
}

34
web/js/airshipctl/document.js Executable file
View File

@ -0,0 +1,34 @@
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
function documentAction(element) { // eslint-disable-line no-unused-vars
let elementId = element.id;
// change text & disable the button while the process happens
buttonHelper(elementId, "In Progress", true);
var json = { "type": "airshipctl", "component": "document" };
switch(elementId) {
case "DocPullBtn": Object.assign(json, { "subComponent": "docPull" }); break;
}
ws.send(JSON.stringify(json));
}
function ctlParseDocument(json) { // eslint-disable-line no-unused-vars
switch(json["subComponent"]) {
case "getDefaults": displayCTLInfo(json); break;
case "docPull": buttonHelper("DocPullBtn", "Document Pull",false); handleCTLResponse(json); break;
default: handleCTLResponse(json)
}
}

View File

@ -62,7 +62,7 @@ function handleMessages(message) {
// create and dispatch an event based on the data received
switch(json["type"]) {
case "alert": showDismissableAlert(json["component"], json["message"], json["fade"]); break;
case "airshipctl": ctlParseConfig(json); break;
case "airshipctl": handleCTLMessages(json); break;
case "electron": hanldleElectronMessages(json); break;
default: console.log("Received message: " + json["type"]); break;
}
@ -87,6 +87,16 @@ function hanldleElectronMessages(json) {
}
}
// helper function for the airshiptctl interactions
function handleCTLMessages(json) {
switch(json["component"]) {
case "config": ctlParseConfig(json); break;
case "baremetal": ctlParseBaremetal(json); break;
case "document": ctlParseDocument(json); break;
default: console.log("Received message: " + json); break;
}
}
function open() {
console.log("Websocket established");
var json = { "type": "electron", "component": "initialize" };