Add connection profile persistence to MIAA dashboard (#11061)

* wip

* fixes

* fix pg model

* more updates

* Add resourceType check
This commit is contained in:
Charles Gagnon
2020-06-23 16:36:09 -07:00
committed by GitHub
parent 9131653d71
commit 64dc9b365f
15 changed files with 278 additions and 132 deletions

View File

@@ -52,7 +52,7 @@ export class AzureArcTreeDataProvider implements vscode.TreeDataProvider<TreeNod
if (controllerNode) {
controllerNode.model.info = model.info;
} else {
this._controllerNodes.push(new ControllerTreeNode(model, this._context));
this._controllerNodes.push(new ControllerTreeNode(model, this._context, this));
}
await this.updatePassword(model, password);
if (refreshTree) {
@@ -95,7 +95,7 @@ export class AzureArcTreeDataProvider implements vscode.TreeDataProvider<TreeNod
const controllerMementos: ControllerInfo[] = this._context.globalState.get(mementoToken) || [];
this._controllerNodes = controllerMementos.map(memento => {
const controllerModel = new ControllerModel(this, memento);
return new ControllerTreeNode(controllerModel, this._context);
return new ControllerTreeNode(controllerModel, this._context, this);
});
} finally {
this._loading = false;
@@ -103,8 +103,9 @@ export class AzureArcTreeDataProvider implements vscode.TreeDataProvider<TreeNod
}
}
private async saveControllers(): Promise<void> {
await this._context.globalState.update(mementoToken, this._controllerNodes.map(node => node.model.info));
public async saveControllers(): Promise<void> {
const controllerInfo = this._controllerNodes.map(node => node.model.info);
await this._context.globalState.update(mementoToken, controllerInfo);
}
}

View File

