integrate the CTL cluster components with the UI
This integrates the cluster functions: Init Move Status, though status is in an error state in CTL Move and init have been deprecated and the UI has been updated Currently in need of a CTL bug fix for status: https://github.com/airshipit/airshipctl/issues/370 Change-Id: I0a85c3fa4c223a7c03d76fc37918f97e0f87e891
This commit is contained in:
parent
fde880397c
commit
63653daf89
44
client/src/app/ctl/cluster/cluster.component.css
Executable file
44
client/src/app/ctl/cluster/cluster.component.css
Executable file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
# 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
|
||||
#
|
||||
# http://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.
|
||||
*/
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mat-form-field {
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
th.mat-sort-header-sorted {
|
||||
color: black;
|
||||
}
|
||||
|
||||
/* add border & center the table */
|
||||
.clusterBorder {
|
||||
border-spacing: 10px;
|
||||
border:1px gray solid;
|
||||
border-radius: 5px;
|
||||
align-self: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.example-spacer {
|
||||
flex: 1 1 auto;
|
||||
}
|
@ -1 +1,52 @@
|
||||
<h1>Cluster component</h1>
|
||||
<h1>Airship Cluster Operations</h1>
|
||||
|
||||
<div class="container">
|
||||
<h2>Cluster Init</h2>
|
||||
<table class="clusterBorder">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Deprecated:</b>
|
||||
</td>
|
||||
<td>
|
||||
<mat-icon color="primary" svgIcon="error_outline"></mat-icon>
|
||||
</td>
|
||||
<td>
|
||||
Functionality has moved to phases
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2>Cluster Move</h2>
|
||||
<table class="clusterBorder">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Deprecated:</b>
|
||||
</td>
|
||||
<td>
|
||||
<mat-icon color="primary" svgIcon="error_outline"></mat-icon>
|
||||
</td>
|
||||
<td>
|
||||
Functionality has moved to phases
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2>Cluster Status</h2>
|
||||
<table class="clusterBorder">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<button type="submit" id="statusButton" disabled>Status</button>
|
||||
</td>
|
||||
<td>
|
||||
<mat-icon color="primary" svgIcon="error_outline"></mat-icon>
|
||||
</td>
|
||||
<td>
|
||||
Status is not currently operable see: https://github.com/airshipit/airshipctl/issues/370
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
@ -15,6 +15,9 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ClusterComponent } from './cluster.component';
|
||||
import { ToastrModule } from 'ngx-toastr';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
|
||||
|
||||
describe('ClusterComponent', () => {
|
||||
let component: ClusterComponent;
|
||||
@ -23,6 +26,8 @@ describe('ClusterComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
MatIconModule,
|
||||
HttpClientModule,
|
||||
ToastrModule.forRoot()
|
||||
],
|
||||
declarations: [
|
||||
|
@ -19,8 +19,9 @@ import { Log } from '../../../services/log/log.service';
|
||||
import { LogMessage } from '../../../services/log/log-message';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bare-metal',
|
||||
selector: 'app-cluster',
|
||||
templateUrl: './cluster.component.html',
|
||||
styleUrls: ['./cluster.component.css']
|
||||
})
|
||||
|
||||
export class ClusterComponent implements WSReceiver {
|
||||
@ -37,8 +38,11 @@ export class ClusterComponent implements WSReceiver {
|
||||
if (message.hasOwnProperty('error')) {
|
||||
this.websocketService.printIfToast(message);
|
||||
} else {
|
||||
// TODO (aschiefe): determine what should be notifications and what should be 86ed
|
||||
Log.Debug(new LogMessage('Message received in cluster', this.className, message));
|
||||
switch (message.subComponent) {
|
||||
default:
|
||||
Log.Error(new LogMessage('Cluster message sub component not handled', this.className, message));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,13 +14,16 @@
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ClusterComponent } from './cluster.component';
|
||||
import { ToastrModule } from 'ngx-toastr';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
MatIconModule,
|
||||
ToastrModule.forRoot()
|
||||
],
|
||||
declarations: [
|
||||
ClusterComponent
|
||||
],
|
||||
providers: []
|
||||
]
|
||||
})
|
||||
export class ClusterModule { }
|
||||
|
@ -17,6 +17,7 @@ import { RouterModule } from '@angular/router';
|
||||
import { CtlComponent } from './ctl.component';
|
||||
import { DocumentModule } from './document/document.module';
|
||||
import { BaremetalModule } from './baremetal/baremetal.module';
|
||||
import { ClusterModule } from './cluster/cluster.module';
|
||||
import { CtlRoutingModule } from './ctl-routing.module';
|
||||
import { PhaseModule } from './phase/phase.module';
|
||||
import { SecretModule } from './secret/secret.module';
|
||||
@ -24,7 +25,7 @@ import { SecretModule } from './secret/secret.module';
|
||||
@NgModule({
|
||||
imports: [
|
||||
CtlRoutingModule,
|
||||
|
||||
ClusterModule,
|
||||
RouterModule,
|
||||
DocumentModule,
|
||||
BaremetalModule,
|
||||
|
1
client/src/assets/icons/error_outline.svg
Executable file
1
client/src/assets/icons/error_outline.svg
Executable file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/></svg>
|
After Width: | Height: | Size: 307 B |
@ -22,6 +22,7 @@ export enum Icons {
|
||||
launch = 'launch',
|
||||
text_snippet = 'text_snippet',
|
||||
error = 'error',
|
||||
error_outline = 'error_outline',
|
||||
open_in_new = 'open_in_new',
|
||||
filter = 'filter',
|
||||
security = 'security',
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"opendev.org/airship/airshipctl/pkg/log"
|
||||
"opendev.org/airship/airshipui/pkg/configs"
|
||||
uiLog "opendev.org/airship/airshipui/pkg/log"
|
||||
"opendev.org/airship/airshipui/pkg/statistics"
|
||||
"opendev.org/airship/airshipui/pkg/webservice"
|
||||
)
|
||||
|
||||
@ -123,3 +124,15 @@ func (cw *LogInterceptor) Write(data []byte) (n int, err error) {
|
||||
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
// errorHelper formats & sends errors for the ctl components
|
||||
func errorHelper(err error, transaction *statistics.Transaction, response configs.WsMessage) {
|
||||
uiLog.Error(err)
|
||||
e := err.Error()
|
||||
response.Error = &e
|
||||
transaction.Complete(false)
|
||||
err = webservice.WebSocketSend(response)
|
||||
if err != nil {
|
||||
uiLog.Error(err)
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ type phaseInfo struct {
|
||||
ClusterName string `json:"clusterName,omitempty"`
|
||||
}
|
||||
|
||||
type defaultData struct {
|
||||
type baremetalData struct {
|
||||
Nodes []nodeInfo `json:"nodes,omitempty"`
|
||||
Phases []phaseInfo `json:"phases,omitempty"`
|
||||
}
|
||||
@ -66,7 +66,7 @@ func HandleBaremetalRequest(user *string, request configs.WsMessage) configs.WsM
|
||||
|
||||
switch subComponent {
|
||||
case configs.GetDefaults:
|
||||
response.Data, err = getDefaults(request)
|
||||
response.Data, err = getBaremetalDefaults(request)
|
||||
case configs.EjectMedia:
|
||||
err = doAction(user, request)
|
||||
case configs.PowerOff:
|
||||
@ -93,7 +93,7 @@ func HandleBaremetalRequest(user *string, request configs.WsMessage) configs.WsM
|
||||
return response
|
||||
}
|
||||
|
||||
func getDefaults(request configs.WsMessage) (defaultData, error) {
|
||||
func getBaremetalDefaults(request configs.WsMessage) (baremetalData, error) {
|
||||
nodeInfo, err := getNodeInfo(request)
|
||||
phaseInfo, err2 := getPhaseInfo()
|
||||
|
||||
@ -103,7 +103,7 @@ func getDefaults(request configs.WsMessage) (defaultData, error) {
|
||||
err = err2
|
||||
}
|
||||
|
||||
return defaultData{
|
||||
return baremetalData{
|
||||
Nodes: nodeInfo,
|
||||
Phases: phaseInfo,
|
||||
}, err
|
||||
@ -189,7 +189,7 @@ func actionHelper(user *string, target string, phase string, request configs.WsM
|
||||
response := configs.WsMessage{
|
||||
Type: configs.CTL,
|
||||
Component: configs.Baremetal,
|
||||
SubComponent: configs.EjectMedia,
|
||||
SubComponent: request.SubComponent,
|
||||
SessionID: request.SessionID,
|
||||
ActionType: request.ActionType,
|
||||
Target: &target,
|
||||
@ -200,14 +200,7 @@ func actionHelper(user *string, target string, phase string, request configs.WsM
|
||||
|
||||
client, err := NewClient(AirshipConfigPath, KubeConfigPath, response)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
e := err.Error()
|
||||
response.Error = &e
|
||||
transaction.Complete(false)
|
||||
err = webservice.WebSocketSend(response)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
errorHelper(err, transaction, response)
|
||||
return
|
||||
}
|
||||
|
||||
@ -219,14 +212,7 @@ func actionHelper(user *string, target string, phase string, request configs.WsM
|
||||
}
|
||||
m, err := remote.NewManager(client.Config, phase, selectors...)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
e := err.Error()
|
||||
response.Error = &e
|
||||
transaction.Complete(false)
|
||||
err = webservice.WebSocketSend(response)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
errorHelper(err, transaction, response)
|
||||
return
|
||||
}
|
||||
|
||||
@ -256,14 +242,7 @@ func actionHelper(user *string, target string, phase string, request configs.WsM
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
e := err.Error()
|
||||
response.Error = &e
|
||||
transaction.Complete(false)
|
||||
err = webservice.WebSocketSend(response)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
errorHelper(err, transaction, response)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
func HandleClusterRequest(user *string, request configs.WsMessage) configs.WsMessage {
|
||||
response := configs.WsMessage{
|
||||
Type: configs.CTL,
|
||||
Component: configs.Baremetal,
|
||||
Component: configs.Cluster,
|
||||
SubComponent: request.SubComponent,
|
||||
}
|
||||
|
||||
@ -34,10 +34,12 @@ func HandleClusterRequest(user *string, request configs.WsMessage) configs.WsMes
|
||||
|
||||
subComponent := request.SubComponent
|
||||
switch subComponent {
|
||||
case configs.GetDefaults:
|
||||
err = fmt.Errorf("Subcomponent %s deprecated", request.SubComponent)
|
||||
case configs.Init:
|
||||
err = fmt.Errorf("Subcomponent %s not implemented", request.SubComponent)
|
||||
err = fmt.Errorf("Subcomponent %s deprecated", request.SubComponent)
|
||||
case configs.Move:
|
||||
err = fmt.Errorf("Subcomponent %s not implemented", request.SubComponent)
|
||||
err = fmt.Errorf("Subcomponent %s deprecated", request.SubComponent)
|
||||
case configs.Status:
|
||||
err = fmt.Errorf("Subcomponent %s not implemented", request.SubComponent)
|
||||
default:
|
||||
|
Loading…
x
Reference in New Issue
Block a user