This commit is contained in:
nishthaAhujaa 2025-09-02 12:40:58 +05:30
parent 0817acf404
commit ac137c994b
5 changed files with 96 additions and 10 deletions

View File

@ -0,0 +1,13 @@
export const CLOUDSHELL_IP_RECOMMENDATIONS = {
centralindia: ["4.247.135.109", "74.225.207.63"],
southeastasia: ["4.194.56.6", "4.194.213.10", "4.194.144.127", "4.194.5.74"],
centraluseuap: ["52.158.186.182", "172.215.26.246", "134.138.154.177", "134.138.129.52", "172.215.31.177"],
eastus2euap: ["135.18.43.51", "20.252.175.33", "40.89.88.111", "135.18.17.187", "135.18.67.251"],
eastus: ["40.71.199.151", "20.42.18.188", "52.190.17.9", "20.120.96.152"],
northeurope: ["74.234.65.146", "52.169.70.113"],
southcentralus: ["4.151.247.81", "20.225.211.35", "4.151.48.133", "4.151.247.225"],
westeurope: ["52.166.126.216", "108.142.162.20", "52.178.13.125", "172.201.33.160"],
westus: ["20.245.161.131", "57.154.182.51", "40.118.133.244", "20.253.192.12", "20.43.245.209", "20.66.22.66"],
usgovarizona: ["62.10.232.179"],
usgovvirginia: ["62.10.26.85"],
};

View File

