Add config integration to airshipui
Integrates airshipctl's config functionality with Airship UI to allow users to view and set airship configuration settings. Known issues: - Manifests currently only shows the primary (phase) repo. We'll probably need a separate repo sub-component to allow for showing / editing multiple repos - There are some boolean values which once set, cannot be unset using airshipctl's setters. We may need to write custom setters to set the Config struct values directly - It's possible to make edits to the config file that render the config invalid, so the CTL client cannot be initialized for subsequent edits. We'll probably want to make a copy of the original config, test the changes by initializing a new client, and only persist the changes if valid. - Lots and lots of cosmetic work remains to make the output more readable and easier to manage Change-Id: Ib29f3f6cf3e420b6e0e2cdc6afddd48c7e403137
This commit is contained in:
parent
afb291a868
commit
fab7bd9ef5
@ -0,0 +1,17 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
.grey-icon {
|
||||
color: grey;
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<mat-card class="context-card">
|
||||
<mat-card-header>
|
||||
<mat-card-title>
|
||||
<button mat-icon-button (click)="toggleLock()">
|
||||
<mat-icon *ngIf="locked" class="grey-icon" svgIcon="lock"></mat-icon>
|
||||
<mat-icon *ngIf="!locked" class="grey-icon" svgIcon="lock_open"></mat-icon>
|
||||
</button>{{context.name}}
|
||||
<button mat-raised-button (click)="useContext(context.name)">Use Context</button>
|
||||
</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<p>ContextKubeconf:
|
||||
<mat-form-field appearance="fill">
|
||||
<input [formControl]="contextKubeconf" matInput>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>Manifest:
|
||||
<mat-form-field appearance="fill">
|
||||
<input [formControl]="manifest" matInput>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>EncryptionConfig:
|
||||
<mat-form-field appearance="fill">
|
||||
<input [formControl]="encryptionConfig" matInput>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>ManagementConfiguration:
|
||||
<mat-form-field appearance="fill">
|
||||
<input [formControl]="managementConfiguration" matInput>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button mat-raised-button [disabled]="locked" (click)="setContext()" color="primary">Set</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ToastrModule } from 'ngx-toastr';
|
||||
import { Context } from '../config.models';
|
||||
|
||||
import { ConfigContextComponent } from './config-context.component';
|
||||
|
||||
describe('ConfigContextComponent', () => {
|
||||
let component: ConfigContextComponent;
|
||||
let fixture: ComponentFixture<ConfigContextComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ConfigContextComponent ],
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
MatCardModule,
|
||||
FormsModule,
|
||||
MatInputModule,
|
||||
MatIconModule,
|
||||
MatCheckboxModule,
|
||||
MatButtonModule,
|
||||
ReactiveFormsModule,
|
||||
ToastrModule.forRoot()
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ConfigContextComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
component.context = new Context();
|
||||
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { Context, ContextOptions } from '../config.models';
|
||||
import { WebsocketService } from '../../../../services/websocket/websocket.service';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { WebsocketMessage } from 'src/services/websocket/websocket.models';
|
||||
|
||||
@Component({
|
||||
selector: 'app-config-context',
|
||||
templateUrl: './config-context.component.html',
|
||||
styleUrls: ['./config-context.component.css']
|
||||
})
|
||||
export class ConfigContextComponent implements OnInit {
|
||||
@Input() context: Context;
|
||||
type = 'ctl';
|
||||
component = 'config';
|
||||
|
||||
locked = true;
|
||||
|
||||
name = new FormControl({value: '', disabled: true});
|
||||
contextKubeconf = new FormControl({value: '', disabled: true});
|
||||
manifest = new FormControl({value: '', disabled: true});
|
||||
managementConfiguration = new FormControl({value: '', disabled: true});
|
||||
encryptionConfig = new FormControl({value: '', disabled: true});
|
||||
|
||||
controlsArray = [this.name, this.contextKubeconf, this.manifest, this.managementConfiguration, this.encryptionConfig];
|
||||
|
||||
constructor(private websocketService: WebsocketService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.name.setValue(this.context.name);
|
||||
this.contextKubeconf.setValue(this.context.contextKubeconf);
|
||||
this.manifest.setValue(this.context.manifest);
|
||||
this.encryptionConfig.setValue(this.context.encryptionConfig);
|
||||
this.managementConfiguration.setValue(this.context.managementConfiguration);
|
||||
}
|
||||
|
||||
toggleLock(): void {
|
||||
for (const control of this.controlsArray) {
|
||||
if (this.locked) {
|
||||
control.enable();
|
||||
} else {
|
||||
control.disable();
|
||||
}
|
||||
}
|
||||
|
||||
this.locked = !this.locked;
|
||||
}
|
||||
|
||||
setContext(): void {
|
||||
const opts: ContextOptions = {
|
||||
Name: this.name.value,
|
||||
Manifest: this.manifest.value,
|
||||
ManagementConfiguration: this.managementConfiguration.value,
|
||||
EncryptionConfig: this.encryptionConfig.value,
|
||||
};
|
||||
|
||||
const msg = new WebsocketMessage(this.type, this.component, 'setContext');
|
||||
msg.data = JSON.parse(JSON.stringify(opts));
|
||||
msg.name = this.name.value;
|
||||
|
||||
this.websocketService.sendMessage(msg);
|
||||
this.toggleLock();
|
||||
}
|
||||
|
||||
useContext(name: string): void {
|
||||
const msg = new WebsocketMessage(this.type, this.component, 'useContext');
|
||||
msg.name = name;
|
||||
this.websocketService.sendMessage(msg);
|
||||
}
|
||||
}
|
@ -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
|
||||
#
|
||||
# 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.
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
FormsModule,
|
||||
MatInputModule,
|
||||
MatCardModule,
|
||||
MatButtonModule,
|
||||
ReactiveFormsModule,
|
||||
],
|
||||
declarations: [
|
||||
],
|
||||
providers: []
|
||||
})
|
||||
export class ConfigContextModule { }
|
@ -0,0 +1,17 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
.grey-icon {
|
||||
color: grey;
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
<mat-card class="encryption-config-card">
|
||||
<mat-card-header>
|
||||
<mat-card-title>
|
||||
<button mat-icon-button (click)="toggleLock()">
|
||||
<mat-icon *ngIf="locked" class="grey-icon" svgIcon="lock"></mat-icon>
|
||||
<mat-icon *ngIf="!locked" class="grey-icon" svgIcon="lock_open"></mat-icon>
|
||||
</button>{{config.name}}
|
||||
</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<div *ngIf="config.hasOwnProperty('encryptionKeyPath')">
|
||||
<p>EncryptionKeyPath:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="encryptionKeyPath">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>DecryptionKeyPath:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="decryptionKeyPath">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
</div>
|
||||
<div *ngIf="config.hasOwnProperty('keySecretName')">
|
||||
<p>KeySecretName:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="keySecretName">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>KeySecretNamespace:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="keySecretNamespace">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button mat-raised-button [disabled]="locked" (click)="setEncryptionConfig()" color="primary">Set</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ToastrModule } from 'ngx-toastr';
|
||||
import { EncryptionConfig } from '../config.models';
|
||||
|
||||
import { ConfigEncryptionComponent } from './config-encryption.component';
|
||||
|
||||
describe('ConfigEncryptionComponent', () => {
|
||||
let component: ConfigEncryptionComponent;
|
||||
let fixture: ComponentFixture<ConfigEncryptionComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ConfigEncryptionComponent ],
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
FormsModule,
|
||||
MatCardModule,
|
||||
MatInputModule,
|
||||
MatIconModule,
|
||||
MatCheckboxModule,
|
||||
MatButtonModule,
|
||||
ReactiveFormsModule,
|
||||
ToastrModule.forRoot()
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ConfigEncryptionComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
component.config = new EncryptionConfig();
|
||||
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { EncryptionConfig, EncryptionConfigOptions } from '../config.models';
|
||||
import { WebsocketService } from '../../../../services/websocket/websocket.service';
|
||||
import { WebsocketMessage } from '../../../../services/websocket/websocket.models';
|
||||
|
||||
@Component({
|
||||
selector: 'app-config-encryption',
|
||||
templateUrl: './config-encryption.component.html',
|
||||
styleUrls: ['./config-encryption.component.css']
|
||||
})
|
||||
export class ConfigEncryptionComponent implements OnInit {
|
||||
@Input() config: EncryptionConfig;
|
||||
type = 'ctl';
|
||||
component = 'config';
|
||||
|
||||
locked = true;
|
||||
name = new FormControl({value: '', disabled: true});
|
||||
encryptionKeyPath = new FormControl({value: '', disabled: true});
|
||||
decryptionKeyPath = new FormControl({value: '', disabled: true});
|
||||
keySecretName = new FormControl({value: '', disabled: true});
|
||||
keySecretNamespace = new FormControl({value: '', disabled: true});
|
||||
|
||||
controlsArray = [this.encryptionKeyPath, this.decryptionKeyPath, this.keySecretName, this.keySecretNamespace];
|
||||
|
||||
constructor(private websocketService: WebsocketService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.name.setValue(this.config.name);
|
||||
this.encryptionKeyPath.setValue(this.config.encryptionKeyPath);
|
||||
this.decryptionKeyPath.setValue(this.config.decryptionKeyPath);
|
||||
this.keySecretName.setValue(this.config.keySecretName);
|
||||
this.keySecretNamespace.setValue(this.config.keySecretNamespace);
|
||||
}
|
||||
|
||||
toggleLock(): void {
|
||||
for (const control of this.controlsArray) {
|
||||
if (this.locked) {
|
||||
control.enable();
|
||||
} else {
|
||||
control.disable();
|
||||
}
|
||||
}
|
||||
|
||||
this.locked = !this.locked;
|
||||
}
|
||||
|
||||
setEncryptionConfig(): void {
|
||||
const opts: EncryptionConfigOptions = {
|
||||
Name: this.name.value,
|
||||
EncryptionKeyPath: this.encryptionKeyPath.value,
|
||||
DecryptionKeyPath: this.decryptionKeyPath.value,
|
||||
KeySecretName: this.keySecretName.value,
|
||||
KeySecretNamespace: this.keySecretNamespace.value,
|
||||
};
|
||||
|
||||
const msg = new WebsocketMessage(this.type, this.component, 'setEncryptionConfig');
|
||||
msg.data = JSON.parse(JSON.stringify(opts));
|
||||
msg.name = this.name.value;
|
||||
|
||||
this.websocketService.sendMessage(msg);
|
||||
this.toggleLock();
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
#
|
||||
# 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.
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
FormsModule,
|
||||
MatInputModule,
|
||||
MatCardModule,
|
||||
MatButtonModule,
|
||||
ReactiveFormsModule,
|
||||
],
|
||||
declarations: [
|
||||
],
|
||||
providers: []
|
||||
})
|
||||
export class ConfigEncryptionModule { }
|
@ -0,0 +1,17 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
.grey-icon {
|
||||
color: grey;
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<mat-card class="management-config-card">
|
||||
<mat-card-header>
|
||||
<mat-card-title>
|
||||
<button mat-icon-button (click)="toggleLock()">
|
||||
<mat-icon *ngIf="locked" class="grey-icon" svgIcon="lock"></mat-icon>
|
||||
<mat-icon *ngIf="!locked" class="grey-icon" svgIcon="lock_open"></mat-icon>
|
||||
</button>{{config.name}}
|
||||
</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<p>
|
||||
<mat-checkbox [formControl]="insecure" labelPosition="before">Insecure: </mat-checkbox>
|
||||
</p>
|
||||
<p>SystemActionRetries:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="systemActionRetries" pattern="[0-9]*">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>SystemRebootDelay:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="systemRebootDelay" pattern="[0-9]*">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>Type:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="type">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>
|
||||
<mat-checkbox [formControl]="useproxy" labelPosition="before">UseProxy: </mat-checkbox>
|
||||
</p>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button mat-raised-button [disabled]="locked" (click)="setManagementConfig()" color="primary">Set</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ToastrModule } from 'ngx-toastr';
|
||||
import { ManagementConfig } from '../config.models';
|
||||
|
||||
import { ConfigManagementComponent } from './config-management.component';
|
||||
|
||||
describe('ConfigManagementComponent', () => {
|
||||
let component: ConfigManagementComponent;
|
||||
let fixture: ComponentFixture<ConfigManagementComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ConfigManagementComponent ],
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
MatCardModule,
|
||||
FormsModule,
|
||||
MatInputModule,
|
||||
MatIconModule,
|
||||
MatCheckboxModule,
|
||||
MatButtonModule,
|
||||
ReactiveFormsModule,
|
||||
ToastrModule.forRoot(),
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ConfigManagementComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
component.config = new ManagementConfig();
|
||||
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { ManagementConfig } from '../config.models';
|
||||
import { FormControl, Validators } from '@angular/forms';
|
||||
import { WebsocketService } from 'src/services/websocket/websocket.service';
|
||||
import { WebsocketMessage } from 'src/services/websocket/websocket.models';
|
||||
|
||||
@Component({
|
||||
selector: 'app-config-management',
|
||||
templateUrl: './config-management.component.html',
|
||||
styleUrls: ['./config-management.component.css']
|
||||
})
|
||||
export class ConfigManagementComponent implements OnInit {
|
||||
@Input() config: ManagementConfig;
|
||||
msgType = 'ctl';
|
||||
component = 'config';
|
||||
|
||||
locked = true;
|
||||
|
||||
name = new FormControl({value: '', disabled: true});
|
||||
insecure = new FormControl({value: false, disabled: true});
|
||||
systemActionRetries = new FormControl({value: '', disabled: true}, Validators.pattern('[0-9]*'));
|
||||
systemRebootDelay = new FormControl({value: '', disabled: true}, Validators.pattern('[0-9]*'));
|
||||
type = new FormControl({value: '', disabled: true});
|
||||
useproxy = new FormControl({value: false, disabled: true});
|
||||
|
||||
controlsArray = [this.name, this.insecure, this.systemRebootDelay, this.systemActionRetries, this.type, this.useproxy];
|
||||
|
||||
constructor(private websocketService: WebsocketService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.name.setValue(this.config.name);
|
||||
this.insecure.setValue(this.config.insecure);
|
||||
this.systemActionRetries.setValue(this.config.systemActionRetries);
|
||||
this.systemRebootDelay.setValue(this.config.systemRebootDelay);
|
||||
this.type.setValue(this.config.type);
|
||||
this.useproxy.setValue(this.config.useproxy);
|
||||
}
|
||||
|
||||
toggleLock(): void {
|
||||
for (const control of this.controlsArray) {
|
||||
if (this.locked) {
|
||||
control.enable();
|
||||
} else {
|
||||
control.disable();
|
||||
}
|
||||
}
|
||||
|
||||
this.locked = !this.locked;
|
||||
}
|
||||
|
||||
setManagementConfig(): void {
|
||||
const msg = new WebsocketMessage(this.msgType, this.component, 'setManagementConfig');
|
||||
msg.name = this.name.value;
|
||||
|
||||
const cfg: ManagementConfig = {
|
||||
name: this.name.value,
|
||||
insecure: this.insecure.value,
|
||||
// TODO(mfuller): need to validate these are numerical values in the form
|
||||
systemActionRetries: +this.systemActionRetries.value,
|
||||
systemRebootDelay: +this.systemRebootDelay.value,
|
||||
type: this.type.value,
|
||||
useproxy: this.useproxy.value
|
||||
};
|
||||
|
||||
msg.data = JSON.parse(JSON.stringify(cfg));
|
||||
this.websocketService.sendMessage(msg);
|
||||
this.toggleLock();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
FormsModule,
|
||||
MatInputModule,
|
||||
MatCardModule,
|
||||
MatButtonModule,
|
||||
ReactiveFormsModule,
|
||||
MatCheckboxModule,
|
||||
MatIconModule
|
||||
],
|
||||
declarations: [
|
||||
],
|
||||
providers: []
|
||||
})
|
||||
export class ConfigManagementModule { }
|
@ -0,0 +1,17 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
.grey-icon {
|
||||
color: grey;
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
<mat-card class="manifest-config-card">
|
||||
<mat-card-header>
|
||||
<mat-card-title>
|
||||
<button mat-icon-button (click)="toggleLock()">
|
||||
<mat-icon *ngIf="locked" class="grey-icon" svgIcon="lock"></mat-icon>
|
||||
<mat-icon *ngIf="!locked" class="grey-icon" svgIcon="lock_open"></mat-icon>
|
||||
</button>{{manifest.name}}
|
||||
</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<p>RepoName:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="RepoName">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>URL:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="URL">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>Branch:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="Branch">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>CommitHash:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="CommitHash">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>Tag:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="Tag">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>RemoteRef:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="RemoteRef">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>
|
||||
<mat-checkbox [formControl]="Force" labelPosition="before">Force: </mat-checkbox>
|
||||
</p>
|
||||
<p>
|
||||
<mat-checkbox [formControl]="IsPhase" labelPosition="before">IsPhase: </mat-checkbox>
|
||||
</p>
|
||||
<p>SubPath:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="SubPath">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>TargetPath:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="TargetPath">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>MetadataPath:
|
||||
<mat-form-field appearance="fill">
|
||||
<input matInput [formControl]="MetadataPath">
|
||||
</mat-form-field>
|
||||
</p>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button mat-raised-button [disabled]="locked" (click)="setManifest()" color="primary">Set</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
@ -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
|
||||
#
|
||||
# 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.
|
||||
*/
|
||||
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ToastrModule } from 'ngx-toastr';
|
||||
import { CtlManifest, Manifest, RepoCheckout, Repository } from '../config.models';
|
||||
|
||||
import { ConfigManifestComponent } from './config-manifest.component';
|
||||
|
||||
describe('ConfigManifestComponent', () => {
|
||||
let component: ConfigManifestComponent;
|
||||
let fixture: ComponentFixture<ConfigManifestComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ConfigManifestComponent ],
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
MatCardModule,
|
||||
FormsModule,
|
||||
MatInputModule,
|
||||
MatIconModule,
|
||||
MatCheckboxModule,
|
||||
MatButtonModule,
|
||||
ReactiveFormsModule,
|
||||
ToastrModule.forRoot()
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ConfigManifestComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
component.manifest = new Manifest();
|
||||
component.manifest.manifest = new CtlManifest();
|
||||
const repoName = 'fakerepo';
|
||||
component.manifest.manifest.phaseRepositoryName = repoName;
|
||||
component.manifest.manifest.repositories = {};
|
||||
component.manifest.manifest.repositories[repoName] = new Repository();
|
||||
component.manifest.manifest.repositories[repoName].checkout = new RepoCheckout();
|
||||
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Manifest, ManifestOptions, Repository } from '../config.models';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { WebsocketService } from 'src/services/websocket/websocket.service';
|
||||
import { WebsocketMessage } from 'src/services/websocket/websocket.models';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-config-manifest',
|
||||
templateUrl: './config-manifest.component.html',
|
||||
styleUrls: ['./config-manifest.component.css']
|
||||
})
|
||||
export class ConfigManifestComponent implements OnInit {
|
||||
@Input() manifest: Manifest;
|
||||
|
||||
type = 'ctl';
|
||||
component = 'config';
|
||||
|
||||
locked = true;
|
||||
Name = new FormControl({value: '', disabled: true});
|
||||
RepoName = new FormControl({value: '', disabled: true});
|
||||
URL = new FormControl({value: '', disabled: true});
|
||||
Branch = new FormControl({value: '', disabled: true});
|
||||
CommitHash = new FormControl({value: '', disabled: true});
|
||||
Tag = new FormControl({value: '', disabled: true});
|
||||
RemoteRef = new FormControl({value: '', disabled: true});
|
||||
Force = new FormControl({value: false, disabled: true});
|
||||
IsPhase = new FormControl({value: false, disabled: true});
|
||||
SubPath = new FormControl({value: '', disabled: true});
|
||||
TargetPath = new FormControl({value: '', disabled: true});
|
||||
MetadataPath = new FormControl({value: '', disabled: true});
|
||||
|
||||
controlsArray = [
|
||||
this.Name,
|
||||
this.RepoName,
|
||||
this.URL,
|
||||
this.Branch,
|
||||
this.CommitHash,
|
||||
this.Tag,
|
||||
this.RemoteRef,
|
||||
this.Force,
|
||||
this.IsPhase,
|
||||
this.SubPath,
|
||||
this.TargetPath,
|
||||
this.MetadataPath
|
||||
];
|
||||
|
||||
constructor(private websocketService: WebsocketService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.Name.setValue(this.manifest.name);
|
||||
|
||||
// TODO(mfuller): not sure yet how to handle multiple repositories,
|
||||
// so for now, I'm just showing the phase repository (primary)
|
||||
const repoName = this.manifest.manifest.phaseRepositoryName;
|
||||
this.RepoName.setValue(repoName);
|
||||
const primaryRepo: Repository = this.manifest.manifest.repositories[repoName];
|
||||
this.URL.setValue(primaryRepo.url);
|
||||
this.Branch.setValue(primaryRepo.checkout.branch);
|
||||
this.CommitHash.setValue(primaryRepo.checkout.commitHash);
|
||||
this.Tag.setValue(primaryRepo.checkout.tag);
|
||||
this.RemoteRef.setValue(primaryRepo.checkout.remoteRef);
|
||||
this.Force.setValue(primaryRepo.checkout.force);
|
||||
// TODO(mfuller): this value doesn't come from the config file, but if set to true,
|
||||
// it appears to set the phaseRepositoryName key, and since that's
|
||||
// the only repo I'm showing, set to true for now
|
||||
this.IsPhase.setValue(true);
|
||||
this.SubPath.setValue(this.manifest.manifest.subPath);
|
||||
this.TargetPath.setValue(this.manifest.manifest.targetPath);
|
||||
this.MetadataPath.setValue(this.manifest.manifest.metadataPath);
|
||||
}
|
||||
|
||||
toggleLock(): void {
|
||||
for (const control of this.controlsArray) {
|
||||
if (this.locked) {
|
||||
control.enable();
|
||||
} else {
|
||||
control.disable();
|
||||
}
|
||||
}
|
||||
|
||||
this.locked = !this.locked;
|
||||
}
|
||||
|
||||
setManifest(): void {
|
||||
const msg = new WebsocketMessage(this.type, this.component, 'setManifest');
|
||||
msg.name = this.manifest.name;
|
||||
|
||||
// TODO(mfuller): since "Force" and "IsPhase" can only be set by passing in
|
||||
// CLI flags rather than passing in values, there doesn't appear to be a way
|
||||
// to unset them once they're true without manually editing the config file.
|
||||
// Open a bug for this? Or is this intentional? I may have to write a custom
|
||||
// setter to set the value directly in the Config struct
|
||||
const opts: ManifestOptions = {
|
||||
Name: this.Name.value,
|
||||
RepoName: this.RepoName.value,
|
||||
URL: this.URL.value,
|
||||
Branch: this.Branch.value,
|
||||
CommitHash: this.CommitHash.value,
|
||||
Tag: this.Tag.value,
|
||||
RemoteRef: this.RemoteRef.value,
|
||||
Force: this.Force.value,
|
||||
IsPhase: this.IsPhase.value,
|
||||
SubPath: this.SubPath.value,
|
||||
TargetPath: this.TargetPath.value,
|
||||
MetadataPath: this.MetadataPath.value
|
||||
};
|
||||
|
||||
msg.data = JSON.parse(JSON.stringify(opts));
|
||||
this.websocketService.sendMessage(msg);
|
||||
this.toggleLock();
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
FormsModule,
|
||||
MatInputModule,
|
||||
MatCardModule,
|
||||
MatButtonModule,
|
||||
ReactiveFormsModule,
|
||||
MatCheckboxModule
|
||||
],
|
||||
declarations: [
|
||||
],
|
||||
providers: []
|
||||
})
|
||||
export class ConfigManifestModule { }
|
17
client/src/app/ctl/config/config.component.css
Normal file
17
client/src/app/ctl/config/config.component.css
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
.grey-icon {
|
||||
color: grey;
|
||||
}
|
@ -1 +1,26 @@
|
||||
<h1>Config component</h1>
|
||||
<h1>Airship Configuration Operations</h1>
|
||||
<mat-divider></mat-divider>
|
||||
<div class="config-container">
|
||||
<h3>Contexts - Current Context: {{currentContext}}</h3>
|
||||
<div class="contexts" *ngFor="let context of contexts">
|
||||
<app-config-context [context]="context"></app-config-context>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<h3>Manifests</h3>
|
||||
<div class="manifests" *ngFor="let manifest of manifests">
|
||||
<app-config-manifest [manifest]="manifest"></app-config-manifest>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<h3>Encryption Configurations</h3>
|
||||
<div class="encryption-configs" *ngFor="let config of encryptionConfigs">
|
||||
<app-config-encryption [config]="config"></app-config-encryption>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<h3>Management Configurations</h3>
|
||||
<div class="management-configs" *ngFor="let config of managementConfigs">
|
||||
<app-config-management [config]="config"></app-config-management>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -15,6 +15,20 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ConfigComponent } from './config.component';
|
||||
import { ToastrModule } from 'ngx-toastr';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { ConfigContextModule } from './config-context/config-context.module';
|
||||
import { ConfigManagementModule } from './config-management/config-management.module';
|
||||
import { ConfigManifestModule } from './config-manifest/config-manifest.module';
|
||||
import { ConfigEncryptionModule } from './config-encryption/config-encryption.module';
|
||||
import { ConfigManifestComponent } from './config-manifest/config-manifest.component';
|
||||
import { ConfigManagementComponent } from './config-management/config-management.component';
|
||||
import { ConfigEncryptionComponent } from './config-encryption/config-encryption.component';
|
||||
import { ConfigContextComponent } from './config-context/config-context.component';
|
||||
|
||||
describe('ConfigComponent', () => {
|
||||
let component: ConfigComponent;
|
||||
@ -23,11 +37,26 @@ describe('ConfigComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
ToastrModule.forRoot()
|
||||
ToastrModule.forRoot(),
|
||||
FormsModule,
|
||||
MatButtonModule,
|
||||
MatInputModule,
|
||||
MatCardModule,
|
||||
MatCheckboxModule,
|
||||
ConfigContextModule,
|
||||
ConfigManagementModule,
|
||||
ConfigManifestModule,
|
||||
ConfigEncryptionModule,
|
||||
ReactiveFormsModule
|
||||
],
|
||||
declarations: [
|
||||
ConfigComponent
|
||||
]
|
||||
ConfigComponent,
|
||||
ConfigManifestComponent,
|
||||
ConfigManagementComponent,
|
||||
ConfigEncryptionComponent,
|
||||
ConfigContextComponent
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
@ -12,33 +12,115 @@
|
||||
# limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { WebsocketService } from '../../../services/websocket/websocket.service';
|
||||
import { WebsocketMessage, WSReceiver } from '../../../services/websocket/websocket.models';
|
||||
import { Log } from '../../../services/log/log.service';
|
||||
import { LogMessage } from '../../../services/log/log-message';
|
||||
import { Context, ManagementConfig, Manifest, EncryptionConfig } from './config.models';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bare-metal',
|
||||
templateUrl: './config.component.html',
|
||||
})
|
||||
|
||||
export class ConfigComponent implements WSReceiver {
|
||||
export class ConfigComponent implements WSReceiver, OnInit {
|
||||
className = this.constructor.name;
|
||||
// TODO (aschiefe): extract these strings to constants
|
||||
type = 'ctl';
|
||||
component = 'config';
|
||||
|
||||
currentContext: string;
|
||||
contexts: Context[] = [];
|
||||
manifests: Manifest[] = [];
|
||||
managementConfigs: ManagementConfig[] = [];
|
||||
encryptionConfigs: EncryptionConfig[] = [];
|
||||
|
||||
constructor(private websocketService: WebsocketService) {
|
||||
this.websocketService.registerFunctions(this);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getConfig();
|
||||
}
|
||||
|
||||
async receiver(message: WebsocketMessage): Promise<void> {
|
||||
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 config', this.className, message));
|
||||
switch (message.subComponent) {
|
||||
case 'getCurrentContext':
|
||||
this.currentContext = message.message;
|
||||
break;
|
||||
case 'getContexts':
|
||||
Object.assign(this.contexts, message.data);
|
||||
break;
|
||||
case 'getManifests':
|
||||
Object.assign(this.manifests, message.data);
|
||||
break;
|
||||
case 'getEncryptionConfigs':
|
||||
Object.assign(this.encryptionConfigs, message.data);
|
||||
break;
|
||||
case 'getManagementConfigs':
|
||||
Object.assign(this.managementConfigs, message.data);
|
||||
break;
|
||||
case 'useContext':
|
||||
this.getCurrentContext();
|
||||
break;
|
||||
case 'setContext':
|
||||
this.websocketService.printIfToast(message);
|
||||
break;
|
||||
case 'setEncryptionConfig':
|
||||
this.websocketService.printIfToast(message);
|
||||
break;
|
||||
case 'setManifest':
|
||||
this.websocketService.printIfToast(message);
|
||||
break;
|
||||
case 'setManagementConfig':
|
||||
this.websocketService.printIfToast(message);
|
||||
break;
|
||||
default:
|
||||
Log.Error(new LogMessage('Config message sub component not handled', this.className, message));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getConfig(): void {
|
||||
this.getCurrentContext();
|
||||
this.getContexts();
|
||||
this.getManifests();
|
||||
this.getManagementConfigs();
|
||||
this.getEncryptionConfigs();
|
||||
}
|
||||
|
||||
getCurrentContext(): void {
|
||||
this.websocketService.sendMessage(new WebsocketMessage(
|
||||
this.type, this.component, 'getCurrentContext')
|
||||
);
|
||||
}
|
||||
|
||||
getContexts(): void {
|
||||
this.websocketService.sendMessage(new WebsocketMessage(
|
||||
this.type, this.component, 'getContexts')
|
||||
);
|
||||
}
|
||||
|
||||
getManifests(): void {
|
||||
this.websocketService.sendMessage(new WebsocketMessage(
|
||||
this.type, this.component, 'getManifests')
|
||||
);
|
||||
}
|
||||
|
||||
getEncryptionConfigs(): void {
|
||||
this.websocketService.sendMessage(new WebsocketMessage(
|
||||
this.type, this.component, 'getEncryptionConfigs')
|
||||
);
|
||||
}
|
||||
|
||||
getManagementConfigs(): void {
|
||||
this.websocketService.sendMessage(new WebsocketMessage(
|
||||
this.type, this.component, 'getManagementConfigs')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
111
client/src/app/ctl/config/config.models.ts
Normal file
111
client/src/app/ctl/config/config.models.ts
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
# 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.
|
||||
*/
|
||||
|
||||
export class EncryptionConfig {
|
||||
name: string;
|
||||
encryptionKeyPath: string;
|
||||
decryptionKeyPath: string;
|
||||
keySecretName: string;
|
||||
keySecretNamespace: string;
|
||||
}
|
||||
|
||||
export class Context {
|
||||
name: string;
|
||||
contextKubeconf: string;
|
||||
manifest: string;
|
||||
encryptionConfig: string;
|
||||
managementConfiguration: string;
|
||||
}
|
||||
|
||||
export class ContextOptions {
|
||||
Name: string;
|
||||
Manifest: string;
|
||||
ManagementConfiguration: string;
|
||||
EncryptionConfig: string;
|
||||
}
|
||||
|
||||
export class ManagementConfig {
|
||||
name: string;
|
||||
insecure: boolean;
|
||||
systemActionRetries: number;
|
||||
systemRebootDelay: number;
|
||||
type: string;
|
||||
useproxy: boolean;
|
||||
}
|
||||
|
||||
export class Manifest {
|
||||
name: string;
|
||||
manifest: CtlManifest;
|
||||
}
|
||||
|
||||
export class CtlManifest {
|
||||
phaseRepositoryName: string;
|
||||
repositories: object;
|
||||
targetPath: string;
|
||||
subPath: string;
|
||||
metadataPath: string;
|
||||
}
|
||||
|
||||
export class Repository {
|
||||
url: string;
|
||||
auth: RepoAuth;
|
||||
checkout: RepoCheckout;
|
||||
}
|
||||
|
||||
export class RepoAuth {
|
||||
type: string;
|
||||
keyPass: string;
|
||||
sshKey: string;
|
||||
httpPass: string;
|
||||
sshPass: string;
|
||||
username: string;
|
||||
}
|
||||
|
||||
export class RepoCheckout {
|
||||
commitHash: string;
|
||||
branch: string;
|
||||
tag: string;
|
||||
remoteRef: string;
|
||||
force: boolean;
|
||||
}
|
||||
|
||||
// TODO(mfuller): this isn't currently settable from the CLI
|
||||
// should we allow it in UI?
|
||||
export class Permissions {
|
||||
DirectoryPermission: number;
|
||||
FilePermission: number;
|
||||
}
|
||||
|
||||
export class ManifestOptions {
|
||||
Name: string;
|
||||
RepoName: string;
|
||||
URL: string;
|
||||
Branch: string;
|
||||
CommitHash: string;
|
||||
Tag: string;
|
||||
RemoteRef: string;
|
||||
Force: boolean;
|
||||
IsPhase: boolean;
|
||||
SubPath: string;
|
||||
TargetPath: string;
|
||||
MetadataPath: string;
|
||||
}
|
||||
|
||||
export class EncryptionConfigOptions {
|
||||
Name: string;
|
||||
EncryptionKeyPath: string;
|
||||
DecryptionKeyPath: string;
|
||||
KeySecretName: string;
|
||||
KeySecretNamespace: string;
|
||||
}
|
@ -12,15 +12,42 @@
|
||||
# limitations under the License.
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ConfigComponent } from './config.component';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { ConfigContextComponent } from './config-context/config-context.component';
|
||||
import { ConfigEncryptionComponent } from './config-encryption/config-encryption.component';
|
||||
import { ConfigManagementComponent } from './config-management/config-management.component';
|
||||
import { ConfigManifestComponent } from './config-manifest/config-manifest.component';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
MatCardModule,
|
||||
MatInputModule,
|
||||
MatDividerModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatCheckboxModule
|
||||
],
|
||||
declarations: [
|
||||
ConfigComponent
|
||||
ConfigComponent,
|
||||
ConfigContextComponent,
|
||||
ConfigEncryptionComponent,
|
||||
ConfigManagementComponent,
|
||||
ConfigManifestComponent
|
||||
],
|
||||
providers: []
|
||||
providers: [],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
export class ConfigModule { }
|
||||
|
@ -21,11 +21,13 @@ import { ClusterModule } from './cluster/cluster.module';
|
||||
import { CtlRoutingModule } from './ctl-routing.module';
|
||||
import { PhaseModule } from './phase/phase.module';
|
||||
import { SecretModule } from './secret/secret.module';
|
||||
import { ConfigModule } from './config/config.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CtlRoutingModule,
|
||||
ClusterModule,
|
||||
ConfigModule,
|
||||
RouterModule,
|
||||
DocumentModule,
|
||||
BaremetalModule,
|
||||
|
1
client/src/assets/icons/lock.svg
Normal file
1
client/src/assets/icons/lock.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/></svg>
|
After Width: | Height: | Size: 363 B |
1
client/src/assets/icons/lock_open.svg
Normal file
1
client/src/assets/icons/lock_open.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6h1.9c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm0 12H6V10h12v10z"/></svg>
|
After Width: | Height: | Size: 369 B |
@ -31,5 +31,7 @@ export enum Icons {
|
||||
list_alt = 'list_alt',
|
||||
devices = 'devices',
|
||||
check_circle = 'check_circle',
|
||||
close = 'close'
|
||||
close = 'close',
|
||||
lock = 'lock',
|
||||
lock_open = 'lock_open'
|
||||
}
|
||||
|
4
go.mod
4
go.mod
@ -10,8 +10,8 @@ require (
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/stretchr/testify v1.6.1
|
||||
opendev.org/airship/airshipctl v0.0.0-20201007194648-8d6851511840
|
||||
sigs.k8s.io/cli-utils v0.18.1
|
||||
opendev.org/airship/airshipctl v0.0.0-20201021221027-46a0a79066d3
|
||||
sigs.k8s.io/cli-utils v0.20.6
|
||||
sigs.k8s.io/kustomize/api v0.5.1
|
||||
)
|
||||
|
||||
|
76
go.sum
76
go.sum
@ -2,6 +2,14 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
github.com/360EntSecGroup-Skylar/excelize v1.4.1/go.mod h1:vnax29X2usfl7HHkBrX5EvSCJcmH3dT9luvxzu8iGAE=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
@ -180,6 +188,8 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjr
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
@ -295,6 +305,7 @@ github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18h
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@ -336,6 +347,8 @@ github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
@ -346,6 +359,7 @@ github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
@ -353,6 +367,7 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=
|
||||
github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
|
||||
@ -436,11 +451,15 @@ github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM52
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
@ -530,6 +549,8 @@ github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.13.0 h1:M76yO2HkZASFjXL0HSoZJ1AYEmQxNJmY41Jx1zNUq1Y=
|
||||
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
@ -595,6 +616,7 @@ github.com/russross/blackfriday v0.0.0-20170610170232-067529f716f4/go.mod h1:JO/
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
|
||||
github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d/go.mod h1:w5+eXa0mYznDkHaMCXA4XYffjlH+cy1oyKbfzJXa2Do=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
@ -608,6 +630,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
@ -683,6 +707,7 @@ go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL
|
||||
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.starlark.net v0.0.0-20190528202925-30ae18b8564f/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg=
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
|
||||
@ -706,25 +731,33 @@ golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -743,6 +776,8 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@ -757,6 +792,8 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3ob
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@ -786,12 +823,16 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -802,6 +843,9 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 h1:OjiUf46hAmXblsZdnoSXsEUSKU8r1UEzcL5RVZ4gO9Y=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -832,39 +876,56 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51 h1:Ex1mq5jaJof+kRnYi3SlYJ8KKa9Ao3NHyIT5XJ1gF6U=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
|
||||
@ -879,6 +940,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@ -916,6 +978,7 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
k8s.io/api v0.0.0-20190918155943-95b840bb6a1f/go.mod h1:uWuOHnjmNrtQomJrvEBg0c0HRNyQ+8KTEERVsK0PW48=
|
||||
@ -993,14 +1056,15 @@ modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
|
||||
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
|
||||
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
|
||||
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
|
||||
opendev.org/airship/airshipctl v0.0.0-20201007194648-8d6851511840 h1:FdeXz/3JxL20ZLOX5RtTy4BHxGJn/bi9lHnIxv/+rTg=
|
||||
opendev.org/airship/airshipctl v0.0.0-20201007194648-8d6851511840/go.mod h1:uSXCXgsecl6Em2fHfjSXVsWItbzi8UWjKON+m6YdrjE=
|
||||
opendev.org/airship/airshipctl v0.0.0-20201021221027-46a0a79066d3 h1:aqscOCgADezXB7gwOhtKfn8v1mas4vAxzrHwfcptFxA=
|
||||
opendev.org/airship/airshipctl v0.0.0-20201021221027-46a0a79066d3/go.mod h1:qnuSTEEmInUS+zk7fMvNeDEloiTqlHlRsEmWFXlT+pU=
|
||||
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=
|
||||
opendev.org/airship/go-redfish/client v0.0.0-20200318103738-db034d1d753a h1:S1dmsP5Cc6OQjAd6OgIKMcNPBiGjh5TDbijVjNE/VGU=
|
||||
opendev.org/airship/go-redfish/client v0.0.0-20200318103738-db034d1d753a/go.mod h1:s0hwuUpBsRXOrhN0NR+fNVivXGyWgHKpqtyq7qYjpew=
|
||||
sigs.k8s.io/cli-utils v0.18.1 h1:K4usJmMlI98mL+z+TdAnKfzng64/m8bRXZKPwy3ZCWw=
|
||||
sigs.k8s.io/cli-utils v0.18.1/go.mod h1:B7KdqkSkHNIUn3cFbaR4aKUZMKtr+Benboi1w/HW/Fg=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
sigs.k8s.io/cli-utils v0.20.6 h1:leIIk2NOzacXqhuNnm0tB328RSzp+1QR9PkAdSP1aRI=
|
||||
sigs.k8s.io/cli-utils v0.20.6/go.mod h1:Lsj0EXMtqcSYyIPY9IXemMQW/muYDHMEWNfQI/DctrA=
|
||||
sigs.k8s.io/cluster-api v0.3.10 h1:iUbnDdFQjp406hclEV1/rRMO7/NpyJ7IxozAaAA9Zns=
|
||||
sigs.k8s.io/cluster-api v0.3.10/go.mod h1:XBBDBiaczcyNlH4D7FNjSKc5bBofYRppfg0ZgaP2x1U=
|
||||
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
|
||||
|
@ -137,15 +137,17 @@ const (
|
||||
Status WsSubComponentType = "status"
|
||||
|
||||
// ctl config subcomponets
|
||||
GetContext WsSubComponentType = "getContext"
|
||||
GetEncryptionConfig WsSubComponentType = "getEncryptionConfig"
|
||||
GetManagementConfig WsSubComponentType = "getManagementConfig"
|
||||
GetManifest WsSubComponentType = "getManifest"
|
||||
SetContext WsSubComponentType = "setContext"
|
||||
SetEncryptionConfig WsSubComponentType = "setEncryptionConfig"
|
||||
SetManagementConfig WsSubComponentType = "setManagementConfig"
|
||||
SetManifest WsSubComponentType = "setManifest"
|
||||
UseContext WsSubComponentType = "useContext"
|
||||
GetContexts WsSubComponentType = "getContexts"
|
||||
GetCurrentContext WsSubComponentType = "getCurrentContext"
|
||||
GetEncryptionConfigs WsSubComponentType = "getEncryptionConfigs"
|
||||
GetManagementConfigs WsSubComponentType = "getManagementConfigs"
|
||||
GetManifests WsSubComponentType = "getManifests"
|
||||
SetContext WsSubComponentType = "setContext"
|
||||
SetEncryptionConfig WsSubComponentType = "setEncryptionConfig"
|
||||
SetManagementConfig WsSubComponentType = "setManagementConfig"
|
||||
SetManifest WsSubComponentType = "setManifest"
|
||||
UseContext WsSubComponentType = "useContext"
|
||||
GetConfig WsSubComponentType = "getConfig"
|
||||
|
||||
// ctl document subcomponents
|
||||
Plugin WsSubComponentType = "plugin"
|
||||
|
@ -64,9 +64,12 @@ func Init() {
|
||||
}
|
||||
|
||||
// NewDefaultClient initializes the airshipctl client for external usage with default logging.
|
||||
func NewDefaultClient(airshipConfigPath, kubeConfigPath *string) (*Client, error) {
|
||||
cfgFactory := config.CreateFactory(airshipConfigPath, kubeConfigPath)
|
||||
func NewDefaultClient(airshipConfigPath *string) (*Client, error) {
|
||||
cfgFactory := config.CreateFactory(airshipConfigPath)
|
||||
|
||||
// TODO(mfuller): Factory doesn't throw an error if there's no
|
||||
// config file, it calls log.Fatal and kills the app. Not sure
|
||||
// how to handle this yet
|
||||
conf, err := cfgFactory()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -84,7 +87,7 @@ func NewDefaultClient(airshipConfigPath, kubeConfigPath *string) (*Client, error
|
||||
|
||||
// NewClient initializes the airshipctl client for external usage with the logging overridden.
|
||||
func NewClient(airshipConfigPath, kubeConfigPath *string, request configs.WsMessage) (*Client, error) {
|
||||
client, err := NewDefaultClient(airshipConfigPath, kubeConfigPath)
|
||||
client, err := NewDefaultClient(airshipConfigPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -15,9 +15,12 @@
|
||||
package ctl
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
ctlconfig "opendev.org/airship/airshipctl/pkg/config"
|
||||
"opendev.org/airship/airshipui/pkg/configs"
|
||||
"opendev.org/airship/airshipui/pkg/log"
|
||||
)
|
||||
|
||||
// HandleConfigRequest will flop between requests so we don't have to have them all mapped as function calls
|
||||
@ -25,35 +28,54 @@ import (
|
||||
func HandleConfigRequest(user *string, request configs.WsMessage) configs.WsMessage {
|
||||
response := configs.WsMessage{
|
||||
Type: configs.CTL,
|
||||
Component: configs.Baremetal,
|
||||
Component: configs.CTLConfig,
|
||||
SubComponent: request.SubComponent,
|
||||
Name: request.Name,
|
||||
}
|
||||
|
||||
var err error
|
||||
var message *string
|
||||
|
||||
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error initializing airshipctl client: %s", err)
|
||||
response.Error = &e
|
||||
return response
|
||||
}
|
||||
|
||||
subComponent := request.SubComponent
|
||||
switch subComponent {
|
||||
case configs.GetContext:
|
||||
err = fmt.Errorf("Subcomponent %s not implemented", request.SubComponent)
|
||||
case configs.GetEncryptionConfig:
|
||||
err = fmt.Errorf("Subcomponent %s not implemented", request.SubComponent)
|
||||
case configs.GetManagementConfig:
|
||||
err = fmt.Errorf("Subcomponent %s not implemented", request.SubComponent)
|
||||
case configs.GetManifest:
|
||||
err = fmt.Errorf("Subcomponent %s not implemented", request.SubComponent)
|
||||
case configs.GetCurrentContext:
|
||||
context := client.Config.CurrentContext
|
||||
message = &context
|
||||
case configs.GetContexts:
|
||||
response.Data = GetContexts(client)
|
||||
case configs.GetEncryptionConfigs:
|
||||
response.Data = GetEncryptionConfigs(client)
|
||||
case configs.GetManagementConfigs:
|
||||
response.Data = GetManagementConfigs(client)
|
||||
case configs.GetManifests:
|
||||
response.Data = GetManifests(client)
|
||||
case configs.Init:
|
||||
err = fmt.Errorf("Subcomponent %s not implemented", request.SubComponent)
|
||||
err = InitAirshipConfig(AirshipConfigPath)
|
||||
case configs.SetContext:
|
||||
err = fmt.Errorf("Subcomponent %s not implemented", request.SubComponent)
|
||||
response.Data, err = SetContext(client, request)
|
||||
str := fmt.Sprintf("Context '%s' has been modified", request.Name)
|
||||
message = &str
|
||||
case configs.SetEncryptionConfig:
|
||||
err = fmt.Errorf("Subcomponent %s not implemented", request.SubComponent)
|
||||
response.Data, err = SetEncryptionConfig(client, request)
|
||||
str := fmt.Sprintf("Encryption configuration '%s' has been modified", request.Name)
|
||||
message = &str
|
||||
case configs.SetManagementConfig:
|
||||
err = fmt.Errorf("Subcomponent %s not implemented", request.SubComponent)
|
||||
err = SetManagementConfig(client, request)
|
||||
str := fmt.Sprintf("Management configuration '%s' has been modified", request.Name)
|
||||
message = &str
|
||||
case configs.SetManifest:
|
||||
err = fmt.Errorf("Subcomponent %s not implemented", request.SubComponent)
|
||||
response.Data, err = SetManifest(client, request)
|
||||
str := fmt.Sprintf("Manifest '%s' has been modified", request.Name)
|
||||
message = &str
|
||||
case configs.UseContext:
|
||||
err = fmt.Errorf("Subcomponent %s not implemented", request.SubComponent)
|
||||
err = UseContext(client, request)
|
||||
default:
|
||||
err = fmt.Errorf("Subcomponent %s not found", request.SubComponent)
|
||||
}
|
||||
@ -67,3 +89,199 @@ func HandleConfigRequest(user *string, request configs.WsMessage) configs.WsMess
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
// InitAirshipConfig wrapper function for CTL's CreateConfig using the specified path
|
||||
func InitAirshipConfig(path *string) error {
|
||||
return ctlconfig.CreateConfig(*path)
|
||||
}
|
||||
|
||||
// Context wrapper struct to include context name with CTL's Context
|
||||
type Context struct {
|
||||
Name string `json:"name"`
|
||||
ctlconfig.Context
|
||||
}
|
||||
|
||||
// GetContexts returns a slice of wrapper Context structs so we know the name of each
|
||||
// for display in the UI
|
||||
func GetContexts(client *Client) []Context {
|
||||
contexts := []Context{}
|
||||
for name, context := range client.Config.Contexts {
|
||||
contexts = append(contexts, Context{
|
||||
name,
|
||||
ctlconfig.Context{
|
||||
NameInKubeconf: context.NameInKubeconf,
|
||||
Manifest: context.Manifest,
|
||||
EncryptionConfig: context.EncryptionConfig,
|
||||
ManagementConfiguration: context.ManagementConfiguration,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return contexts
|
||||
}
|
||||
|
||||
// Manifest wraps CTL's Manifest to include the manifest name
|
||||
type Manifest struct {
|
||||
Name string `json:"name"`
|
||||
Manifest *ctlconfig.Manifest `json:"manifest"`
|
||||
}
|
||||
|
||||
// GetManifests returns a slice of wrapper Manifest structs so we know the name of each
|
||||
// for display in the UI
|
||||
func GetManifests(client *Client) []Manifest {
|
||||
manifests := []Manifest{}
|
||||
|
||||
for name, manifest := range client.Config.Manifests {
|
||||
manifests = append(manifests, Manifest{
|
||||
Name: name,
|
||||
Manifest: manifest,
|
||||
})
|
||||
}
|
||||
|
||||
return manifests
|
||||
}
|
||||
|
||||
// ManagementConfig wrapper struct for CTL's ManagementConfiguration that
|
||||
// includes a name
|
||||
type ManagementConfig struct {
|
||||
Name string `json:"name"`
|
||||
ctlconfig.ManagementConfiguration
|
||||
}
|
||||
|
||||
// GetManagementConfigs function to retrieve all management configs
|
||||
func GetManagementConfigs(client *Client) []ManagementConfig {
|
||||
configs := []ManagementConfig{}
|
||||
for name, conf := range client.Config.ManagementConfiguration {
|
||||
configs = append(configs, ManagementConfig{
|
||||
name,
|
||||
ctlconfig.ManagementConfiguration{
|
||||
Insecure: conf.Insecure,
|
||||
SystemActionRetries: conf.SystemActionRetries,
|
||||
SystemRebootDelay: conf.SystemRebootDelay,
|
||||
Type: conf.Type,
|
||||
UseProxy: conf.UseProxy,
|
||||
},
|
||||
})
|
||||
}
|
||||
return configs
|
||||
}
|
||||
|
||||
// EncryptionConfig wrapper struct for CTL's EncryptionConfiguration that
|
||||
// includes a name
|
||||
type EncryptionConfig struct {
|
||||
Name string `json:"name"`
|
||||
ctlconfig.EncryptionConfig
|
||||
}
|
||||
|
||||
// GetEncryptionConfigs returns a slice of wrapper EncryptionConfig structs so we
|
||||
// know the name of each for display in the UI
|
||||
func GetEncryptionConfigs(client *Client) []EncryptionConfig {
|
||||
configs := []EncryptionConfig{}
|
||||
for name, config := range client.Config.EncryptionConfigs {
|
||||
configs = append(configs, EncryptionConfig{
|
||||
name,
|
||||
ctlconfig.EncryptionConfig{
|
||||
EncryptionKeyFileSource: config.EncryptionKeyFileSource,
|
||||
EncryptionKeySecretSource: config.EncryptionKeySecretSource,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return configs
|
||||
}
|
||||
|
||||
// SetContext wrapper function for CTL's RunSetContext, using a UI client
|
||||
func SetContext(client *Client, message configs.WsMessage) (bool, error) {
|
||||
bytes, err := json.Marshal(message.Data)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
var opts ctlconfig.ContextOptions
|
||||
err = json.Unmarshal(bytes, &opts)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = opts.Validate()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return ctlconfig.RunSetContext(&opts, client.Config, true)
|
||||
}
|
||||
|
||||
// SetEncryptionConfig wrapper function for CTL's RunSetEncryptionConfig, using a UI client
|
||||
func SetEncryptionConfig(client *Client, message configs.WsMessage) (bool, error) {
|
||||
bytes, err := json.Marshal(message.Data)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
var opts ctlconfig.EncryptionConfigOptions
|
||||
err = json.Unmarshal(bytes, &opts)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = opts.Validate()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return ctlconfig.RunSetEncryptionConfig(&opts, client.Config, true)
|
||||
}
|
||||
|
||||
// SetManagementConfig sets the specified management configuration with values
|
||||
// received from the frontend client
|
||||
// TODO(mfuller): there's currently no setter for this in the CTL config pkg
|
||||
// so we'll set the values manually and then persist the config
|
||||
func SetManagementConfig(client *Client, message configs.WsMessage) error {
|
||||
bytes, err := json.Marshal(message.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mCfg, found := client.Config.ManagementConfiguration[message.Name]; found {
|
||||
err = json.Unmarshal(bytes, mCfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = client.Config.PersistConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("Management configuration '%s' not found", message.Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetManifest wrapper function for CTL's RunSetManifest, using a UI client
|
||||
func SetManifest(client *Client, message configs.WsMessage) (bool, error) {
|
||||
bytes, err := json.Marshal(message.Data)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
var opts ctlconfig.ManifestOptions
|
||||
err = json.Unmarshal(bytes, &opts)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
log.Infof("Unmarshaled options: %+v", opts)
|
||||
err = opts.Validate()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return ctlconfig.RunSetManifest(&opts, client.Config, true)
|
||||
}
|
||||
|
||||
// UseContext wrapper function for CTL's RunUseConfig, using a UI client
|
||||
func UseContext(client *Client, message configs.WsMessage) error {
|
||||
return ctlconfig.RunUseContext(message.Name, client.Config)
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ func HandleDocumentRequest(user *string, request configs.WsMessage) configs.WsMe
|
||||
|
||||
func (c *Client) docPull() (*string, error) {
|
||||
var message *string
|
||||
cfgFactory := config.CreateFactory(AirshipConfigPath, KubeConfigPath)
|
||||
cfgFactory := config.CreateFactory(AirshipConfigPath)
|
||||
// 2nd arg is noCheckout, I assume we want to checkout the repo,
|
||||
// so setting to false
|
||||
err := pull.Pull(cfgFactory, false)
|
||||
|
@ -66,7 +66,7 @@ func HandleImageRequest(user *string, request configs.WsMessage) configs.WsMessa
|
||||
|
||||
// generate iso now just runs a phase and not an individual command
|
||||
func (c *Client) generateIso() (*string, error) {
|
||||
cfgFactory := config.CreateFactory(AirshipConfigPath, KubeConfigPath)
|
||||
cfgFactory := config.CreateFactory(AirshipConfigPath)
|
||||
p := &phase.RunCommand{
|
||||
Factory: cfgFactory,
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ func getHelper() (ifc.Helper, error) {
|
||||
return helper, nil
|
||||
}
|
||||
|
||||
c, err := NewDefaultClient(AirshipConfigPath, KubeConfigPath)
|
||||
c, err := NewDefaultClient(AirshipConfigPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ func InitConfig(t *testing.T) (conf *config.Config, configPath string,
|
||||
require.NoError(t, err)
|
||||
|
||||
conf = config.NewConfig()
|
||||
err = conf.LoadConfig(configPath, kubeConfigPath, false)
|
||||
err = conf.LoadConfig()
|
||||
require.NoError(t, err)
|
||||
return conf, configPath, kubeConfigPath, cleanup
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user