@@ -8,23 +8,25 @@ import { TreeNode } from './treeNode';
import { MiaaTreeNode } from './miaaTreeNode';
import { ResourceType } from '../../constants';
import { PostgresTreeNode } from './postgresTreeNode';
import { ControllerModel, Registration } from '../../models/controllerModel';
import { ControllerModel, Registration, ResourceInfo } from '../../models/controllerModel';
import { ControllerDashboard } from '../dashboards/controller/controllerDashboard';
import { PostgresModel } from '../../models/postgresModel';
import { parseInstanceName } from '../../common/utils';
import { MiaaModel } from '../../models/miaaModel';
import { Deferred } from '../../common/promise';
import { RefreshTreeNode } from './refreshTreeNode';
import { ResourceTreeNode } from './resourceTreeNode';
import { AzureArcTreeDataProvider } from './azureArcTreeDataProvider';
/**
* The TreeNode for displaying an Azure Arc Controller
*/
export class ControllerTreeNode extends TreeNode {
private _children: TreeNode[] = [];
private _children: ResourceTreeNode[] = [];
private _childrenRefreshPromise = new Deferred();
constructor(public model: ControllerModel, private _context: vscode.ExtensionContext) {
constructor(public model: ControllerModel, private _context: vscode.ExtensionContext, private _treeDataProvider: AzureArcTreeDataProvider) {
super(model.info.url, vscode.TreeItemCollapsibleState.Collapsed, ResourceType.dataControllers);
model.onRegistrationsUpdated(registrations => this.refreshChildren(registrations));
}
@@ -51,21 +53,52 @@ export class ControllerTreeNode extends TreeNode {
}
private refreshChildren(registrations: Registration[]): void {
this._children = <TreeNode[]>registrations.map(registration => {
const newChildren: ResourceTreeNode[] = [];
registrations.forEach(registration => {
if (!registration.instanceNamespace || !registration.instanceName) {
console.warn('Registration is missing required namespace and name values, skipping');
return undefined;
return;
}
switch (registration.instanceType) {
case ResourceType.postgresInstances:
const postgresModel = new PostgresModel(this.model.info.url, this.model.auth!, registration.instanceNamespace, parseInstanceName(registration.instanceName));
return new PostgresTreeNode(postgresModel, this.model, this._context);
case ResourceType.sqlManagedInstances:
const miaaModel = new MiaaModel(this.model.info.url, this.model.auth!, registration.instanceNamespace, parseInstanceName(registration.instanceName));
return new MiaaTreeNode(miaaModel, this.model);
const resourceInfo: ResourceInfo = {
namespace: registration.instanceNamespace,
name: parseInstanceName(registration.instanceName),
resourceType: registration.instanceType ?? ''
};
let node = this._children.find(n =>
n.model?.info?.name === resourceInfo.name &&
n.model?.info?.namespace === resourceInfo.namespace &&
n.model?.info?.resourceType === resourceInfo.resourceType);
// If we don't have this child already then create a new node for it
if (!node) {
// If we had a stored connectionId copy that over
resourceInfo.connectionId = this.model.info.resources.find(info =>
info.namespace === resourceInfo.namespace &&
info.name === resourceInfo.name &&
info.resourceType === resourceInfo.resourceType)?.connectionId;
switch (registration.instanceType) {
case ResourceType.postgresInstances:
const postgresModel = new PostgresModel(this.model.info.url, this.model.auth!, resourceInfo, registration);
node = new PostgresTreeNode(postgresModel, this.model, this._context);
break;
case ResourceType.sqlManagedInstances:
const miaaModel = new MiaaModel(this.model.info.url, this.model.auth!, resourceInfo, registration, this._treeDataProvider);
node = new MiaaTreeNode(miaaModel, this.model);
break;
}
}
return undefined;
}).filter(item => item); // filter out invalid nodes (controllers or ones without required properties)
if (node) {
newChildren.push(node);
}
});
this._children = newChildren;
// Update our model info too
this.model.info.resources = <ResourceInfo[]>this._children.map(c => c.model?.info).filter(c => c);
this._treeDataProvider.saveControllers();
this._childrenRefreshPromise.resolve();
}
}

View File

@@ -15,14 +15,14 @@ import { MiaaDashboard } from '../dashboards/miaa/miaaDashboard';
*/
export class MiaaTreeNode extends TreeNode {
constructor(private _model: MiaaModel, private _controllerModel: ControllerModel) {
super(_model.name, vscode.TreeItemCollapsibleState.None, ResourceType.sqlManagedInstances);
constructor(public model: MiaaModel, private _controllerModel: ControllerModel) {
super(model.info.name, vscode.TreeItemCollapsibleState.None, ResourceType.sqlManagedInstances);
}
public async openDashboard(): Promise<void> {
const miaaDashboard = new MiaaDashboard(this._controllerModel, this._model);
const miaaDashboard = new MiaaDashboard(this._controllerModel, this.model);
await Promise.all([
miaaDashboard.showDashboard(),
this._model.refresh()]);
this.model.refresh()]);
}
}

View File

@@ -5,18 +5,18 @@
import * as vscode from 'vscode';
import { ResourceType } from '../../constants';
import { TreeNode } from './treeNode';
import { PostgresModel } from '../../models/postgresModel';
import { ControllerModel } from '../../models/controllerModel';
import { PostgresDashboard } from '../dashboards/postgres/postgresDashboard';
import { ResourceTreeNode } from './resourceTreeNode';
/**
* The TreeNode for displaying an Postgres Server group
*/
export class PostgresTreeNode extends TreeNode {
export class PostgresTreeNode extends ResourceTreeNode {
constructor(private _model: PostgresModel, private _controllerModel: ControllerModel, private _context: vscode.ExtensionContext) {
super(_model.name, vscode.TreeItemCollapsibleState.None, ResourceType.postgresInstances);
super(_model.name, vscode.TreeItemCollapsibleState.None, ResourceType.postgresInstances, _model);
}
public async openDashboard(): Promise<void> {

View File

@@ -0,0 +1,17 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { ResourceModel } from '../../models/resourceModel';
import { TreeNode } from './treeNode';
/**
* A TreeNode belonging to a child of a Controller
*/
export abstract class ResourceTreeNode extends TreeNode {
constructor(label: string, collapsibleState: vscode.TreeItemCollapsibleState, resourceType?: string, public model?: ResourceModel) {
super(label, collapsibleState, resourceType);
}
}