edge upgrade instructions ui implementation

This commit is contained in:
deaflynx 2023-11-22 16:59:21 +02:00
parent 855b9c054b
commit 7fad29e059
8 changed files with 95 additions and 23 deletions

View File

@ -36,6 +36,7 @@ enum EdgeVersion {
V_3_4_0 = 2;
V_3_6_0 = 3;
V_3_6_1 = 4;
V_3_6_2 = 5;
}
/**

View File

@ -21,7 +21,7 @@ import { HttpClient } from '@angular/common/http';
import { PageLink, TimePageLink } from '@shared/models/page/page-link';
import { PageData } from '@shared/models/page/page-data';
import { EntitySubtype } from '@app/shared/models/entity-type.models';
import { Edge, EdgeEvent, EdgeInfo, EdgeInstallInstructions, EdgeSearchQuery } from '@shared/models/edge.models';
import { Edge, EdgeEvent, EdgeInfo, EdgeInstructions, EdgeSearchQuery } from '@shared/models/edge.models';
import { EntityId } from '@shared/models/id/entity-id';
import { BulkImportRequest, BulkImportResult } from '@home/components/import-export/import-export.models';
@ -114,7 +114,11 @@ export class EdgeService {
return this.http.post<BulkImportResult>('/api/edge/bulk_import', entitiesData, defaultHttpOptionsFromConfig(config));
}
public getEdgeInstallInstructions(edgeId: string, method: string = 'ubuntu', config?: RequestConfig): Observable<EdgeInstallInstructions> {
return this.http.get<EdgeInstallInstructions>(`/api/edge/instructions/${edgeId}/${method}`, defaultHttpOptionsFromConfig(config));
public getEdgeInstallInstructions(edgeId: string, method: string = 'ubuntu', config?: RequestConfig): Observable<EdgeInstructions> {
return this.http.get<EdgeInstructions>(`/api/edge/instructions/install/${edgeId}/${method}`, defaultHttpOptionsFromConfig(config));
}
public getEdgeUpgradeInstructions(edgeVersion: string, method: string = 'ubuntu', config?: RequestConfig): Observable<EdgeInstructions> {
return this.http.get<EdgeInstructions>(`/api/edge/instructions/upgrade/${edgeVersion}/${method}`, defaultHttpOptionsFromConfig(config));
}
}

View File

@ -21,12 +21,21 @@ import { AppState } from '@core/core.state';
import { Router } from '@angular/router';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { ActionPreferencesPutUserSettings } from '@core/auth/auth.actions';
import { EdgeInfo, EdgeInstructionsMethod } from '@shared/models/edge.models';
import {
EdgeInfo,
EdgeInstructions,
EdgeInstructionsMethod,
edgeVersionAttributeKey
} from '@shared/models/edge.models';
import { EdgeService } from '@core/http/edge.service';
import { AttributeService } from '@core/http/attribute.service';
import { AttributeScope } from '@shared/models/telemetry/telemetry.models';
import { mergeMap, Observable } from 'rxjs';
export interface EdgeInstructionsDialogData {
edge: EdgeInfo;
afterAdd: boolean;
upgradeAvailable: boolean;
}
@Component({
@ -49,6 +58,7 @@ export class EdgeInstructionsDialogComponent extends DialogComponent<EdgeInstruc
protected router: Router,
@Inject(MAT_DIALOG_DATA) private data: EdgeInstructionsDialogData,
public dialogRef: MatDialogRef<EdgeInstructionsDialogComponent>,
private attributeService: AttributeService,
private edgeService: EdgeService) {
super(store, router, dialogRef);
@ -85,12 +95,22 @@ export class EdgeInstructionsDialogComponent extends DialogComponent<EdgeInstruc
getInstructions(method: string) {
if (!this.contentData[method]) {
this.loadedInstructions = false;
this.edgeService.getEdgeInstallInstructions(this.data.edge.id.id, method).subscribe(
res => {
this.contentData[method] = res.installInstructions;
this.loadedInstructions = true;
let edgeInstructions$: Observable<EdgeInstructions>;
if (this.data.upgradeAvailable) {
edgeInstructions$ = this.attributeService.getEntityAttributes(this.data.edge.id, AttributeScope.SERVER_SCOPE, [edgeVersionAttributeKey])
.pipe(mergeMap(attributes => {
if (attributes.length) {
const edgeVersion = attributes[0].value;
return this.edgeService.getEdgeUpgradeInstructions(edgeVersion, method);
}
);
}));
} else {
edgeInstructions$ = this.edgeService.getEdgeInstallInstructions(this.data.edge.id.id, method);
}
edgeInstructions$.subscribe(res => {
this.contentData[method] = res.instructions;
this.loadedInstructions = true;
});
}
}
}

View File

@ -114,13 +114,26 @@
</button>
</div>
<div fxLayout="row" fxLayout.xs="column">
<div [ngSwitch]="upgradeAvailable">
<ng-container *ngSwitchCase="false">
<button mat-raised-button color="primary"
[disabled]="(isLoading$ | async)"
(click)="onEntityAction($event, 'openInstructions')"
(click)="onEntityAction($event, 'openInstallInstructions')"
[fxShow]="!isEdit && edgeScope !== 'customer_user'">
<mat-icon>info_outline</mat-icon>
<span>{{ 'edge.install-connect-instructions' | translate }}</span>
</button>
</ng-container>
<ng-container *ngSwitchCase="true">
<button mat-raised-button color="primary"
[disabled]="(isLoading$ | async)"
(click)="onEntityAction($event, 'openUpgradeInstructions')"
[fxShow]="!isEdit && edgeScope !== 'customer_user'">
<mat-icon>info_outline</mat-icon>
<span>{{ 'edge.upgrade-instructions' | translate }}</span>
</button>
</ng-container>
</div>
</div>
</div>
<div class="mat-padding" fxLayout="column">

View File

@ -20,12 +20,15 @@ import { AppState } from '@core/core.state';
import { EntityComponent } from '@home/components/entity/entity.component';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { EntityType } from '@shared/models/entity-type.models';
import { EdgeInfo } from '@shared/models/edge.models';
import { EdgeInfo, edgeVersionAttributeKey } from '@shared/models/edge.models';
import { TranslateService } from '@ngx-translate/core';
import { NULL_UUID } from '@shared/models/id/has-uuid';
import { ActionNotificationShow } from '@core/notification/notification.actions';
import { generateSecret, guid } from '@core/utils';
import { EntityTableConfig } from '@home/models/entity/entities-table-config.models';
import { environment as env } from '@env/environment';
import { AttributeService } from '@core/http/attribute.service';
import { AttributeScope } from '@shared/models/telemetry/telemetry.models';
@Component({
selector: 'tb-edge',
@ -37,9 +40,11 @@ export class EdgeComponent extends EntityComponent<EdgeInfo> {
entityType = EntityType;
edgeScope: 'tenant' | 'customer' | 'customer_user';
upgradeAvailable: boolean = false;
constructor(protected store: Store<AppState>,
protected translate: TranslateService,
private attributeService: AttributeService,
@Inject('entity') protected entityValue: EdgeInfo,
@Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig<EdgeInfo>,
public fb: UntypedFormBuilder,
@ -95,6 +100,7 @@ export class EdgeComponent extends EntityComponent<EdgeInfo> {
}
});
this.generateRoutingKeyAndSecret(entity, this.entityForm);
this.checkEdgeVersion();
}
updateFormState() {
@ -133,4 +139,25 @@ export class EdgeComponent extends EntityComponent<EdgeInfo> {
form.get('secret').patchValue(generateSecret(20), {emitEvent: false});
}
}
checkEdgeVersion() {
this.attributeService.getEntityAttributes(this.entity.id, AttributeScope.SERVER_SCOPE, [edgeVersionAttributeKey])
.subscribe(attributes => {
if (attributes?.length) {
const edgeVersion = attributes[0].value;
const tbVersion = 'V_' + env.tbVersion.replaceAll('.', '_');
this.upgradeAvailable = this.versionUpgradeSupported(edgeVersion) && (edgeVersion !== tbVersion);
} else {
this.upgradeAvailable = false;
}
}
);
}
private versionUpgradeSupported(edgeVersion: string): boolean {
const edgeVersionArray = edgeVersion.split('_');
const major = parseInt(edgeVersionArray[1]);
const minor = parseInt(edgeVersionArray[2]);
return major >= 3 && minor >= 6;
}
}

View File

@ -558,7 +558,7 @@ export class EdgesTableConfigResolver implements Resolve<EntityTableConfig<EdgeI
);
}
openInstructions($event, edge: EdgeInfo, afterAdd = false) {
openInstructions($event, edge: EdgeInfo, afterAdd = false, upgradeAvailable = false) {
if ($event) {
$event.stopPropagation();
}
@ -568,7 +568,8 @@ export class EdgesTableConfigResolver implements Resolve<EntityTableConfig<EdgeI
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
data: {
edge,
afterAdd
afterAdd,
upgradeAvailable
}
}).afterClosed().subscribe(() => {
if (afterAdd) {
@ -610,9 +611,12 @@ export class EdgesTableConfigResolver implements Resolve<EntityTableConfig<EdgeI
case 'syncEdge':
this.syncEdge(action.event, action.entity);
return true;
case 'openInstructions':
case 'openInstallInstructions':
this.openInstructions(action.event, action.entity);
return true;
case 'openUpgradeInstructions':
this.openInstructions(action.event, action.entity,false, true);
return true;
}
}

View File

@ -178,8 +178,8 @@ export interface EdgeEvent extends BaseData<EventId> {
body: string;
}
export interface EdgeInstallInstructions {
installInstructions: string;
export interface EdgeInstructions {
instructions: string;
}
export enum EdgeInstructionsMethod {
@ -187,3 +187,5 @@ export enum EdgeInstructionsMethod {
centos,
docker
}
export const edgeVersionAttributeKey = 'edgeVersion';

View File

@ -2017,6 +2017,7 @@
"sync-process-started-successfully": "Sync process started successfully!",
"missing-related-rule-chains-title": "Edge has missing related rule chain(s)",
"missing-related-rule-chains-text": "Assigned to edge rule chain(s) use rule nodes that forward message(s) to rule chain(s) that are not assigned to this edge. <br><br> List of missing rule chain(s): <br> {{missingRuleChains}}",
"upgrade-instructions": "Upgrade Instructions",
"widget-datasource-error": "This widget supports only EDGE entity datasource"
},
"edge-event": {