Remove REST API from Arc extension (#11888)

* wip

* Remove old API

* Fix tests
This commit is contained in:
Charles Gagnon
2020-08-20 15:56:46 -07:00
committed by GitHub
parent 9c81db574e
commit b2a1738836
209 changed files with 550 additions and 15997 deletions

View File

@@ -9,7 +9,7 @@ import * as loc from '../../../localizedConstants';
import { DashboardPage } from '../../components/dashboardPage';
import { IconPathHelper, cssStyles, iconSize, ResourceType, Endpoints } from '../../../constants';
import { ControllerModel } from '../../../models/controllerModel';
import { resourceTypeToDisplayName, getResourceTypeIcon, getConnectionModeDisplayText, parseInstanceName } from '../../../common/utils';
import { resourceTypeToDisplayName, getResourceTypeIcon, parseInstanceName } from '../../../common/utils';
export class ControllerDashboardOverviewPage extends DashboardPage {
@@ -167,10 +167,12 @@ export class ControllerDashboardOverviewPage extends DashboardPage {
this.disposables.push(
openInAzurePortalButton.onDidClick(async () => {
const r = this._controllerModel.controllerRegistration;
if (r) {
const config = this._controllerModel.controllerConfig;
if (config) {
/* TODO CHGAGNON CONFIG
vscode.env.openExternal(vscode.Uri.parse(
`https://portal.azure.com/#resource/subscriptions/${r.subscriptionId}/resourceGroups/${r.resourceGroupName}/providers/Microsoft.AzureData/${ResourceType.dataControllers}/${r.instanceName}`));
`https://portal.azure.com/#resource/subscriptions/${config.subscriptionId}/resourceGroups/${config.resourceGroupName}/providers/Microsoft.AzureData/${ResourceType.dataControllers}/${config.instanceName}`));
*/
} else {
vscode.window.showErrorMessage(loc.couldNotFindRegistration(this._controllerModel.namespace, 'controller'));
}
@@ -186,17 +188,17 @@ export class ControllerDashboardOverviewPage extends DashboardPage {
}
private handleRegistrationsUpdated(): void {
const reg = this._controllerModel.controllerRegistration;
this.controllerProperties.instanceName = reg?.instanceName || this.controllerProperties.instanceName;
this.controllerProperties.resourceGroupName = reg?.resourceGroupName || this.controllerProperties.resourceGroupName;
this.controllerProperties.location = reg?.region || this.controllerProperties.location;
this.controllerProperties.subscriptionId = reg?.subscriptionId || this.controllerProperties.subscriptionId;
this.controllerProperties.connectionMode = getConnectionModeDisplayText(reg?.connectionMode) || this.controllerProperties.connectionMode;
this.controllerProperties.instanceNamespace = reg?.instanceNamespace || this.controllerProperties.instanceNamespace;
const config = this._controllerModel.controllerConfig;
this.controllerProperties.instanceName = config?.metadata.name || this.controllerProperties.instanceName;
this.controllerProperties.resourceGroupName = /* TODO CHGAGNON RG */ this.controllerProperties.resourceGroupName;
this.controllerProperties.location = /* TODO CHGAGNON LOCATION */ this.controllerProperties.location;
this.controllerProperties.subscriptionId = /* TODO CHGAGNON LOCATION */ this.controllerProperties.subscriptionId;
this.controllerProperties.connectionMode = /* TODO CHGAGNON MODE getConnectionModeDisplayText(config?.connectionMode) || */ this.controllerProperties.connectionMode;
this.controllerProperties.instanceNamespace = config?.metadata.namespace || this.controllerProperties.instanceNamespace;
this.refreshDisplayedProperties();
this._arcResourcesTable.data = this._controllerModel.registrations
.filter(r => r.instanceType !== ResourceType.dataControllers && !r.isDeleted)
.filter(r => r.instanceType !== ResourceType.dataControllers)
.map(r => {
const iconPath = getResourceTypeIcon(r.instanceType ?? '');
const imageComponent = this.modelView.modelBuilder.image()
@@ -213,9 +215,11 @@ export class ControllerDashboardOverviewPage extends DashboardPage {
url: ''
}).component();
nameLink.onDidClick(async () => {
await this._controllerModel.treeDataProvider.openResourceDashboard(this._controllerModel, r.instanceType || '', r.instanceNamespace || '', parseInstanceName(r.instanceName));
// TODO chgagnon
await this._controllerModel.treeDataProvider.openResourceDashboard(this._controllerModel, r.instanceType || '', /* r.instanceNamespace || */ '', parseInstanceName(r.instanceName));
});
return [imageComponent, nameLink, resourceTypeToDisplayName(r.instanceType), loc.numVCores(r.vCores)];
// TODO chgagnon
return [imageComponent, nameLink, resourceTypeToDisplayName(r.instanceType), '-'/* loc.numVCores(r.vCores) */];
});
this._arcResourcesLoadingComponent.loading = !this._controllerModel.registrationsLastUpdated;
}

View File

@@ -5,17 +5,16 @@
import * as azdata from 'azdata';
import * as loc from '../../../localizedConstants';
import { IconPathHelper, cssStyles, ResourceType } from '../../../constants';
import { KeyValueContainer, KeyValue, InputKeyValue, MultilineInputKeyValue } from '../../components/keyValueContainer';
import { IconPathHelper, cssStyles } from '../../../constants';
import { KeyValueContainer, KeyValue } from '../../components/keyValueContainer';
import { DashboardPage } from '../../components/dashboardPage';
import { ControllerModel } from '../../../models/controllerModel';
import { MiaaModel } from '../../../models/miaaModel';
export class MiaaConnectionStringsPage extends DashboardPage {
private _keyValueContainer!: KeyValueContainer;
constructor(modelView: azdata.ModelView, private _controllerModel: ControllerModel, private _miaaModel: MiaaModel) {
constructor(modelView: azdata.ModelView, private _controllerModel: ControllerModel) {
super(modelView);
this.disposables.push(this._controllerModel.onRegistrationsUpdated(_ =>
this.eventuallyRunOnInitialized(() => this.updateConnectionStrings())));
@@ -64,6 +63,7 @@ export class MiaaConnectionStringsPage extends DashboardPage {
}
private getConnectionStrings(): KeyValue[] {
/*
const instanceRegistration = this._controllerModel.getRegistration(ResourceType.sqlManagedInstances, this._miaaModel.info.namespace, this._miaaModel.info.name);
if (!instanceRegistration) {
return [];
@@ -87,6 +87,8 @@ $conn = sqlsrv_connect($serverName, $connectionInfo);`),
new InputKeyValue(this.modelView.modelBuilder, 'Ruby', `host=${ip}; user=${username} password={your_password_here} port=${port} sslmode=require`),
new InputKeyValue(this.modelView.modelBuilder, 'Web App', `Database=master; Data Source=${ip}; User Id=${username}; Password={your_password_here}`)
];
*/
return [];
}
private updateConnectionStrings(): void {

View File

@@ -26,7 +26,7 @@ export class MiaaDashboard extends Dashboard {
protected async registerTabs(modelView: azdata.ModelView): Promise<(azdata.DashboardTab | azdata.DashboardTabGroup)[]> {
const overviewPage = new MiaaDashboardOverviewPage(modelView, this._controllerModel, this._miaaModel);
const connectionStringsPage = new MiaaConnectionStringsPage(modelView, this._controllerModel, this._miaaModel);
const connectionStringsPage = new MiaaConnectionStringsPage(modelView, this._controllerModel);
return [
overviewPage.tab,
{

View File

@@ -7,9 +7,9 @@ import * as azdata from 'azdata';
import * as vscode from 'vscode';
import * as loc from '../../../localizedConstants';
import { DashboardPage } from '../../components/dashboardPage';
import { IconPathHelper, cssStyles, ResourceType, Endpoints } from '../../../constants';
import { IconPathHelper, cssStyles, Endpoints } from '../../../constants';
import { ControllerModel } from '../../../models/controllerModel';
import { promptForResourceDeletion, getDatabaseStateDisplayText } from '../../../common/utils';
import { getDatabaseStateDisplayText } from '../../../common/utils';
import { MiaaModel } from '../../../models/miaaModel';
export class MiaaDashboardOverviewPage extends DashboardPage {
@@ -41,7 +41,7 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
this.disposables.push(
this._controllerModel.onRegistrationsUpdated(() => this.handleRegistrationsUpdated()),
this._controllerModel.onEndpointsUpdated(() => this.eventuallyRunOnInitialized(() => this.handleEndpointsUpdated())),
this._miaaModel.onStatusUpdated(() => this.eventuallyRunOnInitialized(() => this.handleMiaaStatusUpdated())),
this._miaaModel.onConfigUpdated(() => this.eventuallyRunOnInitialized(() => this.handleMiaaConfigUpdated())),
this._miaaModel.onDatabasesUpdated(() => this.eventuallyRunOnInitialized(() => this.handleDatabasesUpdated()))
);
}
@@ -99,7 +99,7 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
// Update loaded components with data
this.handleRegistrationsUpdated();
this.handleMiaaStatusUpdated();
this.handleMiaaConfigUpdated();
this.handleEndpointsUpdated();
this.handleDatabasesUpdated();
@@ -182,10 +182,12 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
deleteButton.onDidClick(async () => {
deleteButton.enabled = false;
try {
/* TODO chgagnon enable delete
if (await promptForResourceDeletion(this._miaaModel.info.namespace, this._miaaModel.info.name)) {
await this._controllerModel.miaaDelete(this._miaaModel.info.namespace, this._miaaModel.info.name);
vscode.window.showInformationMessage(loc.resourceDeleted(this._miaaModel.info.name));
}
*/
} catch (error) {
vscode.window.showErrorMessage(loc.resourceDeletionFailed(this._miaaModel.info.name, error));
} finally {
@@ -221,6 +223,7 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
this.disposables.push(
openInAzurePortalButton.onDidClick(async () => {
/* TODO chgagnon enable open in Azure
const r = this._controllerModel.getRegistration(ResourceType.sqlManagedInstances, this._miaaModel.info.namespace, this._miaaModel.info.name);
if (r) {
vscode.env.openExternal(vscode.Uri.parse(
@@ -228,6 +231,7 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
} else {
vscode.window.showErrorMessage(loc.couldNotFindRegistration(this._miaaModel.info.namespace, this._miaaModel.info.name));
}
*/
}));
return this.modelView.modelBuilder.toolbarContainer().withToolbarItems(
@@ -240,20 +244,23 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
}
private handleRegistrationsUpdated(): void {
const reg = this._controllerModel.getRegistration(ResourceType.sqlManagedInstances, this._miaaModel.info.namespace, this._miaaModel.info.name);
// TODO chgagnon
/*
const reg = this._controllerModel.getRegistration(ResourceType.sqlManagedInstances, this._miaaModel.info.namespace || '', this._miaaModel.info.name);
if (reg) {
this._instanceProperties.resourceGroup = reg.resourceGroupName || '-';
this._instanceProperties.dataController = this._controllerModel.controllerRegistration?.instanceName || '-';
this._instanceProperties.dataController = this._controllerModel.controllerConfig?.metadata.name || '-';
this._instanceProperties.region = reg.region || '-';
this._instanceProperties.subscriptionId = reg.subscriptionId || '-';
this._instanceProperties.vCores = reg.vCores || '';
this._instanceProperties.host = reg.externalEndpoint || '-';
this.refreshDisplayedProperties();
}
*/
}
private handleMiaaStatusUpdated(): void {
this._instanceProperties.status = this._miaaModel.status;
private handleMiaaConfigUpdated(): void {
this._instanceProperties.status = this._miaaModel.config?.status.state || '-';
this.refreshDisplayedProperties();
}
@@ -320,7 +327,7 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
this._propertiesLoading.loading =
!this._controllerModel.registrationsLastUpdated &&
!this._miaaModel.statusLastUpdated &&
!this._miaaModel.configLastUpdated &&
!this._miaaModel.databasesLastUpdated;
}
}

View File

@@ -35,7 +35,7 @@ export class PostgresDashboard extends Dashboard {
const propertiesPage = new PostgresPropertiesPage(modelView, this._controllerModel, this._postgresModel);
const resourceHealthPage = new PostgresResourceHealthPage(modelView, this._postgresModel);
const diagnoseAndSolveProblemsPage = new PostgresDiagnoseAndSolveProblemsPage(modelView, this._context, this._postgresModel);
const supportRequestPage = new PostgresSupportRequestPage(modelView, this._controllerModel, this._postgresModel);
const supportRequestPage = new PostgresSupportRequestPage(modelView);
return [
overviewPage.tab,

View File

@@ -6,12 +6,11 @@
import * as vscode from 'vscode';
import * as azdata from 'azdata';
import * as loc from '../../../localizedConstants';
import { IconPathHelper, cssStyles, ResourceType, Endpoints } from '../../../constants';
import { V1Pod, DuskyObjectModelsDatabaseServiceArcPayload } from '../../../controller/generated/dusky/api';
import { IconPathHelper, cssStyles, Endpoints } from '../../../constants';
import { DashboardPage } from '../../components/dashboardPage';
import { ControllerModel } from '../../../models/controllerModel';
import { PostgresModel, PodRole } from '../../../models/postgresModel';
import { promptForResourceDeletion, promptAndConfirmPassword } from '../../../common/utils';
import { PostgresModel } from '../../../models/postgresModel';
import { promptAndConfirmPassword } from '../../../common/utils';
export class PostgresOverviewPage extends DashboardPage {
@@ -207,7 +206,8 @@ export class PostgresOverviewPage extends DashboardPage {
const password = await promptAndConfirmPassword(input => !input ? loc.enterANonEmptyPassword : '');
if (password) {
await this._postgresModel.update(s => {
s.arc = s.arc ?? new DuskyObjectModelsDatabaseServiceArcPayload();
// TODO chgagnon
// s.arc = s.arc ?? new DuskyObjectModelsDatabaseServiceArcPayload();
s.arc.servicePassword = password;
});
vscode.window.showInformationMessage(loc.passwordReset);
@@ -229,11 +229,13 @@ export class PostgresOverviewPage extends DashboardPage {
deleteButton.onDidClick(async () => {
deleteButton.enabled = false;
try {
/*
if (await promptForResourceDeletion(this._postgresModel.namespace, this._postgresModel.name)) {
await this._postgresModel.delete();
await this._controllerModel.deleteRegistration(ResourceType.postgresInstances, this._postgresModel.namespace, this._postgresModel.name);
vscode.window.showInformationMessage(loc.resourceDeleted(this._postgresModel.fullName));
}
*/
} catch (error) {
vscode.window.showErrorMessage(loc.resourceDeletionFailed(this._postgresModel.fullName, error));
} finally {
@@ -276,6 +278,7 @@ export class PostgresOverviewPage extends DashboardPage {
this.disposables.push(
openInAzurePortalButton.onDidClick(async () => {
/*
const r = this._controllerModel.getRegistration(ResourceType.postgresInstances, this._postgresModel.namespace, this._postgresModel.name);
if (!r) {
vscode.window.showErrorMessage(loc.couldNotFindAzureResource(this._postgresModel.fullName));
@@ -283,6 +286,7 @@ export class PostgresOverviewPage extends DashboardPage {
vscode.env.openExternal(vscode.Uri.parse(
`https://portal.azure.com/#resource/subscriptions/${r.subscriptionId}/resourceGroups/${r.resourceGroupName}/providers/Microsoft.AzureData/${ResourceType.postgresInstances}/${r.instanceName}`));
}
*/
}));
return this.modelView.modelBuilder.toolbarContainer().withToolbarItems([
@@ -294,6 +298,7 @@ export class PostgresOverviewPage extends DashboardPage {
}
private getProperties(): azdata.PropertiesContainerItem[] {
/*
const registration = this._controllerModel.getRegistration(ResourceType.postgresInstances, this._postgresModel.namespace, this._postgresModel.name);
const endpoint: { ip?: string, port?: number } = this._postgresModel.endpoint;
@@ -307,6 +312,8 @@ export class PostgresOverviewPage extends DashboardPage {
{ displayName: loc.subscriptionId, value: registration?.subscriptionId ?? '' },
{ displayName: loc.postgresVersion, value: this._postgresModel.service?.spec?.engine?.version?.toString() ?? '' }
];
*/
return [];
}
private getKibanaLink(): string {
@@ -321,8 +328,8 @@ export class PostgresOverviewPage extends DashboardPage {
}
private getNodes(): string[][] {
/* TODO chgagnon
const endpoint: { ip?: string, port?: number } = this._postgresModel.endpoint;
return this._postgresModel.pods?.map((pod: V1Pod) => {
const name = pod.metadata?.name ?? '';
const role: PodRole | undefined = PostgresModel.getPodRole(pod);
@@ -336,6 +343,8 @@ export class PostgresOverviewPage extends DashboardPage {
role === PodRole.Router ? `${endpoint.ip}:${endpoint.port}` : internalDns
];
}) ?? [];
*/
return [];
}
private handleEndpointsUpdated() {

View File

@@ -6,8 +6,8 @@
import * as vscode from 'vscode';
import * as azdata from 'azdata';
import * as loc from '../../../localizedConstants';
import { IconPathHelper, cssStyles, ResourceType } from '../../../constants';
import { KeyValueContainer, InputKeyValue, TextKeyValue, KeyValue } from '../../components/keyValueContainer';
import { IconPathHelper, cssStyles } from '../../../constants';
import { KeyValueContainer, KeyValue } from '../../components/keyValueContainer';
import { DashboardPage } from '../../components/dashboardPage';
import { ControllerModel } from '../../../models/controllerModel';
import { PostgresModel } from '../../../models/postgresModel';
@@ -91,6 +91,7 @@ export class PostgresPropertiesPage extends DashboardPage {
}
private getProperties(): KeyValue[] {
/*
const endpoint: { ip?: string, port?: number } = this._postgresModel.endpoint;
const connectionString = `postgresql://postgres@${endpoint.ip}:${endpoint.port}`;
const registration = this._controllerModel.getRegistration(ResourceType.postgresInstances, this._postgresModel.namespace, this._postgresModel.name);
@@ -106,6 +107,8 @@ export class PostgresPropertiesPage extends DashboardPage {
new TextKeyValue(this.modelView.modelBuilder, loc.resourceGroup, registration?.resourceGroupName ?? ''),
new TextKeyValue(this.modelView.modelBuilder, loc.subscriptionId, registration?.subscriptionId ?? '')
];
*/
return [];
}
private handleRegistrationsUpdated() {

View File

@@ -191,6 +191,7 @@ export class PostgresResourceHealthPage extends DashboardPage {
}
private getConditionsTable(): (string | azdata.ImageComponent)[][] {
/* TODO chgagnon
return this._postgresModel.service?.status?.conditions?.map(c => {
const healthy = c.type === 'Ready' ? c.status === 'True' : c.status === 'False';
@@ -209,6 +210,8 @@ export class PostgresResourceHealthPage extends DashboardPage {
c.lastTransitionTime ? fromNow(c.lastTransitionTime!, true) : ''
];
}) ?? [];
*/
return [];
}
private handleServiceUpdated() {

View File

@@ -3,16 +3,13 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as azdata from 'azdata';
import * as loc from '../../../localizedConstants';
import { IconPathHelper, cssStyles, ResourceType } from '../../../constants';
import { IconPathHelper, cssStyles } from '../../../constants';
import { DashboardPage } from '../../components/dashboardPage';
import { ControllerModel } from '../../../models/controllerModel';
import { PostgresModel } from '../../../models/postgresModel';
export class PostgresSupportRequestPage extends DashboardPage {
constructor(protected modelView: azdata.ModelView, private _controllerModel: ControllerModel, private _postgresModel: PostgresModel) {
constructor(protected modelView: azdata.ModelView) {
super(modelView);
}
@@ -51,6 +48,7 @@ export class PostgresSupportRequestPage extends DashboardPage {
this.disposables.push(
supportRequestButton.onDidClick(() => {
/*
const r = this._controllerModel.getRegistration(ResourceType.postgresInstances, this._postgresModel.namespace, this._postgresModel.name);
if (!r) {
vscode.window.showErrorMessage(loc.couldNotFindAzureResource(this._postgresModel.fullName));
@@ -58,6 +56,7 @@ export class PostgresSupportRequestPage extends DashboardPage {
vscode.env.openExternal(vscode.Uri.parse(
`https://portal.azure.com/#resource/subscriptions/${r.subscriptionId}/resourceGroups/${r.resourceGroupName}/providers/Microsoft.AzureData/${ResourceType.postgresInstances}/${r.instanceName}/supportrequest`));
}
*/
}));
content.addItem(supportRequestButton);

View File

@@ -121,12 +121,12 @@ export class ConnectToControllerDialog extends InitializingComponent {
rememberPassword: this.rememberPwCheckBox.checked ?? false,
resources: []
};
const controllerModel = new ControllerModel(this._treeDataProvider, controllerInfo, this.passwordInputBox.value);
const controllerModel = new ControllerModel(this._treeDataProvider, controllerInfo);
try {
// Validate that we can connect to the controller, this also populates the controllerRegistration from the connection response.
await controllerModel.refresh(false);
// default info.name to the name of the controller instance if the user did not specify their own and to a pre-canned default if for some weird reason controller endpoint returned instanceName is also not a valid value
controllerModel.info.name = controllerModel.info.name || controllerModel.controllerRegistration?.instanceName || loc.defaultControllerName;
controllerModel.info.name = controllerModel.info.name || controllerModel.controllerConfig?.metadata.name || loc.defaultControllerName;
} catch (err) {
vscode.window.showErrorMessage(loc.connectToControllerFailed(this.urlInputBox.value, err));
return false;

View File

@@ -77,38 +77,35 @@ export class ControllerTreeNode extends TreeNode {
private refreshChildren(registrations: Registration[]): void {
const newChildren: ResourceTreeNode[] = [];
registrations.filter(r => !r.isDeleted).forEach(registration => {
if (!registration.instanceNamespace || !registration.instanceName) {
console.warn('Registration is missing required namespace and name values, skipping');
registrations.forEach(registration => {
if (!registration.instanceName) {
console.warn('Registration is missing required name value, skipping');
return;
}
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);
const postgresModel = new PostgresModel(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);
const miaaModel = new MiaaModel(resourceInfo, registration, this._treeDataProvider);
node = new MiaaTreeNode(miaaModel, this.model);
break;
}