From d07d2c7c0d4e7fdecdd8fc368c41290fa246b563 Mon Sep 17 00:00:00 2001 From: sindhuba <122321535+sindhuba@users.noreply.github.com> Date: Fri, 19 Jul 2024 08:02:44 -0700 Subject: [PATCH 1/3] Add readOnlyKeys call to support accounts with Reader role (#1916) * Fix API endpoint for CassandraProxy query API * activate Mongo Proxy and Cassandra Proxy in Prod * Add CP Prod endpoint * Run npm format and tests * Revert code * fix bug that blocked local mongo proxy and cassandra proxy development * Add prod endpoint * fix pr check tests * Remove prod * Remove prod endpoint * Remove dev endpoint * Support data plane RBAC * Support data plane RBAC * Add additional changes for Portal RBAC functionality * Remove unnecessary code * Remove unnecessary code * Add code to fix VCoreMongo/PG bug * Address feedback * Add more logs for RBAC feature * Add more logs for RBAC features * Add readOnlyKeys call for accounts with Reader role * Resolve conflicts --------- Co-authored-by: Asier Isayas --- .../Panes/SettingsPane/SettingsPane.tsx | 28 +++++++++------ src/hooks/useKnockoutExplorer.ts | 36 +++++++++++-------- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/Explorer/Panes/SettingsPane/SettingsPane.tsx b/src/Explorer/Panes/SettingsPane/SettingsPane.tsx index ef277b53f..216deda25 100644 --- a/src/Explorer/Panes/SettingsPane/SettingsPane.tsx +++ b/src/Explorer/Panes/SettingsPane/SettingsPane.tsx @@ -36,8 +36,7 @@ import Explorer from "../../Explorer"; import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm"; import { AuthType } from "AuthType"; import create, { UseStore } from "zustand"; -import { DatabaseAccountListKeysResult } from "@azure/arm-cosmosdb/esm/models"; -import { listKeys } from "Utils/arm/generatedClients/cosmos/databaseAccounts"; +import { getReadOnlyKeys, listKeys } from "Utils/arm/generatedClients/cosmos/databaseAccounts"; export interface DataPlaneRbacState { dataPlaneRbacEnabled: boolean; @@ -172,18 +171,25 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({ }); const { databaseAccount: account, subscriptionId, resourceGroup } = userContext; if (!userContext.features.enableAadDataPlane && !userContext.masterKey) { + let keys; try { - const keys: DatabaseAccountListKeysResult = await listKeys(subscriptionId, resourceGroup, account.name); - - if (keys.primaryMasterKey) { - updateUserContext({ masterKey: keys.primaryMasterKey }); - - useDataPlaneRbac.setState({ dataPlaneRbacEnabled: false }); - } + keys = await listKeys(subscriptionId, resourceGroup, account.name); + updateUserContext({ + masterKey: keys.primaryMasterKey, + }); } catch (error) { - logConsoleError(`Error occurred fetching keys for the account." ${error.message}`); - throw error; + // if listKeys fail because of permissions issue, then make call to get ReadOnlyKeys + if (error.code === "AuthorizationFailed") { + keys = await getReadOnlyKeys(subscriptionId, resourceGroup, account.name); + updateUserContext({ + masterKey: keys.primaryReadonlyMasterKey, + }); + } else { + logConsoleError(`Error occurred fetching keys for the account." ${error.message}`); + throw error; + } } + useDataPlaneRbac.setState({ dataPlaneRbacEnabled: false }); } } diff --git a/src/hooks/useKnockoutExplorer.ts b/src/hooks/useKnockoutExplorer.ts index 8a0bfa149..fcf1d314e 100644 --- a/src/hooks/useKnockoutExplorer.ts +++ b/src/hooks/useKnockoutExplorer.ts @@ -40,7 +40,7 @@ import { DefaultExperienceUtility } from "../Shared/DefaultExperienceUtility"; import { Node, PortalEnv, updateUserContext, userContext } from "../UserContext"; import { acquireTokenWithMsal, getAuthorizationHeader, getMsalInstance } from "../Utils/AuthorizationUtils"; import { isInvalidParentFrameOrigin, shouldProcessMessage } from "../Utils/MessageValidation"; -import { listKeys } from "../Utils/arm/generatedClients/cosmos/databaseAccounts"; +import { getReadOnlyKeys, listKeys } from "../Utils/arm/generatedClients/cosmos/databaseAccounts"; import { applyExplorerBindings } from "../applyExplorerBindings"; import { useDataPlaneRbac } from "Explorer/Panes/SettingsPane/SettingsPane"; import * as Logger from "../Common/Logger"; @@ -453,25 +453,33 @@ function configureEmulator(): Explorer { return explorer; } -async function fetchAndUpdateKeys(subscriptionId: string, resourceGroup: string, account: string) { +export async function fetchAndUpdateKeys(subscriptionId: string, resourceGroup: string, account: string) { + Logger.logInfo(`Fetching keys for ${userContext.apiType} account ${account}`, "Explorer/fetchAndUpdateKeys"); + let keys; try { - Logger.logInfo(`Fetching keys for ${userContext.apiType} account ${account}`, "Explorer/fetchAndUpdateKeys"); - const keys = await listKeys(subscriptionId, resourceGroup, account); + keys = await listKeys(subscriptionId, resourceGroup, account); Logger.logInfo(`Keys fetched for ${userContext.apiType} account ${account}`, "Explorer/fetchAndUpdateKeys"); updateUserContext({ masterKey: keys.primaryMasterKey, }); - Logger.logInfo( - `User context updated with Master key for ${userContext.apiType} account ${account}`, - "Explorer/fetchAndUpdateKeys", - ); } catch (error) { - logConsoleError(`Error occurred fetching keys for the account." ${error.message}`); - Logger.logError( - `Error during fetching keys or updating user context: ${error} for ${userContext.apiType} account ${account}`, - "Explorer/fetchAndUpdateKeys", - ); - throw error; + if (error.code === "AuthorizationFailed") { + keys = await getReadOnlyKeys(subscriptionId, resourceGroup, account); + Logger.logInfo( + `Read only Keys fetched for ${userContext.apiType} account ${account}`, + "Explorer/fetchAndUpdateKeys", + ); + updateUserContext({ + masterKey: keys.primaryReadonlyMasterKey, + }); + } else { + logConsoleError(`Error occurred fetching keys for the account." ${error.message}`); + Logger.logError( + `Error during fetching keys or updating user context: ${error} for ${userContext.apiType} account ${account}`, + "Explorer/fetchAndUpdateKeys", + ); + throw error; + } } } From 70d1dc6f747dd3151c5b05cfd1e86d9f8f44ba05 Mon Sep 17 00:00:00 2001 From: Nitesh Vijay Date: Sat, 20 Jul 2024 00:02:42 +0530 Subject: [PATCH 2/3] Add vector search capability for emulator (#1917) --- src/Platform/Emulator/emulatorAccount.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Platform/Emulator/emulatorAccount.tsx b/src/Platform/Emulator/emulatorAccount.tsx index 295f9ee6f..59eda84e2 100644 --- a/src/Platform/Emulator/emulatorAccount.tsx +++ b/src/Platform/Emulator/emulatorAccount.tsx @@ -11,5 +11,11 @@ export const emulatorAccount = { tableEndpoint: "", gremlinEndpoint: "", cassandraEndpoint: "", + capabilities: [ + { + name: "EnableNoSqlVectorSearch", + description: "Enable Vector Search on NoSQL account", + }, + ], }, }; From 1e6c40eabf29343e349c9d14cc1150dbc00e2761 Mon Sep 17 00:00:00 2001 From: Nitesh Vijay Date: Tue, 23 Jul 2024 07:33:24 +0530 Subject: [PATCH 3/3] Fix vector search capability name (#1918) --- src/Platform/Emulator/emulatorAccount.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Platform/Emulator/emulatorAccount.tsx b/src/Platform/Emulator/emulatorAccount.tsx index 59eda84e2..211f4dfd8 100644 --- a/src/Platform/Emulator/emulatorAccount.tsx +++ b/src/Platform/Emulator/emulatorAccount.tsx @@ -13,7 +13,7 @@ export const emulatorAccount = { cassandraEndpoint: "", capabilities: [ { - name: "EnableNoSqlVectorSearch", + name: "EnableNoSQLVectorSearch", description: "Enable Vector Search on NoSQL account", }, ],