diff --git a/extensions/arc/src/common/utils.ts b/extensions/arc/src/common/utils.ts index f0f1e493a2..825e9d1d7e 100644 --- a/extensions/arc/src/common/utils.ts +++ b/extensions/arc/src/common/utils.ts @@ -148,12 +148,11 @@ async function promptInputBox(title: string, options: vscode.InputBoxOptions): P /** * Opens an input box prompting the user to enter in the name of a resource to delete - * @param namespace The namespace of the resource to delete * @param name The name of the resource to delete * @returns Promise resolving to true if the user confirmed the name, false if the input box was closed for any other reason */ -export async function promptForResourceDeletion(namespace: string, name: string): Promise { - const title = loc.resourceDeletionWarning(namespace, name); +export async function promptForResourceDeletion(name: string): Promise { + const title = loc.resourceDeletionWarning(name); const options: vscode.InputBoxOptions = { placeHolder: name, validateInput: input => input !== name ? loc.invalidResourceDeletionName(name) : '' diff --git a/extensions/arc/src/localizedConstants.ts b/extensions/arc/src/localizedConstants.ts index 3cac845ad6..b3240a578f 100644 --- a/extensions/arc/src/localizedConstants.ts +++ b/extensions/arc/src/localizedConstants.ts @@ -149,7 +149,7 @@ export function fetchEndpointsFailed(name: string, error: any): string { return export function fetchRegistrationsFailed(name: string, error: any): string { return localize('arc.fetchRegistrationsFailed', "An unexpected error occurred retrieving the registrations for '{0}'. {1}", name, getErrorMessage(error)); } export function fetchDatabasesFailed(name: string, error: any): string { return localize('arc.fetchDatabasesFailed', "An unexpected error occurred retrieving the databases for '{0}'. {1}", name, getErrorMessage(error)); } export function couldNotFindRegistration(namespace: string, name: string) { return localize('arc.couldNotFindRegistration', "Could not find controller registration for {0} ({1})", name, namespace); } -export function resourceDeletionWarning(namespace: string, name: string): string { return localize('arc.resourceDeletionWarning', "Warning! Deleting a resource is permanent and cannot be undone. To delete the resource '{0}.{1}' type the name '{1}' below to proceed.", namespace, name); } +export function resourceDeletionWarning(name: string): string { return localize('arc.resourceDeletionWarning', "Warning! Deleting a resource is permanent and cannot be undone. To delete the resource '{0}' type the name '{0}' below to proceed.", name); } export function invalidResourceDeletionName(name: string): string { return localize('arc.invalidResourceDeletionName', "The value '{0}' does not match the instance name. Try again or press escape to exit", name); } export function couldNotFindAzureResource(name: string): string { return localize('arc.couldNotFindAzureResource', "Could not find Azure resource for {0}", name); } export function passwordResetFailed(error: any): string { return localize('arc.passwordResetFailed', "Failed to reset password. {0}", getErrorMessage(error)); } diff --git a/extensions/arc/src/models/controllerModel.ts b/extensions/arc/src/models/controllerModel.ts index d5aa8cf273..c5d64a6fe5 100644 --- a/extensions/arc/src/models/controllerModel.ts +++ b/extensions/arc/src/models/controllerModel.ts @@ -3,12 +3,12 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as azdataExt from 'azdata-ext'; import * as vscode from 'vscode'; import { parseInstanceName, UserCancelledError } from '../common/utils'; import { ResourceType } from '../constants'; import { AzureArcTreeDataProvider } from '../ui/tree/azureArcTreeDataProvider'; import * as loc from '../localizedConstants'; -import * as azdataExt from '../../../azdata/src/typings/azdata-ext'; import { ConnectToControllerDialog } from '../ui/dialogs/connectControllerDialog'; export type ControllerInfo = { @@ -22,7 +22,6 @@ export type ControllerInfo = { export type ResourceInfo = { name: string, resourceType: ResourceType | string, - namespace?: string, connectionId?: string }; @@ -55,7 +54,11 @@ export class ControllerModel { this._azdataApi = vscode.extensions.getExtension(azdataExt.extension.name)?.exports; } - public async refresh(showErrors: boolean = true, promptReconnect: boolean = false): Promise { + /** + * Calls azdata login to set the context to this controller + * @param promptReconnect + */ + public async azdataLogin(promptReconnect: boolean = false): Promise { // We haven't gotten our password yet or we want to prompt for a reconnect if (!this._password || promptReconnect) { this._password = ''; @@ -70,6 +73,7 @@ export class ControllerModel { const model = await dialog.waitForClose(); if (model) { this.treeDataProvider.addOrUpdateController(model.controllerModel, model.password, false); + this._password = model.password; } else { throw new UserCancelledError(); } @@ -77,7 +81,21 @@ export class ControllerModel { } await this._azdataApi.login(this.info.url, this.info.username, this._password); + } + /** + * Refreshes the Tree Node for this model. This will also result in the model being refreshed. + */ + public async refreshTreeNode(): Promise { + const node = this.treeDataProvider.getControllerNode(this); + if (node) { + this.treeDataProvider.refreshNode(node); + } else { + await this.refresh(false); + } + } + public async refresh(showErrors: boolean = true, promptReconnect: boolean = false): Promise { + await this.azdataLogin(promptReconnect); this._registrations = []; await Promise.all([ this._azdataApi.dc.config.show().then(result => { @@ -156,8 +174,7 @@ export class ControllerModel { public getRegistration(type: ResourceType, name: string): Registration | undefined { return this._registrations.find(r => { - // TODO chgagnon namespace - return r.instanceType === type && /* r.instanceNamespace === namespace && */ parseInstanceName(r.instanceName) === name; + return r.instanceType === type && parseInstanceName(r.instanceName) === name; }); } @@ -170,17 +187,6 @@ export class ControllerModel { */ } - /** - * Deletes the specified MIAA resource from the controller - * @param namespace The namespace of the resource - * @param name The name of the resource - */ - public async miaaDelete(name: string): Promise { - // TODO chgagnon Fix delete - //await this._sqlInstanceRouter.apiV1HybridSqlNsNameDelete(namespace, name); - await this.deleteRegistration(ResourceType.sqlManagedInstances, name); - } - /** * Tests whether this model is for the same controller as another * @param other The other instance to test diff --git a/extensions/arc/src/models/miaaModel.ts b/extensions/arc/src/models/miaaModel.ts index 7d9aea521a..10e86f19fb 100644 --- a/extensions/arc/src/models/miaaModel.ts +++ b/extensions/arc/src/models/miaaModel.ts @@ -4,14 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import * as azdata from 'azdata'; +import * as azdataExt from 'azdata-ext'; import * as vscode from 'vscode'; import { ResourceModel } from './resourceModel'; -import { ResourceInfo, Registration } from './controllerModel'; +import { ResourceInfo, Registration, ControllerModel } from './controllerModel'; import { AzureArcTreeDataProvider } from '../ui/tree/azureArcTreeDataProvider'; import { Deferred } from '../common/promise'; import * as loc from '../localizedConstants'; import { UserCancelledError } from '../common/utils'; -import * as azdataExt from '../../../azdata/src/typings/azdata-ext'; export type DatabaseModel = { name: string, status: string }; @@ -34,7 +34,7 @@ export class MiaaModel extends ResourceModel { private _refreshPromise: Deferred | undefined = undefined; - constructor(info: ResourceInfo, registration: Registration, private _treeDataProvider: AzureArcTreeDataProvider) { + constructor(private _controllerModel: ControllerModel, info: ResourceInfo, registration: Registration, private _treeDataProvider: AzureArcTreeDataProvider) { super(info, registration); this._azdataApi = vscode.extensions.getExtension(azdataExt.extension.name)?.exports; } @@ -73,6 +73,7 @@ export class MiaaModel extends ResourceModel { } this._refreshPromise = new Deferred(); try { + await this._controllerModel.azdataLogin(); const instanceRefresh = this._azdataApi.sql.mi.show(this.info.name).then(result => { this._config = result.result; this.configLastUpdated = new Date(); diff --git a/extensions/arc/src/models/postgresModel.ts b/extensions/arc/src/models/postgresModel.ts index 1573d2dd90..bd0852f27d 100644 --- a/extensions/arc/src/models/postgresModel.ts +++ b/extensions/arc/src/models/postgresModel.ts @@ -93,7 +93,7 @@ export class PostgresModel extends ResourceModel { /** Returns the service's Kubernetes namespace */ public get namespace(): string | undefined { - return this.info.namespace; + return ''; // TODO chgagnon return this.info.namespace; } /** Returns the service's name */ @@ -103,7 +103,7 @@ export class PostgresModel extends ResourceModel { /** Returns the service's fully qualified name in the format namespace.name */ public get fullName(): string { - return `${this.info.namespace}.${this.info.name}`; + return `${this.namespace}.${this.name}`; } /** Returns the service's spec */ diff --git a/extensions/arc/src/test/common/utils.test.ts b/extensions/arc/src/test/common/utils.test.ts index 8b8689c25c..8418702951 100644 --- a/extensions/arc/src/test/common/utils.test.ts +++ b/extensions/arc/src/test/common/utils.test.ts @@ -139,7 +139,7 @@ describe('promptForResourceDeletion Method Tests', function (): void { }); it('Resolves as true when value entered is correct', function (done): void { - promptForResourceDeletion('mynamespace', 'myname').then((value: boolean) => { + promptForResourceDeletion('myname').then((value: boolean) => { value ? done() : done(new Error('Expected return value to be true')); }); mockInputBox.value = 'myname'; @@ -147,14 +147,14 @@ describe('promptForResourceDeletion Method Tests', function (): void { }); it('Resolves as false when input box is closed early', function (done): void { - promptForResourceDeletion('mynamespace', 'myname').then((value: boolean) => { + promptForResourceDeletion('myname').then((value: boolean) => { !value ? done() : done(new Error('Expected return value to be false')); }); mockInputBox.hide(); }); it('Validation message is set when value entered is incorrect', async function (): Promise { - promptForResourceDeletion('mynamespace', 'myname'); + promptForResourceDeletion('myname'); mockInputBox.value = 'wrong value'; await mockInputBox.triggerAccept(); should(mockInputBox.validationMessage).not.be.equal('', 'Validation message should not be empty after incorrect value entered'); diff --git a/extensions/arc/src/typings/refs.d.ts b/extensions/arc/src/typings/refs.d.ts index bc3ed06ab5..c0d0cf7a85 100644 --- a/extensions/arc/src/typings/refs.d.ts +++ b/extensions/arc/src/typings/refs.d.ts @@ -7,3 +7,4 @@ /// /// /// +/// diff --git a/extensions/arc/src/ui/dashboards/controller/controllerDashboardOverviewPage.ts b/extensions/arc/src/ui/dashboards/controller/controllerDashboardOverviewPage.ts index 0305275320..dbd85d4a93 100644 --- a/extensions/arc/src/ui/dashboards/controller/controllerDashboardOverviewPage.ts +++ b/extensions/arc/src/ui/dashboards/controller/controllerDashboardOverviewPage.ts @@ -162,7 +162,8 @@ export class ControllerDashboardOverviewPage extends DashboardPage { const openInAzurePortalButton = this.modelView.modelBuilder.button().withProperties({ label: loc.openInAzurePortal, - iconPath: IconPathHelper.openInTab + iconPath: IconPathHelper.openInTab, + enabled: false }).component(); this.disposables.push( @@ -215,8 +216,7 @@ export class ControllerDashboardOverviewPage extends DashboardPage { url: '' }).component(); nameLink.onDidClick(async () => { - // TODO chgagnon - await this._controllerModel.treeDataProvider.openResourceDashboard(this._controllerModel, r.instanceType || '', /* r.instanceNamespace || */ '', parseInstanceName(r.instanceName)); + await this._controllerModel.treeDataProvider.openResourceDashboard(this._controllerModel, r.instanceType || '', parseInstanceName(r.instanceName)); }); // TODO chgagnon return [imageComponent, nameLink, resourceTypeToDisplayName(r.instanceType), '-'/* loc.numVCores(r.vCores) */]; diff --git a/extensions/arc/src/ui/dashboards/miaa/miaaDashboardOverviewPage.ts b/extensions/arc/src/ui/dashboards/miaa/miaaDashboardOverviewPage.ts index c57ca4e821..318e558c92 100644 --- a/extensions/arc/src/ui/dashboards/miaa/miaaDashboardOverviewPage.ts +++ b/extensions/arc/src/ui/dashboards/miaa/miaaDashboardOverviewPage.ts @@ -4,12 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import * as azdata from 'azdata'; +import * as azdataExt from 'azdata-ext'; import * as vscode from 'vscode'; import * as loc from '../../../localizedConstants'; import { DashboardPage } from '../../components/dashboardPage'; import { IconPathHelper, cssStyles, Endpoints } from '../../../constants'; import { ControllerModel } from '../../../models/controllerModel'; -import { getDatabaseStateDisplayText } from '../../../common/utils'; +import { getDatabaseStateDisplayText, promptForResourceDeletion } from '../../../common/utils'; import { MiaaModel } from '../../../models/miaaModel'; export class MiaaDashboardOverviewPage extends DashboardPage { @@ -24,6 +25,8 @@ export class MiaaDashboardOverviewPage extends DashboardPage { private _grafanaLink!: azdata.HyperlinkComponent; private _databasesTable!: azdata.DeclarativeTableComponent; + private readonly _azdataApi: azdataExt.IExtension; + private _instanceProperties = { resourceGroup: '-', status: '-', @@ -37,6 +40,8 @@ export class MiaaDashboardOverviewPage extends DashboardPage { constructor(modelView: azdata.ModelView, private _controllerModel: ControllerModel, private _miaaModel: MiaaModel) { super(modelView); + this._azdataApi = vscode.extensions.getExtension(azdataExt.extension.name)?.exports; + this._instanceProperties.miaaAdmin = this._miaaModel.username || this._instanceProperties.miaaAdmin; this.disposables.push( this._controllerModel.onRegistrationsUpdated(() => this.handleRegistrationsUpdated()), @@ -182,12 +187,11 @@ 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); + if (await promptForResourceDeletion(this._miaaModel.info.name)) { + await this._azdataApi.sql.mi.delete(this._miaaModel.info.name); + await this._controllerModel.refreshTreeNode(); vscode.window.showInformationMessage(loc.resourceDeleted(this._miaaModel.info.name)); } - */ } catch (error) { vscode.window.showErrorMessage(loc.resourceDeletionFailed(this._miaaModel.info.name, error)); } finally { @@ -266,7 +270,7 @@ export class MiaaDashboardOverviewPage extends DashboardPage { private handleEndpointsUpdated(): void { const kibanaEndpoint = this._controllerModel.getEndpoint(Endpoints.logsui); - const kibanaQuery = `kubernetes_namespace:"${this._miaaModel.info.namespace}" and instance_name :"${this._miaaModel.info.name}"`; + const kibanaQuery = `kubernetes_namespace:"${this._miaaModel.config?.metadata.namespace}" and instance_name :"${this._miaaModel.config?.metadata.name}"`; const kibanaUrl = kibanaEndpoint ? `${kibanaEndpoint.endpoint}/app/kibana#/discover?_a=(query:(language:kuery,query:'${kibanaQuery}'))` : ''; this._kibanaLink.label = kibanaUrl; this._kibanaLink.url = kibanaUrl; diff --git a/extensions/arc/src/ui/tree/azureArcTreeDataProvider.ts b/extensions/arc/src/ui/tree/azureArcTreeDataProvider.ts index d317e6e022..1c5e325786 100644 --- a/extensions/arc/src/ui/tree/azureArcTreeDataProvider.ts +++ b/extensions/arc/src/ui/tree/azureArcTreeDataProvider.ts @@ -51,7 +51,7 @@ export class AzureArcTreeDataProvider implements vscode.TreeDataProvider { - const controllerNode = this._controllerNodes.find(node => model.equals(node.model)); + const controllerNode = this.getControllerNode(model); if (controllerNode) { controllerNode.model.info = model.info; } else { @@ -64,6 +64,10 @@ export class AzureArcTreeDataProvider implements vscode.TreeDataProvider model.equals(node.model)); + } + public async removeController(controllerNode: ControllerTreeNode): Promise { this._controllerNodes = this._controllerNodes.filter(node => node !== controllerNode); this._onDidChangeTreeData.fire(undefined); @@ -115,17 +119,16 @@ export class AzureArcTreeDataProvider implements vscode.TreeDataProvider { + public async openResourceDashboard(controllerModel: ControllerModel, resourceType: string, name: string): Promise { const controllerNode = this._controllerNodes.find(n => n.model === controllerModel); if (controllerNode) { - const resourceNode = controllerNode.getResourceNode(resourceType, namespace, name); + const resourceNode = controllerNode.getResourceNode(resourceType, name); if (resourceNode) { } else { - console.log(`Couldn't find resource node for ${namespace}.${name} (${resourceType})`); + console.log(`Couldn't find resource node for ${name} (${resourceType})`); } await resourceNode?.openDashboard(); } else { diff --git a/extensions/arc/src/ui/tree/controllerTreeNode.ts b/extensions/arc/src/ui/tree/controllerTreeNode.ts index 64108f14fd..d1d2670405 100644 --- a/extensions/arc/src/ui/tree/controllerTreeNode.ts +++ b/extensions/arc/src/ui/tree/controllerTreeNode.ts @@ -13,7 +13,6 @@ import { ControllerDashboard } from '../dashboards/controller/controllerDashboar import { PostgresModel } from '../../models/postgresModel'; import { parseInstanceName, UserCancelledError } 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'; @@ -25,24 +24,20 @@ import * as loc from '../../localizedConstants'; export class ControllerTreeNode extends TreeNode { private _children: ResourceTreeNode[] = []; - private _childrenRefreshPromise = new Deferred(); constructor(public model: ControllerModel, private _context: vscode.ExtensionContext, private _treeDataProvider: AzureArcTreeDataProvider) { super(model.label, vscode.TreeItemCollapsibleState.Collapsed, ResourceType.dataControllers); - model.onRegistrationsUpdated(registrations => this.refreshChildren(registrations)); } public async getChildren(): Promise { - // First reset our deferred promise so we're sure we'll get the refreshed children - this._childrenRefreshPromise = new Deferred(); try { await this.model.refresh(false); - await this._childrenRefreshPromise.promise; + this.updateChildren(this.model.registrations); } catch (err) { vscode.window.showErrorMessage(loc.errorConnectingToController(err)); try { await this.model.refresh(false, true); - await this._childrenRefreshPromise.promise; + this.updateChildren(this.model.registrations); } catch (err) { if (!(err instanceof UserCancelledError)) { vscode.window.showErrorMessage(loc.errorConnectingToController(err)); @@ -65,17 +60,15 @@ export class ControllerTreeNode extends TreeNode { /** * Finds and returns the ResourceTreeNode specified if it exists, otherwise undefined * @param resourceType The resourceType of the node - * @param namespace The namespace of the node * @param name The name of the node */ - public getResourceNode(resourceType: string, namespace: string, name: string): ResourceTreeNode | undefined { + public getResourceNode(resourceType: string, name: string): ResourceTreeNode | undefined { return this._children.find(c => c.model?.info.resourceType === resourceType && - c.model?.info.namespace === namespace && c.model.info.name === name); } - private refreshChildren(registrations: Registration[]): void { + private updateChildren(registrations: Registration[]): void { const newChildren: ResourceTreeNode[] = []; registrations.forEach(registration => { if (!registration.instanceName) { @@ -105,7 +98,7 @@ export class ControllerTreeNode extends TreeNode { node = new PostgresTreeNode(postgresModel, this.model, this._context); break; case ResourceType.sqlManagedInstances: - const miaaModel = new MiaaModel(resourceInfo, registration, this._treeDataProvider); + const miaaModel = new MiaaModel(this.model, resourceInfo, registration, this._treeDataProvider); node = new MiaaTreeNode(miaaModel, this.model); break; } @@ -119,6 +112,5 @@ export class ControllerTreeNode extends TreeNode { // Update our model info too this.model.info.resources = this._children.map(c => c.model?.info).filter(c => c); this._treeDataProvider.saveControllers(); - this._childrenRefreshPromise.resolve(); } } diff --git a/extensions/azdata/src/azdata.ts b/extensions/azdata/src/azdata.ts index 91af9162f6..4d2e01c476 100644 --- a/extensions/azdata/src/azdata.ts +++ b/extensions/azdata/src/azdata.ts @@ -3,13 +3,13 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { AzdataOutput } from 'azdata-ext'; import * as os from 'os'; import * as vscode from 'vscode'; import { HttpClient } from './common/httpClient'; import * as loc from './localizedConstants'; import { executeCommand, executeSudoCommand, ExitCodeError } from './common/childProcess'; import { searchForCmd } from './common/utils'; -import { AzdataOutput } from './typings/azdata-ext'; export const azdataHostname = 'https://aka.ms'; export const azdataUri = 'azdata-msi'; diff --git a/extensions/azdata/src/extension.ts b/extensions/azdata/src/extension.ts index 6297791fc4..1058ee7d28 100644 --- a/extensions/azdata/src/extension.ts +++ b/extensions/azdata/src/extension.ts @@ -3,13 +3,13 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as azdata from './typings/azdata-ext'; +import * as azdataExt from 'azdata-ext'; import * as vscode from 'vscode'; import { findAzdata, IAzdataTool } from './azdata'; let localAzdata: IAzdataTool | undefined = undefined; -export async function activate(): Promise { +export async function activate(): Promise { const outputChannel = vscode.window.createOutputChannel('azdata'); localAzdata = await checkForAzdata(outputChannel); return { @@ -40,6 +40,9 @@ export async function activate(): Promise { }, sql: { mi: { + delete: async (name: string) => { + return executeLocalAzdataCommand(['arc', 'sql', 'mi', 'delete', '-n', name]); + }, list: async () => { return executeLocalAzdataCommand(['arc', 'sql', 'mi', 'list']); }, @@ -51,7 +54,7 @@ export async function activate(): Promise { }; } -async function executeLocalAzdataCommand(args: string[], additionalEnvVars?: { [key: string]: string }): Promise> { +async function executeLocalAzdataCommand(args: string[], additionalEnvVars?: { [key: string]: string }): Promise> { if (!localAzdata) { throw new Error('No azdata'); } diff --git a/extensions/azdata/src/typings/azdata-ext.d.ts b/extensions/azdata/src/typings/azdata-ext.d.ts index 615fe7bfbe..a5459b83fd 100644 --- a/extensions/azdata/src/typings/azdata-ext.d.ts +++ b/extensions/azdata/src/typings/azdata-ext.d.ts @@ -3,221 +3,218 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -/** - * Covers defining what the azdata extension exports to other extensions - * - * IMPORTANT: THIS IS NOT A HARD DEFINITION unlike vscode; therefore no enums or classes should be defined here - * (const enums get evaluated when typescript -> javascript so those are fine) - */ -export const enum extension { - name = 'Microsoft.azdata' -} +declare module 'azdata-ext' { + /** + * Covers defining what the azdata extension exports to other extensions + * + * IMPORTANT: THIS IS NOT A HARD DEFINITION unlike vscode; therefore no enums or classes should be defined here + * (const enums get evaluated when typescript -> javascript so those are fine) + */ + export const enum extension { + name = 'Microsoft.azdata' + } -export interface DcEndpointListResult { - description: string, - endpoint: string, - name: string, - protocol: string -} + export interface DcEndpointListResult { + description: string, // "Management Proxy" + endpoint: string, // "https://10.91.86.39:30777" + name: string, // "mgmtproxy" + protocol: string // "https" + } -export interface SqlMiListResult { - name: string, - replicas: string, - serverEndpoint: string, - state: string -} + export interface SqlMiListResult { + name: string, // "arc-miaa" + replicas: string, // "1/1" + serverEndpoint: string, + state: string // "Ready" + } -export interface PostgresServerListResult { - name: string, - state: string, - workers: number -} + export interface PostgresServerListResult { + name: string, // "arc-pg" + state: string, // "Ready" + workers: number // 1 + } -export interface DcConfigShowResult { - apiVersion: string, - kind: string, - metadata: { - creationTimestamp: string, - generation: number, - name: string, - namespace: string, - resourceVersion: string, - selfLink: string, - uid: string - }, - spec: { - credentials: { - controllerAdmin: string, - dockerRegistry: string, - serviceAccount: string + export interface DcConfigShowResult { + apiVersion: string, // "arcdata.microsoft.com/v1alpha1" + kind: string, // "DataController" + metadata: { + creationTimestamp: string, // "2020-08-19T17:05:39Z" + generation: number, // /1 + name: string, // "arc" + namespace: string, // "arc" + resourceVersion: string, // "200369" + selfLink: string, // "/apis/arcdata.microsoft.com/v1alpha1/namespaces/arc/datacontrollers/arc" + uid: string// "da72ed34-ee51-4bf0-b5c9-b0753834c5c1" }, - docker: { - imagePullPolicy: string, - imageTag: string, - registry: string, - repository: string - }, - security: { - allowDumps: string, - allowNodeMetricsCollection: boolean, - allowPodMetricsCollection: boolean, - allowRunAsRoot: false - }, - services: [ - { - name: string, - port: number, - serviceType: string - }, - { - name: string, - port: number, - serviceType: string - } - ], - settings: { + spec: { + credentials: { + controllerAdmin: string, // "controller-login-secret" + dockerRegistry: string, // "mssql-private-registry" + serviceAccount: string, // "sa-mssql-controller" + }, + docker: { + imagePullPolicy: string, // "Always" + imageTag: string, // "15.0.2000.41811_5" + registry: string, // "hlsaris.azurecr.io" + repository: string // "aris-p-master-dsmain-standard" + }, + security: { + allowDumps: boolean, // true, + allowNodeMetricsCollection: boolean // true + allowPodMetricsCollection: boolean, // true + allowRunAsRoot: boolean // false + }, + services: { + name: string, // "controller" + port: number, // 30080 + serviceType: string // "NodePort" + }[], + settings: { ElasticSearch: { - 'vm.max_map_count': string + 'vm.max_map_count': string // "-1" }, controller: { - enableBilling: string, - 'logs.rotation.days': string, - 'logs.rotation.size': string + 'enableBilling': string, // "True" + 'logs.rotation.days': string, // "7" + 'logs.rotation.size': string, // "5000" } - }, - storage: { + }, + storage: { data: { - accessMode: string, - className: string, - size: string + accessMode: string, // "ReadWriteOnce" + className: string, // "local-storage" + size: string, // "15Gi" }, logs: { - accessMode: string, - className: string, - size: string + accessMode: string, // "ReadWriteOnce" + className: string, // "local-storage" + size: string, // "10Gi" } - } - }, - status: { - state: string - } -} - -export interface SqlMiShowResult { - apiVersion: string, // "sql.arcdata.microsoft.com/v1alpha1" - kind: string, // "sqlmanagedinstance" - metadata: { - creationTimestamp: string, // "2020-08-19T17:35:45Z" - generation: number, // 1 - name: string, // "miaa-instance" - namespace: string, // "arc" - resourceVersion: string, // "202623" - selfLink: string, // "/apis/sql.arcdata.microsoft.com/v1alpha1/namespaces/arc/sqlmanagedinstances/miaa-instance" - uid: string // "cea737aa-3f82-4f6a-9bed-2b51c2c33dff" - }, - spec: { - storage: { - data: { - className: string, // "local-storage" - size: string // "5Gi" - }, - logs: { - className: string, // "local-storage" - size: string // "5Gi" - } - } - }, - status: { - readyReplicas: string, // "1/1" - state: string // "Ready" - } -} - -export interface PostgresServerShowResult { - apiVersion: string, // "arcdata.microsoft.com/v1alpha1" - kind: string, // "postgresql-12" - metadata: { - creationTimestamp: string, // "2020-08-19T20:25:11Z" - generation: number, // 1 - name: string, // "chgagnon-pg" - namespace: string, // "arc", - resourceVersion: string, // "214944", - selfLink: string, // "/apis/arcdata.microsoft.com/v1alpha1/namespaces/arc/postgresql-12s/chgagnon-pg", - uid: string, // "26d0f5bb-0c0b-4225-a6b5-5be2bf6feac0" - }, - spec: { - backups: { - deltaMinutes: number, // 3, - fullMinutes: number, // 10, - tiers: [ - { - retention: { - maximums: string[], // [ "6", "512MB" ], - minimums: string[], // [ "3" ] - }, - storage: { - volumeSize: string, // "1Gi" - } - } - ] + } }, - scale: { - shards: number // 1 + status: { + state: string, // "Ready" + } + } + + export interface SqlMiShowResult { + apiVersion: string, // "sql.arcdata.microsoft.com/v1alpha1" + kind: string, // "sqlmanagedinstance" + metadata: { + creationTimestamp: string, // "2020-08-19T17:35:45Z" + generation: number, // 1 + name: string, // "miaa-instance" + namespace: string, // "arc" + resourceVersion: string, // "202623" + selfLink: string, // "/apis/sql.arcdata.microsoft.com/v1alpha1/namespaces/arc/sqlmanagedinstances/miaa-instance" + uid: string // "cea737aa-3f82-4f6a-9bed-2b51c2c33dff" }, - scheduling: { - default: { - resources: { - requests: { - memory: string, // "256Mi" - } + spec: { + storage: { + data: { + className: string, // "local-storage" + size: string // "5Gi" + }, + logs: { + className: string, // "local-storage" + size: string // "5Gi" } } }, - storage: { - data: { - className: string, // "local-storage", - size: string // "5Gi" + status: { + readyReplicas: string, // "1/1" + state: string // "Ready" + } + } + + export interface PostgresServerShowResult { + apiVersion: string, // "arcdata.microsoft.com/v1alpha1" + kind: string, // "postgresql-12" + metadata: { + creationTimestamp: string, // "2020-08-19T20:25:11Z" + generation: number, // 1 + name: string, // "chgagnon-pg" + namespace: string, // "arc", + resourceVersion: string, // "214944", + selfLink: string, // "/apis/arcdata.microsoft.com/v1alpha1/namespaces/arc/postgresql-12s/chgagnon-pg", + uid: string, // "26d0f5bb-0c0b-4225-a6b5-5be2bf6feac0" + }, + spec: { + backups: { + deltaMinutes: number, // 3, + fullMinutes: number, // 10, + tiers: [ + { + retention: { + maximums: string[], // [ "6", "512MB" ], + minimums: string[], // [ "3" ] + }, + storage: { + volumeSize: string, // "1Gi" + } + } + ] }, - logs: { - className: string, // "local-storage", - size: string // "5Gi" + scale: { + shards: number // 1 + }, + scheduling: { + default: { + resources: { + requests: { + memory: string, // "256Mi" + } + } + } + }, + storage: { + data: { + className: string, // "local-storage", + size: string // "5Gi" + }, + logs: { + className: string, // "local-storage", + size: string // "5Gi" + } + } + }, + status: { + readyPods: string, // "1/1", + state: string // "Ready" + } + } + + export interface AzdataOutput { + logs: string[], + result: R, + stderr: string[], + stdout: string[], + code?: number + } + + export interface IExtension { + dc: { + endpoint: { + list(): Promise> + }, + config: { + show(): Promise> + } + }, + login(endpoint: string, username: string, password: string): Promise>, + postgres: { + server: { + list(): Promise>, + show(name: string): Promise> + } + }, + sql: { + mi: { + delete(name: string): Promise>, + list(): Promise>, + show(name: string): Promise> } } - }, - status: { - readyPods: string, // "1/1", - state: string // "Ready" } } -export interface AzdataOutput { - logs: string[], - result: R, - stderr: string[], - stdout: string[], - code?: number -} - -export interface IExtension { - dc: { - endpoint: { - list(): Promise> - }, - config: { - show(): Promise> - } - }, - login(endpoint: string, username: string, password: string): Promise>, - postgres: { - server: { - list(): Promise>, - show(name: string): Promise> - } - }, - sql: { - mi: { - list(): Promise>, - show(name: string): Promise> - } - } -}