@ -10,6 +10,8 @@ const validCloudShellRegions = new Set([
"westcentralus", "westcentralus",
"usgovvirginia", "usgovvirginia",
"usgovarizona", "usgovarizona",
"centraluseuap",
"eastus2euap",
]); ]);
/** /**
@ -41,8 +43,8 @@ export const getNormalizedRegion = (region: string, defaultCloudshellRegion: str
} }
const regionMap: Record<string, string> = { const regionMap: Record<string, string> = {
centralus: "westcentralus", centralus: "centraluseuap",
eastus2: "eastus", eastus2: "eastus2euap",
}; };
const normalizedRegion = regionMap[region.toLowerCase()] || region; const normalizedRegion = regionMap[region.toLowerCase()] || region;

View File

@ -0,0 +1,40 @@
import { configContext } from "ConfigContext";
import * as DataModels from "Contracts/DataModels";
import { userContext } from "UserContext";
import { armRequest } from "Utils/arm/request";
import { CLOUDSHELL_IP_RECOMMENDATIONS } from "../CloudShellTab/Utils/CloudShellIPUtils";
import { getNormalizedRegion } from "../CloudShellTab/Utils/RegionUtils";
export async function checkCloudShellIPsConfigured() {
const databaseRegion = userContext.databaseAccount?.location;
console.log("db region", databaseRegion);
const normalizedRegion = getNormalizedRegion(databaseRegion, "westus");
const cloudShellIPs = getCloudShellIPsForRegion(normalizedRegion);
console.log("CloudShell IPs for region", normalizedRegion, cloudShellIPs);
if (!cloudShellIPs || cloudShellIPs.length === 0) {
return false;
}
const firewallRules = await getFirewallRules();
console.log("firewall rules", firewallRules);
return false;
}
function getCloudShellIPsForRegion(region: string): string[] {
const regionKey = region.toLowerCase();
const ips = CLOUDSHELL_IP_RECOMMENDATIONS[regionKey as keyof typeof CLOUDSHELL_IP_RECOMMENDATIONS];
return ips ? [...ips] : [];
}
async function getFirewallRules(): Promise<DataModels.FirewallRule[]> {
const firewallRulesUri = `${userContext.databaseAccount.id}/firewallRules`;
const response: any = await armRequest({
host: configContext.ARM_ENDPOINT,
path: firewallRulesUri,
method: "GET",
apiVersion: "2023-03-01-preview",
});
return response?.data?.value || response?.value || [];
}

View File

@ -22,9 +22,19 @@ export abstract class BaseTerminalComponentAdapter implements ReactAdapter {
protected getUsername: () => string, protected getUsername: () => string,
protected isAllPublicIPAddressesEnabled: ko.Observable<boolean>, protected isAllPublicIPAddressesEnabled: ko.Observable<boolean>,
protected kind: ViewModels.TerminalKind, protected kind: ViewModels.TerminalKind,
) {} protected isCloudShellIPsConfigured?: ko.Observable<boolean>,
) { }
public renderComponent(): JSX.Element { public renderComponent(): JSX.Element {
if (this.kind === ViewModels.TerminalKind.VCoreMongo && this.isCloudShellIPsConfigured && !this.isCloudShellIPsConfigured()) {
return (
<QuickstartFirewallNotification
messageType={this.getMessageType()}
screenshot={VcoreFirewallRuleScreenshot}
shellName={getShellNameForDisplay(this.kind)}
/>
);
}
if (!this.isAllPublicIPAddressesEnabled()) { if (!this.isAllPublicIPAddressesEnabled()) {
return ( return (
<QuickstartFirewallNotification <QuickstartFirewallNotification

View File

@ -8,6 +8,7 @@ import { userContext } from "../../UserContext";
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent"; import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
import Explorer from "../Explorer"; import Explorer from "../Explorer";
import { useNotebook } from "../Notebook/useNotebook"; import { useNotebook } from "../Notebook/useNotebook";
import { checkCloudShellIPsConfigured } from "./Shared/CloudShellIPChecker";
import { NotebookTerminalComponentAdapter } from "./ShellAdapters/NotebookTerminalComponentAdapter"; import { NotebookTerminalComponentAdapter } from "./ShellAdapters/NotebookTerminalComponentAdapter";
import TabsBase from "./TabsBase"; import TabsBase from "./TabsBase";
@ -23,11 +24,13 @@ export default class TerminalTab extends TabsBase {
private container: Explorer; private container: Explorer;
private notebookTerminalComponentAdapter: ReactAdapter; private notebookTerminalComponentAdapter: ReactAdapter;
private isAllPublicIPAddressesEnabled: ko.Observable<boolean>; private isAllPublicIPAddressesEnabled: ko.Observable<boolean>;
private isCloudShellIPsConfigured: ko.Observable<boolean>;
constructor(options: TerminalTabOptions) { constructor(options: TerminalTabOptions) {
super(options); super(options);
this.container = options.container; this.container = options.container;
this.isAllPublicIPAddressesEnabled = ko.observable(true); this.isAllPublicIPAddressesEnabled = ko.observable(true);
this.isCloudShellIPsConfigured = ko.observable(true);
const commonArgs: [ const commonArgs: [
() => DataModels.DatabaseAccount, () => DataModels.DatabaseAccount,
@ -36,19 +39,37 @@ export default class TerminalTab extends TabsBase {
ko.Observable<boolean>, ko.Observable<boolean>,
ViewModels.TerminalKind, ViewModels.TerminalKind,
] = [ ] = [
() => userContext?.databaseAccount, () => userContext?.databaseAccount,
() => this.tabId, () => this.tabId,
() => this.getUsername(), () => this.getUsername(),
this.isAllPublicIPAddressesEnabled, this.isAllPublicIPAddressesEnabled,
options.kind, options.kind,
]; ];
if (userContext.features.enableCloudShell) { if (userContext.features.enableCloudShell) {
this.notebookTerminalComponentAdapter = new CloudShellTerminalComponentAdapter(...commonArgs); this.notebookTerminalComponentAdapter = new CloudShellTerminalComponentAdapter(
() => userContext?.databaseAccount,
() => this.tabId,
() => this.getUsername(),
this.isAllPublicIPAddressesEnabled,
options.kind,
options.kind === ViewModels.TerminalKind.VCoreMongo ? this.isCloudShellIPsConfigured : undefined,
);
this.notebookTerminalComponentAdapter.parameters = ko.computed<boolean>(() => { this.notebookTerminalComponentAdapter.parameters = ko.computed<boolean>(() => {
if (options.kind === ViewModels.TerminalKind.VCoreMongo) {
const cloudShellConfigured = this.isCloudShellIPsConfigured();
return this.isTemplateReady() && cloudShellConfigured;
}
return this.isTemplateReady() && this.isAllPublicIPAddressesEnabled(); return this.isTemplateReady() && this.isAllPublicIPAddressesEnabled();
}); });
if (options.kind === ViewModels.TerminalKind.VCoreMongo) {
(async () => {
const result = await checkCloudShellIPsConfigured();
this.isCloudShellIPsConfigured(result);
})();
}
} else { } else {
this.notebookTerminalComponentAdapter = new NotebookTerminalComponentAdapter( this.notebookTerminalComponentAdapter = new NotebookTerminalComponentAdapter(
() => this.getNotebookServerInfo(options), () => this.getNotebookServerInfo(options),