Azure Arc Postgres - Support + Troubleshooting (#10686)

This commit is contained in:
Brian Bergeron
2020-06-08 12:03:51 -07:00
committed by GitHub
parent 9ca17dbe7f
commit 5c6f334113
16 changed files with 850 additions and 37 deletions
+10
View File
@@ -28,6 +28,8 @@ export class IconPathHelper {
public static properties: IconPath;
public static networking: IconPath;
public static refresh: IconPath;
public static support: IconPath;
public static wrench: IconPath;
public static setExtensionContext(context: vscode.ExtensionContext) {
IconPathHelper.context = context;
@@ -91,6 +93,14 @@ export class IconPathHelper {
light: context.asAbsolutePath('images/refresh.svg'),
dark: context.asAbsolutePath('images/refresh.svg')
};
IconPathHelper.support = {
light: context.asAbsolutePath('images/support.svg'),
dark: context.asAbsolutePath('images/support.svg')
};
IconPathHelper.wrench = {
light: context.asAbsolutePath('images/wrench.svg'),
dark: context.asAbsolutePath('images/wrench.svg')
};
}
}
+1 -1
View File
@@ -26,7 +26,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
try {
const controllerModel = new ControllerModel(controllerUrl, auth);
const postgresModel = new PostgresModel(controllerUrl, auth, dbNamespace, dbName);
const postgresDashboard = new PostgresDashboard(loc.postgresDashboard, controllerModel, postgresModel);
const postgresDashboard = new PostgresDashboard(loc.postgresDashboard, context, controllerModel, postgresModel);
await Promise.all([
postgresDashboard.showDashboard(),
+40 -34
View File
@@ -15,8 +15,11 @@ export const networking = localize('arc.networking', "Networking");
export const properties = localize('arc.properties', "Properties");
export const settings = localize('arc.settings', "Settings");
export const security = localize('arc.security', "Security");
export const computeAndStorage = localize('arc.computeAndStorage', 'Compute + Storage');
export const computeAndStorage = localize('arc.computeAndStorage', "Compute + Storage");
export const backup = localize('arc.backup', "Backup");
export const newSupportRequest = localize('arc.newSupportRequest', "New support request");
export const diagnoseAndSolveProblems = localize('arc.diagnoseAndSolveProblems', "Diagnose and solve problems");
export const supportAndTroubleshooting = localize('arc.supportAndTroubleshooting', "Support + troubleshooting");
export const createNew = localize('arc.createNew', "Create New");
export const deleteText = localize('arc.delete', "Delete");
@@ -32,40 +35,42 @@ export const host = localize('arc.host', "Host");
export const name = localize('arc.name', "Name");
export const type = localize('arc.type', "Type");
export const status = localize('arc.status', "Status");
export const dataController = localize('arc.dataController', 'Data controller');
export const kibanaDashboard = localize('arc.kibanaDashboard', 'Kibana Dashboard');
export const grafanaDashboard = localize('arc.grafanaDashboard', 'Grafana Dashboard');
export const kibanaDashboardDescription = localize('arc.kibanaDashboardDescription', 'Dashboard for viewing logs');
export const grafanaDashboardDescription = localize('arc.grafanaDashboardDescription', 'Dashboard for viewing metrics');
export const serviceEndpoints = localize('arc.serviceEndpoints', 'Service endpoints');
export const endpoint = localize('arc.endpoint', 'Endpoint');
export const description = localize('arc.description', 'Description');
export const yes = localize('arc.yes', 'Yes');
export const no = localize('arc.no', 'No');
export const feedback = localize('arc.feedback', 'Feedback');
export const selectConnectionString = localize('arc.selectConnectionString', 'Select from available client connection strings below');
export const vCores = localize('arc.vCores', 'vCores');
export const ram = localize('arc.ram', 'RAM');
export const refresh = localize('arc.refresh', 'Refresh');
export const dataController = localize('arc.dataController', "Data controller");
export const kibanaDashboard = localize('arc.kibanaDashboard', "Kibana Dashboard");
export const grafanaDashboard = localize('arc.grafanaDashboard', "Grafana Dashboard");
export const kibanaDashboardDescription = localize('arc.kibanaDashboardDescription', "Dashboard for viewing logs");
export const grafanaDashboardDescription = localize('arc.grafanaDashboardDescription', "Dashboard for viewing metrics");
export const serviceEndpoints = localize('arc.serviceEndpoints', "Service endpoints");
export const endpoint = localize('arc.endpoint', "Endpoint");
export const description = localize('arc.description', "Description");
export const yes = localize('arc.yes', "Yes");
export const no = localize('arc.no', "No");
export const feedback = localize('arc.feedback', "Feedback");
export const selectConnectionString = localize('arc.selectConnectionString', "Select from available client connection strings below");
export const vCores = localize('arc.vCores', "vCores");
export const ram = localize('arc.ram', "RAM");
export const refresh = localize('arc.refresh', "Refresh");
export const troubleshoot = localize('arc.troubleshoot', "Troubleshoot");
export const clickTheNewSupportRequestButton = localize('arc.clickTheNewSupportRequestButton', "Click the new support request button to file a support request in the Azure Portal.");
// Postgres constants
export const coordinatorEndpoint = localize('arc.coordinatorEndpoint', 'Coordinator endpoint');
export const postgresAdminUsername = localize('arc.postgresAdminUsername', 'Admin username');
export const nodeConfiguration = localize('arc.nodeConfiguration', 'Node configuration');
export const postgresVersion = localize('arc.postgresVersion', 'PostgreSQL version');
export const serverGroupType = localize('arc.serverGroupType', 'Server group type');
export const serverGroupNodes = localize('arc.serverGroupNodes', 'Server group nodes');
export const fullyQualifiedDomain = localize('arc.fullyQualifiedDomain', 'Fully qualified domain');
export const postgresArcProductName = localize('arc.postgresArcProductName', 'Azure Database for PostgreSQL - Azure Arc');
export const coordinator = localize('arc.coordinator', 'Coordinator');
export const worker = localize('arc.worker', 'Worker');
export const newDatabase = localize('arc.newDatabase', 'New Database');
export const databaseName = localize('arc.databaseName', 'Database name');
export const newPassword = localize('arc.newPassword', 'New password');
export const learnAboutPostgresClients = localize('arc.learnAboutPostgresClients', 'Learn more about Azure PostgreSQL Hyperscale client interfaces');
export const node = localize('arc.node', 'node');
export const nodes = localize('arc.nodes', 'nodes');
export const storagePerNode = localize('arc.storagePerNode', 'storage per node');
export const coordinatorEndpoint = localize('arc.coordinatorEndpoint', "Coordinator endpoint");
export const postgresAdminUsername = localize('arc.postgresAdminUsername', "Admin username");
export const nodeConfiguration = localize('arc.nodeConfiguration', "Node configuration");
export const postgresVersion = localize('arc.postgresVersion', "PostgreSQL version");
export const serverGroupType = localize('arc.serverGroupType', "Server group type");
export const serverGroupNodes = localize('arc.serverGroupNodes', "Server group nodes");
export const fullyQualifiedDomain = localize('arc.fullyQualifiedDomain', "Fully qualified domain");
export const postgresArcProductName = localize('arc.postgresArcProductName', "Azure Database for PostgreSQL - Azure Arc");
export const coordinator = localize('arc.coordinator', "Coordinator");
export const worker = localize('arc.worker', "Worker");
export const newDatabase = localize('arc.newDatabase', "New Database");
export const databaseName = localize('arc.databaseName', "Database name");
export const newPassword = localize('arc.newPassword', "New password");
export const learnAboutPostgresClients = localize('arc.learnAboutPostgresClients', "Learn more about Azure PostgreSQL Hyperscale client interfaces");
export const node = localize('arc.node', "node");
export const nodes = localize('arc.nodes', "nodes");
export const storagePerNode = localize('arc.storagePerNode', "storage per node");
export function databaseCreated(name: string): string { return localize('arc.databaseCreated', "Database {0} created", name); }
export function databaseCreationFailed(name: string, error: any): string { return localize('arc.databaseCreationFailed', "Failed to create database {0}. {1}", name, (error instanceof Error ? error.message : error)); }
@@ -75,8 +80,9 @@ export function deleteServicePrompt(name: string): string { return localize('arc
export function serviceDeleted(name: string): string { return localize('arc.serviceDeleted', "Service {0} deleted", name); }
export function serviceDeletionFailed(name: string, error: any): string { return localize('arc.serviceDeletionFailed', "Failed to delete service {0}. {1}", name, (error instanceof Error ? error.message : error)); }
export function couldNotFindAzureResource(name: string): string { return localize('arc.couldNotFindAzureResource', "Could not find Azure resource for {0}", name); }
export function copiedToClipboard(name: string): string { return localize('arc.copiedToClipboard', '{0} copied to clipboard', name); }
export function copiedToClipboard(name: string): string { return localize('arc.copiedToClipboard', "{0} copied to clipboard", name); }
export function refreshFailed(error: any): string { return localize('arc.refreshFailed', "Refresh failed. {0}", (error instanceof Error ? error.message : error)); }
export function failedToManagePostgres(name: string, error: any): string { return localize('arc.failedToManagePostgres', "Failed to manage Postgres {0}. {1}", name, (error instanceof Error ? error.message : error)); }
export function clickTheTroubleshootButton(resourceType: string): string { return localize('arc.clickTheTroubleshootButton', "Click the troubleshoot button to open the Azure Arc {0} troubleshooting notebook.", resourceType); }
export const arcResources = localize('arc.arcResources', "Azure Arc Resources");
@@ -3,6 +3,7 @@
* 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 { ControllerModel } from '../../../models/controllerModel';
@@ -14,9 +15,11 @@ import { PostgresBackupPage } from './postgresBackupPage';
import { PostgresPropertiesPage } from './postgresPropertiesPage';
import { PostgresNetworkingPage } from './postgresNetworkingPage';
import { Dashboard } from '../../components/dashboard';
import { PostgresDiagnoseAndSolveProblemsPage } from './postgresDiagnoseAndSolveProblemsPage';
import { PostgresSupportRequestPage } from './postgresSupportRequestPage';
export class PostgresDashboard extends Dashboard {
constructor(title: string, private _controllerModel: ControllerModel, private _postgresModel: PostgresModel) {
constructor(title: string, private _context: vscode.ExtensionContext, private _controllerModel: ControllerModel, private _postgresModel: PostgresModel) {
super(title);
}
@@ -27,6 +30,8 @@ export class PostgresDashboard extends Dashboard {
const backupPage = new PostgresBackupPage(modelView);
const propertiesPage = new PostgresPropertiesPage(modelView, this._controllerModel, this._postgresModel);
const networkingPage = new PostgresNetworkingPage(modelView);
const diagnoseAndSolveProblemsPage = new PostgresDiagnoseAndSolveProblemsPage(modelView, this._context, this._postgresModel);
const supportRequestPage = new PostgresSupportRequestPage(modelView, this._controllerModel, this._postgresModel);
return [
overviewPage.tab,
@@ -43,6 +48,13 @@ export class PostgresDashboard extends Dashboard {
tabs: [
networkingPage.tab
]
},
{
title: loc.supportAndTroubleshooting,
tabs: [
diagnoseAndSolveProblemsPage.tab,
supportRequestPage.tab
]
}
];
}
@@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as azdata from 'azdata';
import * as loc from '../../../localizedConstants';
import { IconPathHelper, cssStyles } from '../../../constants';
import { DashboardPage } from '../../components/dashboardPage';
import { PostgresModel } from '../../../models/postgresModel';
export class PostgresDiagnoseAndSolveProblemsPage extends DashboardPage {
constructor(protected modelView: azdata.ModelView, private _context: vscode.ExtensionContext, private _postgresModel: PostgresModel) {
super(modelView);
}
protected get title(): string {
return loc.diagnoseAndSolveProblems;
}
protected get id(): string {
return 'postgres-diagnose-and-solve-problems';
}
protected get icon(): { dark: string; light: string; } {
return IconPathHelper.wrench;
}
protected get container(): azdata.Component {
const root = this.modelView.modelBuilder.divContainer().component();
const content = this.modelView.modelBuilder.divContainer().component();
root.addItem(content, { CSSStyles: { 'margin': '20px' } });
content.addItem(this.modelView.modelBuilder.text().withProperties<azdata.TextComponentProperties>({
value: loc.diagnoseAndSolveProblems,
CSSStyles: { ...cssStyles.title, 'margin-bottom': '20px' }
}).component());
content.addItem(this.modelView.modelBuilder.text().withProperties<azdata.TextComponentProperties>({
value: loc.clickTheTroubleshootButton('Postgres'),
CSSStyles: { ...cssStyles.text, 'margin-bottom': '20px' }
}).component());
const troubleshootButton = this.modelView.modelBuilder.button().withProperties<azdata.ButtonProperties>({
iconPath: IconPathHelper.wrench,
label: loc.troubleshoot,
width: '160px'
}).component();
troubleshootButton.onDidClick(() => {
process.env['POSTGRES_SERVER_NAMESPACE'] = this._postgresModel.namespace();
process.env['POSTGRES_SERVER_NAME'] = this._postgresModel.name();
vscode.commands.executeCommand('bookTreeView.openBook', this._context.asAbsolutePath('notebooks/arc'), true, 'postgres/tsg100-troubleshoot-postgres');
});
content.addItem(troubleshootButton);
return root;
}
protected get toolbarContainer(): azdata.ToolbarContainer {
return this.modelView.modelBuilder.toolbarContainer().component();
}
}
@@ -245,7 +245,7 @@ export class PostgresOverviewPage extends DashboardPage {
openInAzurePortalButton.onDidClick(async () => {
const r = this._controllerModel.registration('postgresInstances', this._postgresModel.namespace(), this._postgresModel.name());
if (r === undefined) {
if (!r) {
vscode.window.showErrorMessage(loc.couldNotFindAzureResource(this._postgresModel.fullName()));
} else {
vscode.env.openExternal(vscode.Uri.parse(
@@ -0,0 +1,69 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as azdata from 'azdata';
import * as loc from '../../../localizedConstants';
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) {
super(modelView);
}
protected get title(): string {
return loc.newSupportRequest;
}
protected get id(): string {
return 'postgres-support-request';
}
protected get icon(): { dark: string; light: string; } {
return IconPathHelper.support;
}
protected get container(): azdata.Component {
const root = this.modelView.modelBuilder.divContainer().component();
const content = this.modelView.modelBuilder.divContainer().component();
root.addItem(content, { CSSStyles: { 'margin': '20px' } });
content.addItem(this.modelView.modelBuilder.text().withProperties<azdata.TextComponentProperties>({
value: loc.newSupportRequest,
CSSStyles: { ...cssStyles.title, 'margin-bottom': '20px' }
}).component());
content.addItem(this.modelView.modelBuilder.text().withProperties<azdata.TextComponentProperties>({
value: loc.clickTheNewSupportRequestButton,
CSSStyles: { ...cssStyles.text, 'margin-bottom': '20px' }
}).component());
const supportRequestButton = this.modelView.modelBuilder.button().withProperties<azdata.ButtonProperties>({
iconPath: IconPathHelper.support,
label: loc.newSupportRequest,
width: '205px'
}).component();
supportRequestButton.onDidClick(() => {
const r = this._controllerModel.registration('postgresInstances', this._postgresModel.namespace(), this._postgresModel.name());
if (!r) {
vscode.window.showErrorMessage(loc.couldNotFindAzureResource(this._postgresModel.fullName()));
} else {
vscode.env.openExternal(vscode.Uri.parse(
`https://portal.azure.com/#resource/subscriptions/${r.subscriptionId}/resourceGroups/${r.resourceGroupName}/providers/Microsoft.AzureData/postgresInstances/${r.instanceName}/supportrequest`));
}
});
content.addItem(supportRequestButton);
return root;
}
protected get toolbarContainer(): azdata.ToolbarContainer {
return this.modelView.modelBuilder.toolbarContainer().component();
}
}