This commit is contained in:
Manuel Romero
2019-11-29 15:43:23 +01:00
parent 9e0a191ade
commit 2196bcbba2
9 changed files with 208 additions and 3 deletions

1
.gitignore vendored
View File

@@ -38,7 +38,6 @@ testem.log
Thumbs.db
**/*/proc-logs/*.log
provisions
**/*/.terraform*
**/*/terraform.tfstate*
scenarios_templates/azqmi-qseok/bin

View File

@@ -365,7 +365,10 @@ var ProvisionsComponent = /** @class */ (function () {
this.subscription.unsubscribe();
this.instantSubs.unsubscribe();
};
ProvisionsComponent.prototype.del = function () {
ProvisionsComponent.prototype.del = function (provision) {
this._provisionsService.delProvision({ "id": provision._id }).subscribe(function (res) {
console.log("Done!", res);
});
};
ProvisionsComponent.prototype.destroy = function (provision) {
this._provisionsService.newDestroy({ "id": provision._id }).subscribe(function (res) {
@@ -611,6 +614,9 @@ var ProvisionsService = /** @class */ (function () {
ProvisionsService.prototype.newProvision = function (body) {
return this.httpClient.post("/api/users/" + this._userId + "/provisions", body);
};
ProvisionsService.prototype.delProvision = function (id) {
return this.httpClient.delete("/provisions/" + id);
};
ProvisionsService.prototype.newDestroy = function (body) {
return this.httpClient.post("/api/users/" + this._userId + "/destroyprovisions", body);
};

File diff suppressed because one or more lines are too long

View File

@@ -214,6 +214,41 @@ router.get('/provisions/:id', passport.ensureAuthenticated, async (req, res, nex
}
});
/**
* @swagger
* /provisions/{id}:
* delete:
* description: Delete Provision by ID
* summary: Delete a Terraform Provision by ID
* produces:
* - application/json
* parameters:
* - name: id
* in: path
* type: string
* required: true
* responses:
* 200:
* description: Provision
* 404:
* description: Not found
*
*/
router.delete('/provisions/:id', passport.ensureAuthenticated, async (req, res, next) => {
try {
const mongoJob = await db.provision.getSingle(req.params.id);
if (!mongoJob){
return res.status(404).json({"msg": "Not found"});
}
const toDestroy = await db.destroy.get({"provId": req.params.id});
await db.destroy.del(toDestroy[0]._id.toStrong());
const delProv = await db.provision.del(req.params.id);
return res.json(delProv);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /provisions/{id}/logs:

View File

@@ -0,0 +1,46 @@
<app-logs *ngIf="logShow" (onClose)="onLogsClose()" [selectedprov]="selectedprov"></app-logs>
<div class="jumbotron">
<h1>QMI Scenarios</h1>
<app-scenarios (onStartProvision)="onStartProvision()"></app-scenarios>
</div>
<table class="table table-sm" style="margin-bottom: 100px;">
<thead class="thead-light">
<tr>
<th>Provision ID</th>
<th>Create Date</th>
<th>Scenario</th>
<th style="width: 150px;">Status</th>
<th>Terraform Project Path</th>
<th>Destroy ID</th>
<th>Status Destroy</th>
<th>Destroyed?</th>
<th></th>
</tr>
</thead>
<tr *ngFor="let provision of provisions; let i = index">
<td><a href (click)="showLogs($event, provision)" >{{ provision._id }}</a></td>
<td>{{provision.created | date: 'MMM dd, yyyy - H:mm'}}</td>
<td>{{ provision.scenario }}</td>
<td>
<span class="badge badge-secondary" [ngClass]="{'badge-warning': provision.status === 'provisioning' || provision.status === 'initializing', 'badge-success': provision.status === 'provisioned'}">{{provision.status}}</span>
<span *ngIf="provision.status === 'provisioning' || provision.status === 'initializing'" class="spinner-border spinner-border-sm text-warning" role="status">
<span class="sr-only"></span>
</span>
</td>
<td class="ell" title="{{provision.path}}" >{{provision.path}}</td>
<td>{{provision.destroyId? provision.destroyId : '-'}}</td>
<td>
<span class="badge badge-secondary" [ngClass]="{'badge-warning': provision.statusDestroy === 'destroying', 'badge-success': provision.statusDestroy === 'destroyed'}">{{provision.statusDestroy}}</span>
<span *ngIf="provision.statusDestroy === 'destroying'" class="spinner-border spinner-border-sm text-warning" role="status">
<span class="sr-only"></span>
</span>
</td>
<td>{{provision.isDestroyed}}</td>
<td>
<button title="Destroy provision" *ngIf="!provision.isDestroyed && provision.statusDestroy !== 'destroying'" (click)="destroy(provision)" class="btn btn-danger btn-sm"><i class="fa fa-window-close-o"></i></button>
<button title="Remove entry" *ngIf="provision.isDestroyed && provision.statusDestroy === 'destroyed'" (click)="del(provision)" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></button>
</td>
</tr>
</table>

View File

@@ -0,0 +1,6 @@
td.ell {
max-width: 150px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

View File

@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ProvisionsComponent } from './provisions.component';
describe('ProvisionsComponent', () => {
let component: ProvisionsComponent;
let fixture: ComponentFixture<ProvisionsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ProvisionsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProvisionsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,84 @@
import { Component, OnInit } from '@angular/core';
import { ProvisionsService } from '../services/provisions.service';
import { Subscription, timer} from 'rxjs';
import { switchMap } from 'rxjs/operators';
@Component({
selector: 'app-provisions',
templateUrl: './provisions.component.html',
styleUrls: ['./provisions.component.scss'],
providers: [ProvisionsService]
})
export class ProvisionsComponent implements OnInit {
provisions;
destroys;
subscription: Subscription;
instantSubs: Subscription;
logShow: boolean = false;
selectedprov: Object = null;
constructor(private _provisionsService: ProvisionsService) {}
private _compose(pair) {
this.destroys = pair['1'];
pair['0'].forEach(prov => {
var foundDes = this.destroys.filter(d=>{
return d.provId.toString() === prov._id.toString()
});
if (foundDes.length){
prov.destroyId = foundDes[0]._id.toString();
prov.statusDestroy = foundDes[0].status;
} else {
prov.destroyId = "-";
}
});
this.provisions = pair['0'];
}
ngOnInit() {
this.subscription = timer(0, 5000).pipe( switchMap(() => this._provisionsService.getCombinedProvisions() ) ).subscribe(pair => {
this._compose(pair);
})
}
ngOnDestroy() {
this.subscription.unsubscribe();
this.instantSubs.unsubscribe();
}
del(provision): void {
this._provisionsService.delProvision({"id": provision._id}).subscribe( res => {
console.log("Done!", res);
})
}
destroy(provision) : void{
this._provisionsService.newDestroy({"id": provision._id}).subscribe( res => {
console.log("Done!", res);
})
}
showLogs($event, provision): void {
this.logShow = false;
$event.preventDefault();
this.selectedprov = provision;
this.logShow = true;
}
onLogsClose($event): void {
this.selectedprov = null;
this.logShow = false;
}
onStartProvision($event): void {
console.log("onStartProvision");
this.instantSubs = this._provisionsService.getCombinedProvisions().subscribe( pair=>{
this._compose(pair);
this.instantSubs.unsubscribe();
})
}
}

View File

@@ -27,6 +27,10 @@ export class ProvisionsService {
return this.httpClient.post(`/api/users/${this._userId}/provisions`, body);
}
delProvision(id): Observable<any> {
return this.httpClient.delete(`/provisions/${id}`);
}
newDestroy(body) : Observable<any> {
return this.httpClient.post(`/api/users/${this._userId}/destroyprovisions`, body);
}