mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Replacing all azdata with az (#16502)
* Changed azdata to az in azcli extension and resource-deployment, and some arc. Removed user, pass, url from controller connect blade. Commented out tests. Ported over work from old branch. * Changed unit tests, all unit tests passing. Changed parameters to new ones, fixed some Controller Connect issues. * Connect data controller and create dc working. * Changed az back to azdata in necessary places in resource-deployment. * Changed notebook values and added namespace to some params. * Added some changes from PR to this branch * Changed azdata.ts to az.ts and changed subscription parameter * Brought over changes from azcli PR into this branch. * added endpoint, username, password to getIsPassword * Changed notebooks to use proper az params, hard coded in some values to verify it is working, removed some variableNames from package.json. * Changed -sc to --storage-class in notebook * Added namespace to SQL deploy, deleted dc create in api * Deleted more dc create code and uncommented findAz() with unfinished work on Do Not Ask Again. * Removed (preview) from extensions/arc and extensions/azcli excluding preview:true in package.json * Commented out install/update prompts until DoNotAskAgain is implemented * Fixed bugs: JSON Output errors are now being caught, --infrastructure now has a required UI component with dropdown options, config page loads properly, SQL create flags use full names instead of shortnames. * Adds validation to pg extensions and bug fixes (#16486) * Extensions * Server parameters * Change locaiton of postgres extensions, pr fixes * Change location of list * List spacing * Commented out Don't Ask Again prompt implementation. * Uncommented header of a test file. * Added Azure CLI arcdata extension to Prerequisites * Reverted package.json and yarn.lock * Took away casting of stderr and stdout in executeCommand. * Deleted override function for initializeFields in connectControllerDialog.ts * Removed fakeAzApi for testing and added back in (Preview) * Removed en-us from python notebook links. * Deleted azdata tool from tool tests in resource-deployment * Deleted another instance of azdata in tool test * Add back in azdata tooltype * Remove en-us * Replaced AzdataTool in typings * Reverting adding azdata tool back in * Changed Azdata to AzdataToolOld * Added back azdata tool type * Added AzdataToolOld to tool types * fix test Co-authored-by: Candice Ye <canye@microsoft.com> Co-authored-by: nasc17 <nasc@microsoft.com> Co-authored-by: nasc17 <69922333+nasc17@users.noreply.github.com> Co-authored-by: chgagnon <chgagnon@microsoft.com>
This commit is contained in:
@@ -18,7 +18,7 @@ export class ControllerDashboard extends Dashboard {
|
||||
public override async showDashboard(): Promise<void> {
|
||||
await super.showDashboard();
|
||||
// Kick off the model refresh but don't wait on it since that's all handled with callbacks anyways
|
||||
this._controllerModel.refresh(false).catch(err => console.log(`Error refreshing Controller dashboard ${err}`));
|
||||
this._controllerModel.refresh(false, this._controllerModel.info.namespace).catch(err => console.log(`Error refreshing Controller dashboard ${err}`));
|
||||
}
|
||||
|
||||
protected async registerTabs(modelView: azdata.ModelView): Promise<(azdata.DashboardTab | azdata.DashboardTabGroup)[]> {
|
||||
|
||||
@@ -58,7 +58,7 @@ export class ControllerDashboardOverviewPage extends DashboardPage {
|
||||
}
|
||||
|
||||
protected async refresh(): Promise<void> {
|
||||
await this._controllerModel.refresh();
|
||||
await this._controllerModel.refresh(false, this._controllerModel.info.namespace);
|
||||
}
|
||||
|
||||
public get container(): azdata.Component {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as azdata from 'azdata';
|
||||
import * as azdataExt from 'azdata-ext';
|
||||
import * as azExt from 'az-ext';
|
||||
import * as loc from '../../../localizedConstants';
|
||||
import { IconPathHelper, cssStyles } from '../../../constants';
|
||||
import { DashboardPage } from '../../components/dashboardPage';
|
||||
@@ -30,11 +30,11 @@ export class MiaaComputeAndStoragePage extends DashboardPage {
|
||||
memoryRequest?: string
|
||||
} = {};
|
||||
|
||||
private readonly _azdataApi: azdataExt.IExtension;
|
||||
private readonly _azApi: azExt.IExtension;
|
||||
|
||||
constructor(modelView: azdata.ModelView, dashboard: azdata.window.ModelViewDashboard, private _miaaModel: MiaaModel) {
|
||||
super(modelView, dashboard);
|
||||
this._azdataApi = vscode.extensions.getExtension(azdataExt.extension.name)?.exports;
|
||||
this._azApi = vscode.extensions.getExtension(azExt.extension.name)?.exports;
|
||||
|
||||
this.initializeConfigurationBoxes();
|
||||
|
||||
@@ -130,8 +130,8 @@ export class MiaaComputeAndStoragePage extends DashboardPage {
|
||||
},
|
||||
async (_progress, _token): Promise<void> => {
|
||||
try {
|
||||
await this._azdataApi.azdata.arc.sql.mi.edit(
|
||||
this._miaaModel.info.name, this.saveArgs, this._miaaModel.controllerModel.azdataAdditionalEnvVars, this._miaaModel.controllerModel.controllerContext);
|
||||
await this._azApi.az.sql.miarc.edit(
|
||||
this._miaaModel.info.name, this.saveArgs, this._miaaModel.controllerModel.info.namespace, this._miaaModel.controllerModel.azAdditionalEnvVars);
|
||||
} catch (err) {
|
||||
this.saveButton!.enabled = true;
|
||||
throw err;
|
||||
|
||||
@@ -21,7 +21,7 @@ export class MiaaDashboard extends Dashboard {
|
||||
public override async showDashboard(): Promise<void> {
|
||||
await super.showDashboard();
|
||||
// Kick off the model refreshes but don't wait on it since that's all handled with callbacks anyways
|
||||
this._controllerModel.refresh().catch(err => console.log(`Error refreshing controller model for MIAA dashboard ${err}`));
|
||||
this._controllerModel.refresh(false, this._controllerModel.info.namespace).catch(err => console.log(`Error refreshing controller model for MIAA dashboard ${err}`));
|
||||
this._miaaModel.refresh().catch(err => console.log(`Error refreshing MIAA model for MIAA dashboard ${err}`));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as azdataExt from 'azdata-ext';
|
||||
import * as azExt from 'az-ext';
|
||||
import * as azurecore from 'azurecore';
|
||||
import * as vscode from 'vscode';
|
||||
import { getDatabaseStateDisplayText, promptForInstanceDeletion } from '../../../common/utils';
|
||||
@@ -34,7 +34,7 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
|
||||
private _connectToServerButton!: azdata.ButtonComponent;
|
||||
private _databasesTableLoading!: azdata.LoadingComponent;
|
||||
|
||||
private readonly _azdataApi: azdataExt.IExtension;
|
||||
private readonly _azApi: azExt.IExtension;
|
||||
private readonly _azurecoreApi: azurecore.IExtension;
|
||||
|
||||
private _instanceProperties = {
|
||||
@@ -50,7 +50,7 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
|
||||
|
||||
constructor(modelView: azdata.ModelView, dashboard: azdata.window.ModelViewDashboard, private _controllerModel: ControllerModel, private _miaaModel: MiaaModel) {
|
||||
super(modelView, dashboard);
|
||||
this._azdataApi = vscode.extensions.getExtension(azdataExt.extension.name)?.exports;
|
||||
this._azApi = vscode.extensions.getExtension(azExt.extension.name)?.exports;
|
||||
this._azurecoreApi = vscode.extensions.getExtension(azurecore.extension.name)?.exports;
|
||||
|
||||
this._instanceProperties.miaaAdmin = this._miaaModel.username || this._instanceProperties.miaaAdmin;
|
||||
@@ -75,7 +75,7 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
|
||||
}
|
||||
|
||||
protected async refresh(): Promise<void> {
|
||||
await Promise.all([this._controllerModel.refresh(), this._miaaModel.refresh()]);
|
||||
await Promise.all([this._controllerModel.refresh(false, this._controllerModel.info.namespace), this._miaaModel.refresh()]);
|
||||
}
|
||||
|
||||
public get container(): azdata.Component {
|
||||
@@ -244,7 +244,7 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
|
||||
cancellable: false
|
||||
},
|
||||
async (_progress, _token) => {
|
||||
return await this._azdataApi.azdata.arc.sql.mi.delete(this._miaaModel.info.name, this._controllerModel.azdataAdditionalEnvVars, this._controllerModel.controllerContext);
|
||||
return await this._azApi.az.sql.miarc.delete(this._miaaModel.info.name, this._controllerModel.info.namespace, this._controllerModel.azAdditionalEnvVars);
|
||||
}
|
||||
);
|
||||
await this._controllerModel.refreshTreeNode();
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as azdata from 'azdata';
|
||||
import * as azdataExt from 'azdata-ext';
|
||||
import * as azExt from 'az-ext';
|
||||
import * as loc from '../../../localizedConstants';
|
||||
import { IconPathHelper, cssStyles } from '../../../constants';
|
||||
import { DashboardPage } from '../../components/dashboardPage';
|
||||
@@ -45,11 +45,11 @@ export class PostgresComputeAndStoragePage extends DashboardPage {
|
||||
private discardButton!: azdata.ButtonComponent;
|
||||
private saveButton!: azdata.ButtonComponent;
|
||||
|
||||
private readonly _azdataApi: azdataExt.IExtension;
|
||||
private readonly _azApi: azExt.IExtension;
|
||||
|
||||
constructor(modelView: azdata.ModelView, dashboard: azdata.window.ModelViewDashboard, private _postgresModel: PostgresModel) {
|
||||
super(modelView, dashboard);
|
||||
this._azdataApi = vscode.extensions.getExtension(azdataExt.extension.name)?.exports;
|
||||
this._azApi = vscode.extensions.getExtension(azExt.extension.name)?.exports;
|
||||
|
||||
this.initializeConfigurationBoxes();
|
||||
|
||||
@@ -165,7 +165,7 @@ export class PostgresComputeAndStoragePage extends DashboardPage {
|
||||
},
|
||||
async (_progress, _token): Promise<void> => {
|
||||
try {
|
||||
await this._azdataApi.azdata.arc.postgres.server.edit(
|
||||
await this._azApi.az.postgres.arcserver.edit(
|
||||
this._postgresModel.info.name,
|
||||
{
|
||||
workers: this.saveArgs.workers,
|
||||
@@ -174,7 +174,8 @@ export class PostgresComputeAndStoragePage extends DashboardPage {
|
||||
memoryRequest: this.schedulingParamsToEdit(this.saveArgs.memoryRequest!),
|
||||
memoryLimit: this.schedulingParamsToEdit(this.saveArgs.memoryLimit!)
|
||||
},
|
||||
this._postgresModel.controllerModel.azdataAdditionalEnvVars);
|
||||
this._postgresModel.controllerModel.info.namespace,
|
||||
this._postgresModel.controllerModel.azAdditionalEnvVars);
|
||||
} catch (err) {
|
||||
// If an error occurs while editing the instance then re-enable the save button since
|
||||
// the edit wasn't successfully applied
|
||||
|
||||
@@ -36,27 +36,27 @@ export class PostgresCoordinatorNodeParametersPage extends PostgresParametersPag
|
||||
}
|
||||
|
||||
protected async saveParameterEdits(engineSettings: string): Promise<void> {
|
||||
await this._azdataApi.azdata.arc.postgres.server.edit(
|
||||
await this._azApi.az.postgres.arcserver.edit(
|
||||
this._postgresModel.info.name,
|
||||
{ coordinatorEngineSettings: engineSettings },
|
||||
this._postgresModel.controllerModel.azdataAdditionalEnvVars,
|
||||
this._postgresModel.controllerModel.controllerContext);
|
||||
this._postgresModel.controllerModel.info.namespace,
|
||||
this._postgresModel.controllerModel.azAdditionalEnvVars);
|
||||
|
||||
}
|
||||
|
||||
protected async resetAllParameters(): Promise<void> {
|
||||
await this._azdataApi.azdata.arc.postgres.server.edit(
|
||||
await this._azApi.az.postgres.arcserver.edit(
|
||||
this._postgresModel.info.name,
|
||||
{ coordinatorEngineSettings: `''`, replaceEngineSettings: true },
|
||||
this._postgresModel.controllerModel.azdataAdditionalEnvVars,
|
||||
this._postgresModel.controllerModel.controllerContext);
|
||||
this._postgresModel.controllerModel.info.namespace,
|
||||
this._postgresModel.controllerModel.azAdditionalEnvVars);
|
||||
}
|
||||
|
||||
protected async resetParameter(parameterName: string): Promise<void> {
|
||||
await this._azdataApi.azdata.arc.postgres.server.edit(
|
||||
await this._azApi.az.postgres.arcserver.edit(
|
||||
this._postgresModel.info.name,
|
||||
{ coordinatorEngineSettings: parameterName + '=' },
|
||||
this._postgresModel.controllerModel.azdataAdditionalEnvVars,
|
||||
this._postgresModel.controllerModel.controllerContext);
|
||||
this._postgresModel.controllerModel.info.namespace,
|
||||
this._postgresModel.controllerModel.azAdditionalEnvVars);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ export class PostgresDashboard extends Dashboard {
|
||||
await super.showDashboard();
|
||||
|
||||
// Kick off the model refresh but don't wait on it since that's all handled with callbacks anyways
|
||||
this._controllerModel.refresh().catch(err => console.log(`Error refreshing controller model for Postgres dashboard ${err}`));
|
||||
this._controllerModel.refresh(false, this._controllerModel.info.namespace).catch(err => console.log(`Error refreshing controller model for Postgres dashboard ${err}`));
|
||||
this._postgresModel.refresh().catch(err => console.log(`Error refreshing Postgres model for Postgres dashboard ${err}`));
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as azdata from 'azdata';
|
||||
import * as azdataExt from 'azdata-ext';
|
||||
import * as azExt from 'az-ext';
|
||||
import * as loc from '../../../localizedConstants';
|
||||
import { IconPathHelper, cssStyles } from '../../../constants';
|
||||
import { DashboardPage } from '../../components/dashboardPage';
|
||||
@@ -22,11 +22,11 @@ export class PostgresExtensionsPage extends DashboardPage {
|
||||
private dropExtensionsButton!: azdata.ButtonComponent;
|
||||
private extensionsLink!: azdata.HyperlinkComponent;
|
||||
|
||||
private readonly _azdataApi: azdataExt.IExtension;
|
||||
private readonly _azApi: azExt.IExtension;
|
||||
|
||||
constructor(modelView: azdata.ModelView, dashboard: azdata.window.ModelViewDashboard, private _postgresModel: PostgresModel) {
|
||||
super(modelView, dashboard);
|
||||
this._azdataApi = vscode.extensions.getExtension(azdataExt.extension.name)?.exports;
|
||||
this._azApi = vscode.extensions.getExtension(azExt.extension.name)?.exports;
|
||||
|
||||
this.disposables.push(
|
||||
this._postgresModel.onConfigUpdated(() => this.eventuallyRunOnInitialized(() => this.handleConfigUpdated())));
|
||||
@@ -138,12 +138,13 @@ export class PostgresExtensionsPage extends DashboardPage {
|
||||
},
|
||||
async (_progress, _token): Promise<void> => {
|
||||
|
||||
await this._azdataApi.azdata.arc.postgres.server.edit(
|
||||
await this._azApi.az.postgres.arcserver.edit(
|
||||
this._postgresModel.info.name,
|
||||
{
|
||||
extensions: extensionList
|
||||
},
|
||||
this._postgresModel.controllerModel.azdataAdditionalEnvVars);
|
||||
this._postgresModel.controllerModel.info.namespace,
|
||||
this._postgresModel.controllerModel.azAdditionalEnvVars);
|
||||
|
||||
try {
|
||||
await this._postgresModel.refresh();
|
||||
@@ -235,6 +236,10 @@ export class PostgresExtensionsPage extends DashboardPage {
|
||||
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px' }
|
||||
}).component();
|
||||
|
||||
if (name === 'citus') {
|
||||
checkBox.enabled = false;
|
||||
}
|
||||
|
||||
this.disposables.push(
|
||||
checkBox.onChanged(() => {
|
||||
if (checkBox.checked) {
|
||||
@@ -256,7 +261,7 @@ export class PostgresExtensionsPage extends DashboardPage {
|
||||
*/
|
||||
public async dropExtension(): Promise<void> {
|
||||
this.droppedExtensions.forEach(d => {
|
||||
let index = this.droppedExtensions.indexOf(d, 0);
|
||||
let index = this.extensionNames.indexOf(d, 0);
|
||||
this.extensionNames.splice(index, 1);
|
||||
});
|
||||
|
||||
@@ -267,12 +272,13 @@ export class PostgresExtensionsPage extends DashboardPage {
|
||||
cancellable: false
|
||||
},
|
||||
async (_progress, _token): Promise<void> => {
|
||||
await this._azdataApi.azdata.arc.postgres.server.edit(
|
||||
await this._azApi.az.postgres.arcserver.edit(
|
||||
this._postgresModel.info.name,
|
||||
{
|
||||
extensions: this.extensionNames.join()
|
||||
},
|
||||
this._postgresModel.controllerModel.azdataAdditionalEnvVars
|
||||
this._postgresModel.controllerModel.info.namespace,
|
||||
this._postgresModel.controllerModel.azAdditionalEnvVars
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as azdata from 'azdata';
|
||||
import * as azdataExt from 'azdata-ext';
|
||||
import * as azExt from 'az-ext';
|
||||
import * as loc from '../../../localizedConstants';
|
||||
import { IconPathHelper, cssStyles, iconSize } from '../../../constants';
|
||||
import { DashboardPage } from '../../components/dashboardPage';
|
||||
@@ -35,11 +35,11 @@ export class PostgresOverviewPage extends DashboardPage {
|
||||
private podStatusTable!: azdata.DeclarativeTableComponent;
|
||||
private podStatusData: PodStatusModel[] = [];
|
||||
|
||||
private readonly _azdataApi: azdataExt.IExtension;
|
||||
private readonly _azApi: azExt.IExtension;
|
||||
|
||||
constructor(modelView: azdata.ModelView, dashboard: azdata.window.ModelViewDashboard, private _controllerModel: ControllerModel, private _postgresModel: PostgresModel) {
|
||||
super(modelView, dashboard);
|
||||
this._azdataApi = vscode.extensions.getExtension(azdataExt.extension.name)?.exports;
|
||||
this._azApi = vscode.extensions.getExtension(azExt.extension.name)?.exports;
|
||||
|
||||
this.disposables.push(
|
||||
this._controllerModel.onRegistrationsUpdated(() => this.eventuallyRunOnInitialized(() => this.handleRegistrationsUpdated())),
|
||||
@@ -223,13 +223,14 @@ export class PostgresOverviewPage extends DashboardPage {
|
||||
try {
|
||||
const password = await promptAndConfirmPassword(input => !input ? loc.enterANonEmptyPassword : '');
|
||||
if (password) {
|
||||
await this._azdataApi.azdata.arc.postgres.server.edit(
|
||||
await this._azApi.az.postgres.arcserver.edit(
|
||||
this._postgresModel.info.name,
|
||||
{
|
||||
adminPassword: true,
|
||||
noWait: true
|
||||
},
|
||||
Object.assign({ 'AZDATA_PASSWORD': password }, this._controllerModel.azdataAdditionalEnvVars));
|
||||
this._postgresModel.controllerModel.info.namespace,
|
||||
Object.assign({ 'AZDATA_PASSWORD': password }, this._controllerModel.azAdditionalEnvVars));
|
||||
vscode.window.showInformationMessage(loc.passwordReset);
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -257,7 +258,7 @@ export class PostgresOverviewPage extends DashboardPage {
|
||||
cancellable: false
|
||||
},
|
||||
async (_progress, _token) => {
|
||||
return await this._azdataApi.azdata.arc.postgres.server.delete(this._postgresModel.info.name, this._controllerModel.azdataAdditionalEnvVars, this._controllerModel.controllerContext);
|
||||
return await this._azApi.az.postgres.arcserver.delete(this._postgresModel.info.name, this._postgresModel.controllerModel.info.namespace, this._controllerModel.azAdditionalEnvVars);
|
||||
}
|
||||
);
|
||||
await this._controllerModel.refreshTreeNode();
|
||||
@@ -294,7 +295,7 @@ export class PostgresOverviewPage extends DashboardPage {
|
||||
|
||||
await Promise.all([
|
||||
this._postgresModel.refresh(),
|
||||
this._controllerModel.refresh()
|
||||
this._controllerModel.refresh(false, this._controllerModel.info.namespace)
|
||||
]);
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(loc.refreshFailed(error));
|
||||
@@ -351,7 +352,7 @@ export class PostgresOverviewPage extends DashboardPage {
|
||||
let podModels: PodStatusModel[] = [];
|
||||
const podStatus = this._postgresModel.config?.status.podsStatus;
|
||||
|
||||
podStatus?.forEach(p => {
|
||||
podStatus?.forEach((p: { conditions: any[]; name: any; role: string; }) => {
|
||||
// If a condition of the pod has a status of False, pod is not Ready
|
||||
const status = p.conditions.find(c => c.status === 'False') ? loc.notReady : loc.ready;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as azdata from 'azdata';
|
||||
import * as azdataExt from 'azdata-ext';
|
||||
import * as azExt from 'az-ext';
|
||||
import * as loc from '../../../localizedConstants';
|
||||
import { UserCancelledError } from '../../../common/api';
|
||||
import { IconPathHelper, cssStyles } from '../../../constants';
|
||||
@@ -37,12 +37,12 @@ export abstract class PostgresParametersPage extends DashboardPage {
|
||||
private changedComponentValues: Set<string> = new Set();
|
||||
private parameterUpdates: Map<string, string> = new Map();
|
||||
|
||||
protected readonly _azdataApi: azdataExt.IExtension;
|
||||
protected readonly _azApi: azExt.IExtension;
|
||||
|
||||
constructor(modelView: azdata.ModelView, dashboard: azdata.window.ModelViewDashboard, protected _postgresModel: PostgresModel) {
|
||||
super(modelView, dashboard);
|
||||
|
||||
this._azdataApi = vscode.extensions.getExtension(azdataExt.extension.name)?.exports;
|
||||
this._azApi = vscode.extensions.getExtension(azExt.extension.name)?.exports;
|
||||
|
||||
this.initializeSearchBox();
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ export class PostgresPropertiesPage extends DashboardPage {
|
||||
this.loading!.loading = true;
|
||||
await Promise.all([
|
||||
this._postgresModel.refresh(),
|
||||
this._controllerModel.refresh()
|
||||
this._controllerModel.refresh(false, this._controllerModel.info.namespace)
|
||||
]);
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(loc.refreshFailed(error));
|
||||
|
||||
@@ -37,26 +37,26 @@ export class PostgresWorkerNodeParametersPage extends PostgresParametersPage {
|
||||
}
|
||||
|
||||
protected async saveParameterEdits(engineSettings: string): Promise<void> {
|
||||
await this._azdataApi.azdata.arc.postgres.server.edit(
|
||||
await this._azApi.az.postgres.arcserver.edit(
|
||||
this._postgresModel.info.name,
|
||||
{ workerEngineSettings: engineSettings },
|
||||
this._postgresModel.controllerModel.azdataAdditionalEnvVars,
|
||||
this._postgresModel.controllerModel.controllerContext);
|
||||
this._postgresModel.controllerModel.info.namespace,
|
||||
this._postgresModel.controllerModel.azAdditionalEnvVars);
|
||||
}
|
||||
|
||||
protected async resetAllParameters(): Promise<void> {
|
||||
await this._azdataApi.azdata.arc.postgres.server.edit(
|
||||
await this._azApi.az.postgres.arcserver.edit(
|
||||
this._postgresModel.info.name,
|
||||
{ workerEngineSettings: `''`, replaceEngineSettings: true },
|
||||
this._postgresModel.controllerModel.azdataAdditionalEnvVars,
|
||||
this._postgresModel.controllerModel.controllerContext);
|
||||
this._postgresModel.controllerModel.info.namespace,
|
||||
this._postgresModel.controllerModel.azAdditionalEnvVars);
|
||||
}
|
||||
|
||||
protected async resetParameter(parameterName: string): Promise<void> {
|
||||
await this._azdataApi.azdata.arc.postgres.server.edit(
|
||||
await this._azApi.az.postgres.arcserver.edit(
|
||||
this._postgresModel.info.name,
|
||||
{ workerEngineSettings: parameterName + '=' },
|
||||
this._postgresModel.controllerModel.azdataAdditionalEnvVars,
|
||||
this._postgresModel.controllerModel.controllerContext);
|
||||
this._postgresModel.controllerModel.info.namespace,
|
||||
this._postgresModel.controllerModel.azAdditionalEnvVars);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import { cssStyles } from '../../constants';
|
||||
import { InitializingComponent } from '../components/initializingComponent';
|
||||
import { PostgresModel } from '../../models/postgresModel';
|
||||
|
||||
export const validExtensions = ['citus', 'pgaudit', 'pgautofailover', 'pg_cron', 'pg_partman', 'plv8', 'postgis', 'postgis_raster', 'postgis_sfcgal', 'postgis_tiger_geocoder', 'tdigest'];
|
||||
|
||||
export class AddPGExtensionsDialog extends InitializingComponent {
|
||||
protected modelBuilder!: azdata.ModelBuilder;
|
||||
|
||||
@@ -28,7 +30,7 @@ export class AddPGExtensionsDialog extends InitializingComponent {
|
||||
this.modelBuilder = view.modelBuilder;
|
||||
|
||||
const info = this.modelBuilder.text().withProps({
|
||||
value: loc.extensionsFunction,
|
||||
value: loc.extensionsAddFunction(validExtensions.join(', ')),
|
||||
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px' }
|
||||
}).component();
|
||||
|
||||
@@ -45,7 +47,15 @@ export class AddPGExtensionsDialog extends InitializingComponent {
|
||||
.withProps({
|
||||
value: '',
|
||||
ariaLabel: loc.extensionsAddList,
|
||||
enabled: true
|
||||
enabled: true,
|
||||
validationErrorMessage: loc.extensionsAddErrorrMessage(validExtensions.join(','))
|
||||
}).withValidation((component) => {
|
||||
if (!component.value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let newExtensions = component.value.split(',');
|
||||
return newExtensions.every(e => validExtensions.includes(e));
|
||||
}).component();
|
||||
|
||||
let formModel = this.modelBuilder.formContainer()
|
||||
@@ -56,7 +66,8 @@ export class AddPGExtensionsDialog extends InitializingComponent {
|
||||
},
|
||||
{
|
||||
component: this.extensionsListInputBox,
|
||||
title: loc.extensionsAddList
|
||||
title: loc.extensionsAddList,
|
||||
required: true
|
||||
}
|
||||
],
|
||||
title: ''
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
import { ControllerInfo, ResourceInfo } from 'arc';
|
||||
import * as azdata from 'azdata';
|
||||
import * as azdataExt from 'azdata-ext';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import * as vscode from 'vscode';
|
||||
import { Deferred } from '../../common/promise';
|
||||
@@ -13,12 +12,11 @@ import * as loc from '../../localizedConstants';
|
||||
import { ControllerModel } from '../../models/controllerModel';
|
||||
import { InitializingComponent } from '../components/initializingComponent';
|
||||
import { AzureArcTreeDataProvider } from '../tree/azureArcTreeDataProvider';
|
||||
import { getErrorMessage } from '../../common/utils';
|
||||
import { RadioOptionsGroup } from '../components/radioOptionsGroup';
|
||||
import { getCurrentClusterContext, getDefaultKubeConfigPath, getKubeConfigClusterContexts, KubeClusterContext } from '../../common/kubeUtils';
|
||||
import { FilePicker } from '../components/filePicker';
|
||||
|
||||
export type ConnectToControllerDialogModel = { controllerModel: ControllerModel, password: string };
|
||||
export type ConnectToControllerDialogModel = { controllerModel: ControllerModel };
|
||||
|
||||
abstract class ControllerDialogBase extends InitializingComponent {
|
||||
protected _toDispose: vscode.Disposable[] = [];
|
||||
@@ -29,9 +27,6 @@ abstract class ControllerDialogBase extends InitializingComponent {
|
||||
protected kubeConfigInputBox!: FilePicker;
|
||||
protected clusterContextRadioGroup!: RadioOptionsGroup;
|
||||
protected nameInputBox!: azdata.InputBoxComponent;
|
||||
protected usernameInputBox!: azdata.InputBoxComponent;
|
||||
protected passwordInputBox!: azdata.InputBoxComponent;
|
||||
protected urlInputBox!: azdata.InputBoxComponent;
|
||||
|
||||
private _kubeClusters: KubeClusterContext[] = [];
|
||||
|
||||
@@ -46,13 +41,6 @@ abstract class ControllerDialogBase extends InitializingComponent {
|
||||
component: this.namespaceInputBox,
|
||||
title: loc.namespace,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
component: this.urlInputBox,
|
||||
title: loc.controllerUrl,
|
||||
layout: {
|
||||
info: loc.controllerUrlDescription
|
||||
}
|
||||
}, {
|
||||
component: this.kubeConfigInputBox.component(),
|
||||
title: loc.controllerKubeConfig,
|
||||
@@ -68,14 +56,6 @@ abstract class ControllerDialogBase extends InitializingComponent {
|
||||
layout: {
|
||||
info: loc.controllerNameDescription
|
||||
}
|
||||
}, {
|
||||
component: this.usernameInputBox,
|
||||
title: loc.controllerUsername,
|
||||
required: true
|
||||
}, {
|
||||
component: this.passwordInputBox,
|
||||
title: loc.controllerPassword,
|
||||
required: true
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -83,16 +63,11 @@ abstract class ControllerDialogBase extends InitializingComponent {
|
||||
protected abstract fieldToFocusOn(): azdata.Component;
|
||||
protected readonlyFields(): azdata.Component[] { return []; }
|
||||
|
||||
protected initializeFields(controllerInfo: ControllerInfo | undefined, password: string | undefined) {
|
||||
protected initializeFields(controllerInfo: ControllerInfo | undefined) {
|
||||
this.namespaceInputBox = this.modelBuilder.inputBox()
|
||||
.withProps({
|
||||
value: controllerInfo?.namespace,
|
||||
}).component();
|
||||
this.urlInputBox = this.modelBuilder.inputBox()
|
||||
.withProps({
|
||||
value: controllerInfo?.endpoint,
|
||||
placeHolder: loc.controllerUrlPlaceholder,
|
||||
}).component();
|
||||
this.kubeConfigInputBox = new FilePicker(
|
||||
this.modelBuilder,
|
||||
controllerInfo?.kubeConfigFilePath || getDefaultKubeConfigPath(),
|
||||
@@ -113,15 +88,6 @@ abstract class ControllerDialogBase extends InitializingComponent {
|
||||
.withProps({
|
||||
value: controllerInfo?.name
|
||||
}).component();
|
||||
this.usernameInputBox = this.modelBuilder.inputBox()
|
||||
.withProps({
|
||||
value: controllerInfo?.username
|
||||
}).component();
|
||||
this.passwordInputBox = this.modelBuilder.inputBox()
|
||||
.withProps({
|
||||
inputType: 'password',
|
||||
value: password
|
||||
}).component();
|
||||
}
|
||||
|
||||
protected completionPromise = new Deferred<ConnectToControllerDialogModel | undefined>();
|
||||
@@ -150,13 +116,13 @@ abstract class ControllerDialogBase extends InitializingComponent {
|
||||
this.namespaceInputBox.value = currentContext?.namespace;
|
||||
}
|
||||
|
||||
public showDialog(controllerInfo?: ControllerInfo, password: string | undefined = undefined): azdata.window.Dialog {
|
||||
public showDialog(controllerInfo?: ControllerInfo): azdata.window.Dialog {
|
||||
this.id = controllerInfo?.id ?? uuid();
|
||||
this.resources = controllerInfo?.resources ?? [];
|
||||
this._toDispose.push(this.dialog.cancelButton.onClick(() => this.handleCancel()));
|
||||
this.dialog.registerContent(async (view) => {
|
||||
this.modelBuilder = view.modelBuilder;
|
||||
this.initializeFields(controllerInfo, password);
|
||||
this.initializeFields(controllerInfo);
|
||||
|
||||
let formModel = this.modelBuilder.formContainer()
|
||||
.withFormItems([{
|
||||
@@ -192,75 +158,37 @@ abstract class ControllerDialogBase extends InitializingComponent {
|
||||
return this.completionPromise.promise;
|
||||
}
|
||||
|
||||
protected getControllerInfo(url: string, rememberPassword: boolean = false): ControllerInfo {
|
||||
protected getControllerInfo(): ControllerInfo {
|
||||
return {
|
||||
id: this.id,
|
||||
endpoint: url || undefined,
|
||||
namespace: this.namespaceInputBox.value!.trim(),
|
||||
kubeConfigFilePath: this.kubeConfigInputBox.value!,
|
||||
kubeClusterContext: this.clusterContextRadioGroup.value!,
|
||||
name: this.nameInputBox.value ?? '',
|
||||
username: this.usernameInputBox.value!,
|
||||
rememberPassword: rememberPassword,
|
||||
resources: this.resources
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class ConnectToControllerDialog extends ControllerDialogBase {
|
||||
protected rememberPwCheckBox!: azdata.CheckBoxComponent;
|
||||
|
||||
protected fieldToFocusOn() {
|
||||
return this.namespaceInputBox;
|
||||
}
|
||||
|
||||
protected override getComponents() {
|
||||
return [
|
||||
...super.getComponents(),
|
||||
{
|
||||
component: this.rememberPwCheckBox,
|
||||
title: ''
|
||||
}];
|
||||
}
|
||||
|
||||
protected override initializeFields(controllerInfo: ControllerInfo | undefined, password: string | undefined) {
|
||||
super.initializeFields(controllerInfo, password);
|
||||
this.rememberPwCheckBox = this.modelBuilder.checkBox()
|
||||
.withProps({
|
||||
label: loc.rememberPassword,
|
||||
checked: controllerInfo?.rememberPassword
|
||||
}).component();
|
||||
}
|
||||
|
||||
constructor(treeDataProvider: AzureArcTreeDataProvider) {
|
||||
super(treeDataProvider, loc.connectToController);
|
||||
}
|
||||
|
||||
public async validate(): Promise<boolean> {
|
||||
if (!this.namespaceInputBox.value || !this.usernameInputBox.value || !this.passwordInputBox.value) {
|
||||
if (!this.namespaceInputBox.value) {
|
||||
return false;
|
||||
}
|
||||
let url = this.urlInputBox.value?.trim() || '';
|
||||
if (url) {
|
||||
// Only support https connections
|
||||
if (url.toLowerCase().startsWith('http://')) {
|
||||
url = url.replace('http', 'https');
|
||||
}
|
||||
// Append https if they didn't type it in
|
||||
if (!url.toLowerCase().startsWith('https://')) {
|
||||
url = `https://${url}`;
|
||||
}
|
||||
// Append default port if one wasn't specified
|
||||
if (!/.*:\d*$/.test(url)) {
|
||||
url = `${url}:30080`;
|
||||
}
|
||||
}
|
||||
|
||||
const controllerInfo: ControllerInfo = this.getControllerInfo(url, !!this.rememberPwCheckBox.checked);
|
||||
const controllerModel = new ControllerModel(this.treeDataProvider, controllerInfo, this.passwordInputBox.value);
|
||||
const controllerInfo: ControllerInfo = this.getControllerInfo();
|
||||
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);
|
||||
await controllerModel.refresh(false, this.namespaceInputBox.value);
|
||||
// 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.controllerConfig?.metadata.name || loc.defaultControllerName;
|
||||
} catch (err) {
|
||||
@@ -270,74 +198,7 @@ export class ConnectToControllerDialog extends ControllerDialogBase {
|
||||
};
|
||||
return false;
|
||||
}
|
||||
this.completionPromise.resolve({ controllerModel: controllerModel, password: this.passwordInputBox.value });
|
||||
this.completionPromise.resolve({ controllerModel: controllerModel });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
export class PasswordToControllerDialog extends ControllerDialogBase {
|
||||
|
||||
constructor(treeDataProvider: AzureArcTreeDataProvider) {
|
||||
super(treeDataProvider, loc.passwordToController);
|
||||
}
|
||||
|
||||
protected fieldToFocusOn() {
|
||||
return this.passwordInputBox;
|
||||
}
|
||||
|
||||
protected override readonlyFields(): azdata.Component[] {
|
||||
return [
|
||||
this.urlInputBox,
|
||||
...this.kubeConfigInputBox.items,
|
||||
...this.clusterContextRadioGroup.items,
|
||||
this.nameInputBox,
|
||||
this.usernameInputBox
|
||||
];
|
||||
}
|
||||
|
||||
public async validate(): Promise<boolean> {
|
||||
if (!this.passwordInputBox.value) {
|
||||
return false;
|
||||
}
|
||||
const controllerInfo: ControllerInfo = this.getControllerInfo(this.urlInputBox.value!, false);
|
||||
const controllerModel = new ControllerModel(this.treeDataProvider, controllerInfo, this.passwordInputBox.value);
|
||||
const azdataApi = <azdataExt.IExtension>vscode.extensions.getExtension(azdataExt.extension.name)?.exports;
|
||||
try {
|
||||
await azdataApi.azdata.login(
|
||||
{
|
||||
endpoint: controllerInfo.endpoint,
|
||||
namespace: controllerInfo.namespace
|
||||
},
|
||||
controllerInfo.username,
|
||||
this.passwordInputBox.value,
|
||||
{
|
||||
'KUBECONFIG': this.kubeConfigInputBox.value!,
|
||||
'KUBECTL_CONTEXT': this.clusterContextRadioGroup.value!
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
if (getErrorMessage(e).match(/Wrong username or password/i)) {
|
||||
this.dialog.message = {
|
||||
text: loc.loginFailed,
|
||||
level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
return false;
|
||||
} else {
|
||||
this.dialog.message = {
|
||||
text: loc.errorVerifyingPassword(e),
|
||||
level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.completionPromise.resolve({ controllerModel: controllerModel, password: this.passwordInputBox.value });
|
||||
return true;
|
||||
}
|
||||
|
||||
public override showDialog(controllerInfo?: ControllerInfo): azdata.window.Dialog {
|
||||
const dialog = super.showDialog(controllerInfo);
|
||||
dialog.okButton.label = loc.ok;
|
||||
return dialog;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ControllerInfo } from 'arc';
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import { ControllerModel } from '../../models/controllerModel';
|
||||
import { ControllerTreeNode } from './controllerTreeNode';
|
||||
@@ -18,7 +17,6 @@ const mementoToken = 'arcDataControllers.v2';
|
||||
*/
|
||||
export class AzureArcTreeDataProvider implements vscode.TreeDataProvider<TreeNode> {
|
||||
|
||||
private _credentialsProvider = azdata.credentials.getProvider('arcControllerPasswords');
|
||||
private _onDidChangeTreeData: vscode.EventEmitter<TreeNode | undefined> = new vscode.EventEmitter<TreeNode | undefined>();
|
||||
readonly onDidChangeTreeData: vscode.Event<TreeNode | undefined> = this._onDidChangeTreeData.event;
|
||||
|
||||
@@ -51,14 +49,13 @@ export class AzureArcTreeDataProvider implements vscode.TreeDataProvider<TreeNod
|
||||
return element;
|
||||
}
|
||||
|
||||
public async addOrUpdateController(model: ControllerModel, password: string, refreshTree = true): Promise<void> {
|
||||
public async addOrUpdateController(model: ControllerModel, refreshTree = true): Promise<void> {
|
||||
const controllerNode = this.getControllerNode(model);
|
||||
if (controllerNode) {
|
||||
controllerNode.model.info = model.info;
|
||||
} else {
|
||||
this._controllerNodes.push(new ControllerTreeNode(model, this._context, this));
|
||||
}
|
||||
await this.updatePassword(model, password);
|
||||
if (refreshTree) {
|
||||
this._onDidChangeTreeData.fire(undefined);
|
||||
}
|
||||
@@ -71,22 +68,10 @@ export class AzureArcTreeDataProvider implements vscode.TreeDataProvider<TreeNod
|
||||
|
||||
public async removeController(controllerNode: ControllerTreeNode): Promise<void> {
|
||||
this._controllerNodes = this._controllerNodes.filter(node => node !== controllerNode);
|
||||
await this.deletePassword(controllerNode.model.info);
|
||||
this._onDidChangeTreeData.fire(undefined);
|
||||
await this.saveControllers();
|
||||
}
|
||||
|
||||
public async getPassword(info: ControllerInfo): Promise<string> {
|
||||
const provider = await this._credentialsProvider;
|
||||
const credential = await provider.readCredential(info.id);
|
||||
return credential.password;
|
||||
}
|
||||
|
||||
private async deletePassword(info: ControllerInfo): Promise<void> {
|
||||
const provider = await this._credentialsProvider;
|
||||
await provider.deleteCredential(info.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the specified node, or the entire tree if node is undefined
|
||||
* @param node The node to refresh, or undefined for the whole tree
|
||||
@@ -95,15 +80,6 @@ export class AzureArcTreeDataProvider implements vscode.TreeDataProvider<TreeNod
|
||||
this._onDidChangeTreeData.fire(node);
|
||||
}
|
||||
|
||||
private async updatePassword(model: ControllerModel, password: string): Promise<void> {
|
||||
const provider = await this._credentialsProvider;
|
||||
if (model.info.rememberPassword) {
|
||||
await provider.saveCredential(model.info.id, password);
|
||||
} else {
|
||||
await provider.deleteCredential(model.info.id);
|
||||
}
|
||||
}
|
||||
|
||||
private async loadSavedControllers(): Promise<void> {
|
||||
try {
|
||||
const controllerMementos: ControllerInfo[] = this._context.globalState.get(mementoToken) || [];
|
||||
|
||||
@@ -39,12 +39,12 @@ export class ControllerTreeNode extends TreeNode {
|
||||
|
||||
public override async getChildren(): Promise<TreeNode[]> {
|
||||
try {
|
||||
await this.model.refresh(false);
|
||||
await this.model.refresh(false, this.model.info.namespace);
|
||||
this.updateChildren(this.model.registrations);
|
||||
} catch (err) {
|
||||
vscode.window.showErrorMessage(loc.errorConnectingToController(err));
|
||||
try {
|
||||
await this.model.refresh(false);
|
||||
await this.model.refresh(false, this.model.info.namespace);
|
||||
this.updateChildren(this.model.registrations);
|
||||
} catch (err) {
|
||||
if (!(err instanceof UserCancelledError)) {
|
||||
|
||||
Reference in New Issue
Block a user