mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-12 19:18:32 -05:00
Arc updates for March release (#14970)
* Updated Postgres Spec for where to find engine version, removed calling calling -ev in edit commands (#14735) * Added spec.engine.version, took out calling engine version with edit calls * Added text wrong place * missed updates * PR fix * Update Arc Postgres troubleshooting notebook Co-authored-by: Brian Bergeron <brberger@microsoft.com> * Remove AzdataSession from azdata commands (#14856) * remove session * Add in controller-context support * Revert "Add in controller-context support" This reverts commit 3b39b968efbf6054041cb01cb2d8443532643a82. * Add azdataContext to login * Undo book change * Undo change correctly * Add controller context support (#14862) * remove session * Add in controller-context support * Add params to fake * Fix tests * Add info and placeholder for controller URL/name (#14887) * Add info and placeholder for controller URL * add period + update name * update memento and allow editing of namespace/URL * vBump * vBump * Fix tests Co-authored-by: nasc17 <69922333+nasc17@users.noreply.github.com> Co-authored-by: Brian Bergeron <brian.e.bergeron@gmail.com> Co-authored-by: Brian Bergeron <brberger@microsoft.com>
This commit is contained in:
@@ -15,7 +15,7 @@ import { InitializingComponent } from '../components/initializingComponent';
|
||||
import { AzureArcTreeDataProvider } from '../tree/azureArcTreeDataProvider';
|
||||
import { getErrorMessage } from '../../common/utils';
|
||||
import { RadioOptionsGroup } from '../components/radioOptionsGroup';
|
||||
import { getCurrentClusterContext, getDefaultKubeConfigPath, getKubeConfigClusterContexts } from '../../common/kubeUtils';
|
||||
import { getCurrentClusterContext, getDefaultKubeConfigPath, getKubeConfigClusterContexts, KubeClusterContext } from '../../common/kubeUtils';
|
||||
import { FilePicker } from '../components/filePicker';
|
||||
|
||||
export type ConnectToControllerDialogModel = { controllerModel: ControllerModel, password: string };
|
||||
@@ -25,24 +25,34 @@ abstract class ControllerDialogBase extends InitializingComponent {
|
||||
protected modelBuilder!: azdata.ModelBuilder;
|
||||
protected dialog: azdata.window.Dialog;
|
||||
|
||||
protected urlInputBox!: azdata.InputBoxComponent;
|
||||
protected namespaceInputBox!: azdata.InputBoxComponent;
|
||||
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[] = [];
|
||||
|
||||
protected dispose(): void {
|
||||
this._toDispose.forEach(disposable => disposable.dispose());
|
||||
this._toDispose.length = 0; // clear the _toDispose array
|
||||
this._toDispose.length = 0;
|
||||
}
|
||||
|
||||
protected getComponents(): (azdata.FormComponent<azdata.Component> & { layout?: azdata.FormItemLayout | undefined; })[] {
|
||||
return [
|
||||
{
|
||||
component: this.namespaceInputBox,
|
||||
title: loc.namespace,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
component: this.urlInputBox,
|
||||
title: loc.controllerUrl,
|
||||
required: true
|
||||
layout: {
|
||||
info: loc.controllerUrlDescription
|
||||
}
|
||||
}, {
|
||||
component: this.kubeConfigInputBox.component(),
|
||||
title: loc.controllerKubeConfig,
|
||||
@@ -54,14 +64,17 @@ abstract class ControllerDialogBase extends InitializingComponent {
|
||||
}, {
|
||||
component: this.nameInputBox,
|
||||
title: loc.controllerName,
|
||||
required: false
|
||||
required: false,
|
||||
layout: {
|
||||
info: loc.controllerNameDescription
|
||||
}
|
||||
}, {
|
||||
component: this.usernameInputBox,
|
||||
title: loc.username,
|
||||
title: loc.controllerUsername,
|
||||
required: true
|
||||
}, {
|
||||
component: this.passwordInputBox,
|
||||
title: loc.password,
|
||||
title: loc.controllerPassword,
|
||||
required: true
|
||||
}
|
||||
];
|
||||
@@ -71,11 +84,14 @@ abstract class ControllerDialogBase extends InitializingComponent {
|
||||
protected readonlyFields(): azdata.Component[] { return []; }
|
||||
|
||||
protected initializeFields(controllerInfo: ControllerInfo | undefined, password: string | undefined) {
|
||||
this.namespaceInputBox = this.modelBuilder.inputBox()
|
||||
.withProps({
|
||||
value: controllerInfo?.namespace,
|
||||
}).component();
|
||||
this.urlInputBox = this.modelBuilder.inputBox()
|
||||
.withProperties<azdata.InputBoxProperties>({
|
||||
value: controllerInfo?.url,
|
||||
// If we have a model then we're editing an existing connection so don't let them modify the URL
|
||||
readOnly: !!controllerInfo
|
||||
.withProps({
|
||||
value: controllerInfo?.endpoint,
|
||||
placeHolder: loc.controllerUrlPlaceholder,
|
||||
}).component();
|
||||
this.kubeConfigInputBox = new FilePicker(
|
||||
this.modelBuilder,
|
||||
@@ -83,22 +99,23 @@ abstract class ControllerDialogBase extends InitializingComponent {
|
||||
(disposable) => this._toDispose.push(disposable)
|
||||
);
|
||||
this.modelBuilder.inputBox()
|
||||
.withProperties<azdata.InputBoxProperties>({
|
||||
.withProps({
|
||||
value: controllerInfo?.kubeConfigFilePath || getDefaultKubeConfigPath()
|
||||
}).component();
|
||||
this.clusterContextRadioGroup = new RadioOptionsGroup(this.modelBuilder, (disposable) => this._toDispose.push(disposable));
|
||||
this.loadRadioGroup(controllerInfo?.kubeClusterContext);
|
||||
this._toDispose.push(this.clusterContextRadioGroup.onRadioOptionChanged(newContext => this.updateNamespace(newContext)));
|
||||
this._toDispose.push(this.kubeConfigInputBox.onTextChanged(() => this.loadRadioGroup(controllerInfo?.kubeClusterContext)));
|
||||
this.nameInputBox = this.modelBuilder.inputBox()
|
||||
.withProperties<azdata.InputBoxProperties>({
|
||||
.withProps({
|
||||
value: controllerInfo?.name
|
||||
}).component();
|
||||
this.usernameInputBox = this.modelBuilder.inputBox()
|
||||
.withProperties<azdata.InputBoxProperties>({
|
||||
.withProps({
|
||||
value: controllerInfo?.username
|
||||
}).component();
|
||||
this.passwordInputBox = this.modelBuilder.inputBox()
|
||||
.withProperties<azdata.InputBoxProperties>({
|
||||
.withProps({
|
||||
inputType: 'password',
|
||||
value: password
|
||||
}).component();
|
||||
@@ -114,15 +131,22 @@ abstract class ControllerDialogBase extends InitializingComponent {
|
||||
}
|
||||
|
||||
private loadRadioGroup(previousClusterContext?: string): void {
|
||||
this.clusterContextRadioGroup.load(async () => {
|
||||
const clusters = await getKubeConfigClusterContexts(this.kubeConfigInputBox.value!);
|
||||
this.clusterContextRadioGroup.load(() => {
|
||||
this._kubeClusters = getKubeConfigClusterContexts(this.kubeConfigInputBox.value!);
|
||||
const currentClusterContext = getCurrentClusterContext(this._kubeClusters, previousClusterContext, false);
|
||||
this.namespaceInputBox.value = currentClusterContext.namespace || this.namespaceInputBox.value;
|
||||
return {
|
||||
values: clusters.map(c => c.name),
|
||||
defaultValue: getCurrentClusterContext(clusters, previousClusterContext, false),
|
||||
values: this._kubeClusters.map(c => c.name),
|
||||
defaultValue: currentClusterContext.name
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private updateNamespace(currentContextName: string | undefined): void {
|
||||
const currentContext = this._kubeClusters.find(cluster => cluster.name === currentContextName);
|
||||
this.namespaceInputBox.value = currentContext?.namespace;
|
||||
}
|
||||
|
||||
public showDialog(controllerInfo?: ControllerInfo, password: string | undefined = undefined): azdata.window.Dialog {
|
||||
this.id = controllerInfo?.id ?? uuid();
|
||||
this.resources = controllerInfo?.resources ?? [];
|
||||
@@ -168,7 +192,8 @@ abstract class ControllerDialogBase extends InitializingComponent {
|
||||
protected getControllerInfo(url: string, rememberPassword: boolean = false): ControllerInfo {
|
||||
return {
|
||||
id: this.id,
|
||||
url: url,
|
||||
endpoint: url || undefined,
|
||||
namespace: this.namespaceInputBox.value!,
|
||||
kubeConfigFilePath: this.kubeConfigInputBox.value!,
|
||||
kubeClusterContext: this.clusterContextRadioGroup.value!,
|
||||
name: this.nameInputBox.value ?? '',
|
||||
@@ -183,7 +208,7 @@ export class ConnectToControllerDialog extends ControllerDialogBase {
|
||||
protected rememberPwCheckBox!: azdata.CheckBoxComponent;
|
||||
|
||||
protected fieldToFocusOn() {
|
||||
return this.urlInputBox;
|
||||
return this.namespaceInputBox;
|
||||
}
|
||||
|
||||
protected getComponents() {
|
||||
@@ -209,22 +234,25 @@ export class ConnectToControllerDialog extends ControllerDialogBase {
|
||||
}
|
||||
|
||||
public async validate(): Promise<boolean> {
|
||||
if (!this.urlInputBox.value || !this.usernameInputBox.value || !this.passwordInputBox.value) {
|
||||
if (!this.namespaceInputBox.value || !this.usernameInputBox.value || !this.passwordInputBox.value) {
|
||||
return false;
|
||||
}
|
||||
let url = this.urlInputBox.value;
|
||||
// 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`;
|
||||
let url = this.urlInputBox.value || '';
|
||||
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);
|
||||
try {
|
||||
@@ -234,7 +262,7 @@ export class ConnectToControllerDialog extends ControllerDialogBase {
|
||||
controllerModel.info.name = controllerModel.info.name || controllerModel.controllerConfig?.metadata.name || loc.defaultControllerName;
|
||||
} catch (err) {
|
||||
this.dialog.message = {
|
||||
text: loc.connectToControllerFailed(this.urlInputBox.value, err),
|
||||
text: loc.connectToControllerFailed(this.namespaceInputBox.value, err),
|
||||
level: azdata.window.MessageLevel.Error
|
||||
};
|
||||
return false;
|
||||
@@ -267,11 +295,16 @@ export class PasswordToControllerDialog extends ControllerDialogBase {
|
||||
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(
|
||||
this.urlInputBox.value!,
|
||||
this.usernameInputBox.value!,
|
||||
{
|
||||
endpoint: controllerInfo.endpoint,
|
||||
namespace: controllerInfo.namespace
|
||||
},
|
||||
controllerInfo.username,
|
||||
this.passwordInputBox.value,
|
||||
{
|
||||
'KUBECONFIG': this.kubeConfigInputBox.value!,
|
||||
@@ -293,8 +326,6 @@ export class PasswordToControllerDialog extends ControllerDialogBase {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const controllerInfo: ControllerInfo = this.getControllerInfo(this.urlInputBox.value!, false);
|
||||
const controllerModel = new ControllerModel(this.treeDataProvider, controllerInfo, this.passwordInputBox.value);
|
||||
this.completionPromise.resolve({ controllerModel: controllerModel, password: this.passwordInputBox.value });
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user