Skip to content

Reveal europe-west1 region for RTDB #2812

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Nov 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
- Adds support for the `europe-west1` region for Firebase Realtime Database.
- Fixes an issue where the `${param:FOO}` syntax for Firebase Extensions did not work with the emulator.
- Fixes issue in `database:settings:get` where the value wasn't being properly displayed.
- Fixes Firebase Console URLs for Firebase Realtime Database `database:push`, `database:set`, and `database:update` commands.
2 changes: 1 addition & 1 deletion src/commands/database-get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default new Command("database:get <path>")
return utils.reject("Path must begin with /", { exit: 1 });
}

const dbHost = realtimeOriginOrEmulatorOrCustomUrl(options);
const dbHost = realtimeOriginOrEmulatorOrCustomUrl(options.instanceDetails.databaseUrl);
const dbUrl = utils.getDatabaseUrl(dbHost, options.instance, path + ".json");
const query: { [key: string]: string } = {};
if (options.shallow) {
Expand Down
31 changes: 9 additions & 22 deletions src/commands/database-instances-create.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,23 @@
import { Command } from "../command";
import logger = require("../logger");
import { requirePermissions } from "../requirePermissions";
import getProjectNumber = require("../getProjectNumber");
import firedata = require("../gcp/firedata");
import { warnEmulatorNotSupported } from "../emulator/commandUtils";
import { Emulators } from "../emulator/types";
import { previews } from "../previews";
import { createInstance, DatabaseLocation, parseDatabaseLocation } from "../management/database";
import getProjectId = require("../getProjectId");

let cmd = new Command("database:instances:create <instanceName>")
export default new Command("database:instances:create <instanceName>")
.description("create a realtime database instance")

.option(
"-l, --location <location>",
"(optional) location for the database instance, defaults to us-central1"
)
.before(requirePermissions, ["firebasedatabase.instances.create"])
.before(warnEmulatorNotSupported, Emulators.DATABASE)
.action(async (instanceName: string, options: any) => {
if (previews.rtdbmanagement) {
const projectId = getProjectId(options);
const location = parseDatabaseLocation(options.location, DatabaseLocation.US_CENTRAL1);
const instance = await createInstance(projectId, instanceName, location);
logger.info(`created database instance ${instance.name}`);
return instance;
}
const projectNumber = await getProjectNumber(options);
const instance = await firedata.createDatabaseInstance(projectNumber, instanceName);
logger.info(`created database instance ${instance.instance}`);
const projectId = getProjectId(options);
const location = parseDatabaseLocation(options.location, DatabaseLocation.US_CENTRAL1);
const instance = await createInstance(projectId, instanceName, location);
logger.info(`created database instance ${instance.name}`);
return instance;
});
if (previews.rtdbmanagement) {
cmd = cmd.option(
"-l, --location <location>",
"(optional) location for the database instance, defaults to us-central1"
);
}
export default cmd;
2 changes: 1 addition & 1 deletion src/commands/database-push.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ module.exports = new Command("database:push <path> [infile]")
}
var inStream =
utils.stringToStream(options.data) || (infile ? fs.createReadStream(infile) : process.stdin);
const origin = realtimeOriginOrEmulatorOrCustomUrl(options);
const origin = realtimeOriginOrEmulatorOrCustomUrl(options.instanceDetails.databaseUrl);
var url = utils.getDatabaseUrl(origin, options.instance, path + ".json");

if (!infile && !options.data) {
Expand Down
2 changes: 1 addition & 1 deletion src/commands/database-remove.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = new Command("database:remove <path>")
if (!_.startsWith(path, "/")) {
return utils.reject("Path must begin with /", { exit: 1 });
}
const origin = realtimeOriginOrEmulatorOrCustomUrl(options);
const origin = realtimeOriginOrEmulatorOrCustomUrl(options.instanceDetails.databaseUrl);
const databaseUrl = utils.getDatabaseUrl(origin, options.instance, path);
return prompt(options, [
{
Expand Down
2 changes: 1 addition & 1 deletion src/commands/database-set.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ module.exports = new Command("database:set <path> [infile]")
if (!_.startsWith(path, "/")) {
return utils.reject("Path must begin with /", { exit: 1 });
}
const origin = realtimeOriginOrEmulatorOrCustomUrl(options);
const origin = realtimeOriginOrEmulatorOrCustomUrl(options.instanceDetails.databaseUrl);
const dbPath = utils.getDatabaseUrl(origin, options.instance, path);
const dbJsonPath = utils.getDatabaseUrl(origin, options.instance, path + ".json");

Expand Down
2 changes: 1 addition & 1 deletion src/commands/database-settings-get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default new Command("database:settings:get <path>")
}
const u = new URL(
utils.getDatabaseUrl(
realtimeOriginOrCustomUrl(options),
realtimeOriginOrCustomUrl(options.instanceDetails.databaseUrl),
options.instance,
`/.settings/${path}.json`
)
Expand Down
2 changes: 1 addition & 1 deletion src/commands/database-settings-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default new Command("database:settings:set <path> <value>")

const u = new URL(
utils.getDatabaseUrl(
realtimeOriginOrCustomUrl(options),
realtimeOriginOrCustomUrl(options.instanceDetails.databaseUrl),
options.instance,
`/.settings/${path}.json`
)
Expand Down
2 changes: 1 addition & 1 deletion src/commands/database-update.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ module.exports = new Command("database:update <path> [infile]")
if (!_.startsWith(path, "/")) {
return utils.reject("Path must begin with /", { exit: 1 });
}
const origin = realtimeOriginOrEmulatorOrCustomUrl(options);
const origin = realtimeOriginOrEmulatorOrCustomUrl(options.instanceDetails.databaseUrl);
const url = utils.getDatabaseUrl(origin, options.instance, path);
return prompt(options, [
{
Expand Down
13 changes: 4 additions & 9 deletions src/database/api.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import { envOverride } from "../utils";
import { Constants } from "../emulator/constants";
import { previews } from "../previews";

const DEFAULT_HOST = "https://firebaseio.com";

/**
* Get base URL for RealtimeDatabase. Preference order: emulator host env override, realtime URL env override, options.instanceDetails.databaseUrl, and then default host.
* Get base URL for RealtimeDatabase. Preference order: emulator host env override, realtime URL env override, and then specified host.
* @param options command options.
*/
export function realtimeOriginOrEmulatorOrCustomUrl(options: any): string {
const host = previews.rtdbmanagement ? options.instanceDetails.databaseUrl : DEFAULT_HOST;
export function realtimeOriginOrEmulatorOrCustomUrl(host: string): string {
return envOverride(
Constants.FIREBASE_DATABASE_EMULATOR_HOST,
envOverride("FIREBASE_REALTIME_URL", host),
Expand All @@ -18,11 +14,10 @@ export function realtimeOriginOrEmulatorOrCustomUrl(options: any): string {
}

/**
* Get base URL for RealtimeDatabase. Preference order: realtime URL env override, options.instanceDetails.databaseUrl, and then default host.
* Get base URL for RealtimeDatabase. Preference order: realtime URL env override, and then the specified host.
* @param options command options.
*/
export function realtimeOriginOrCustomUrl(options: any): string {
const host = previews.rtdbmanagement ? options.instanceDetails.databaseUrl : DEFAULT_HOST;
export function realtimeOriginOrCustomUrl(host: string): string {
return envOverride("FIREBASE_REALTIME_URL", host);
}

Expand Down
11 changes: 2 additions & 9 deletions src/management/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@
import * as api from "../api";
import * as logger from "../logger";
import * as utils from "../utils";
import { previews } from "../previews";
import { FirebaseError } from "../error";
import { Constants } from "../emulator/constants";
const MGMT_API_VERSION = "v1beta";
const TIMEOUT_MILLIS = 10000;
const APP_LIST_PAGE_SIZE = 100;
// projects/$PROJECT_ID/locations/$LOCATION_ID/instances/$INSTANCE_ID
const INSTANCE_RESOURCE_NAME_REGEX = /projects\/([^\/]+?)\/locations\/([^\/]+?)\/instances\/([^\/]*)/;

export enum DatabaseInstanceType {
Expand All @@ -31,7 +29,6 @@ export enum DatabaseInstanceState {
export enum DatabaseLocation {
US_CENTRAL1 = "us-central1",
EUROPE_WEST1 = "europe-west1",
ASIA_SOUTHEAST1 = "asia-southeast1",
ANY = "-",
}

Expand All @@ -49,9 +46,7 @@ export interface DatabaseInstance {
* @param options command options that will be modified to add instanceDetails.
*/
export async function populateInstanceDetails(options: any): Promise<void> {
if (previews.rtdbmanagement) {
options.instanceDetails = await getDatabaseInstanceDetails(options.project, options.instance);
}
options.instanceDetails = await getDatabaseInstanceDetails(options.project, options.instance);
return Promise.resolve();
}

Expand Down Expand Up @@ -152,15 +147,13 @@ export function parseDatabaseLocation(
switch (location.toLowerCase()) {
case "europe-west1":
return DatabaseLocation.EUROPE_WEST1;
case "asia-southeast1":
return DatabaseLocation.ASIA_SOUTHEAST1;
case "us-central1":
return DatabaseLocation.US_CENTRAL1;
case "":
return defaultLocation;
default:
throw new FirebaseError(
`Unexpected location value: ${location}. Only us-central1, europe-west1, and asia-southeast1 locations are supported`
`Unexpected location value: ${location}. Only us-central1, and europe-west1 locations are supported`
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/profiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ tmp.setGracefulCleanup();
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export async function profiler(options: any): Promise<unknown> {
const origin = realtimeOriginOrEmulatorOrCustomUrl(options);
const origin = realtimeOriginOrEmulatorOrCustomUrl(options.instanceDetails.databaseUrl);
const url = new URL(utils.getDatabaseUrl(origin, options.instance, "/.settings/profile.json?"));
const rl = readline.createInterface({ input: process.stdin });

Expand Down
2 changes: 1 addition & 1 deletion src/rtdb.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ exports.updateRules = function(projectId, instance, src, options) {
return populateInstanceDetails(downstreamOptions)
.then(function() {
const origin = utils.getDatabaseUrl(
realtimeOriginOrCustomUrl(downstreamOptions),
realtimeOriginOrCustomUrl(downstreamOptions.instanceDetails.databaseUrl),
instance,
""
);
Expand Down
27 changes: 12 additions & 15 deletions src/test/management/database.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ const SOME_DATABASE_INSTANCE: DatabaseInstance = {

const SOME_DATABASE_INSTANCE_ASIA_SOUTHEAST: DatabaseInstance = {
name: DATABASE_INSTANCE_NAME,
location: DatabaseLocation.ASIA_SOUTHEAST1,
location: DatabaseLocation.EUROPE_WEST1,
project: PROJECT_ID,
databaseUrl: generateDatabaseUrl(DATABASE_INSTANCE_NAME, DatabaseLocation.ASIA_SOUTHEAST1),
databaseUrl: generateDatabaseUrl(DATABASE_INSTANCE_NAME, DatabaseLocation.EUROPE_WEST1),
type: DatabaseInstanceType.USER_DATABASE,
state: DatabaseInstanceState.ACTIVE,
};
Expand All @@ -41,10 +41,10 @@ const INSTANCE_RESPONSE_US_CENTRAL1 = {
state: DatabaseInstanceState.ACTIVE,
};

const INSTANCE_RESPONSE_ASIA_SOUTHEAST1 = {
name: `projects/${PROJECT_ID}/locations/${DatabaseLocation.ASIA_SOUTHEAST1}/instances/${DATABASE_INSTANCE_NAME}`,
const INSTANCE_RESPONSE_EUROPE_WEST1 = {
name: `projects/${PROJECT_ID}/locations/${DatabaseLocation.EUROPE_WEST1}/instances/${DATABASE_INSTANCE_NAME}`,
project: PROJECT_ID,
databaseUrl: generateDatabaseUrl(DATABASE_INSTANCE_NAME, DatabaseLocation.ASIA_SOUTHEAST1),
databaseUrl: generateDatabaseUrl(DATABASE_INSTANCE_NAME, DatabaseLocation.EUROPE_WEST1),
type: DatabaseInstanceType.USER_DATABASE,
state: DatabaseInstanceState.ACTIVE,
};
Expand Down Expand Up @@ -149,16 +149,16 @@ describe("Database management", () => {
describe("createInstance", () => {
it("should resolve with new DatabaseInstance if API call succeeds", async () => {
const expectedDatabaseInstance = SOME_DATABASE_INSTANCE_ASIA_SOUTHEAST;
apiRequestStub.onFirstCall().resolves({ body: INSTANCE_RESPONSE_ASIA_SOUTHEAST1 });
apiRequestStub.onFirstCall().resolves({ body: INSTANCE_RESPONSE_EUROPE_WEST1 });
const resultDatabaseInstance = await createInstance(
PROJECT_ID,
DATABASE_INSTANCE_NAME,
DatabaseLocation.ASIA_SOUTHEAST1
DatabaseLocation.EUROPE_WEST1
);
expect(resultDatabaseInstance).to.deep.equal(expectedDatabaseInstance);
expect(apiRequestStub).to.be.calledOnceWith(
"POST",
`/v1beta/projects/${PROJECT_ID}/locations/${DatabaseLocation.ASIA_SOUTHEAST1}/instances?databaseId=${DATABASE_INSTANCE_NAME}`,
`/v1beta/projects/${PROJECT_ID}/locations/${DatabaseLocation.EUROPE_WEST1}/instances?databaseId=${DATABASE_INSTANCE_NAME}`,
{
auth: true,
origin: api.rtdbManagementOrigin,
Expand Down Expand Up @@ -200,16 +200,13 @@ describe("Database management", () => {
const instancesPerLocation = 2;
const expectedInstanceList = [
...generateInstanceList(instancesPerLocation, DatabaseLocation.US_CENTRAL1),
...generateInstanceList(instancesPerLocation, DatabaseLocation.ASIA_SOUTHEAST1),
...generateInstanceList(instancesPerLocation, DatabaseLocation.EUROPE_WEST1),
];
apiRequestStub.onFirstCall().resolves({
body: {
instances: [
...generateInstanceListApiResponse(instancesPerLocation, DatabaseLocation.US_CENTRAL1),
...generateInstanceListApiResponse(
instancesPerLocation,
DatabaseLocation.ASIA_SOUTHEAST1
),
...generateInstanceListApiResponse(instancesPerLocation, DatabaseLocation.EUROPE_WEST1),
],
},
});
Expand Down Expand Up @@ -261,13 +258,13 @@ describe("Database management", () => {
const nextPageToken = "next-page-token";
const expectedInstancesList = [
...generateInstanceList(countPerLocation, DatabaseLocation.US_CENTRAL1),
...generateInstanceList(countPerLocation, DatabaseLocation.ASIA_SOUTHEAST1),
...generateInstanceList(countPerLocation, DatabaseLocation.EUROPE_WEST1),
...generateInstanceList(countPerLocation, DatabaseLocation.EUROPE_WEST1),
];

const expectedResponsesList = [
...generateInstanceListApiResponse(countPerLocation, DatabaseLocation.US_CENTRAL1),
...generateInstanceListApiResponse(countPerLocation, DatabaseLocation.ASIA_SOUTHEAST1),
...generateInstanceListApiResponse(countPerLocation, DatabaseLocation.EUROPE_WEST1),
...generateInstanceListApiResponse(countPerLocation, DatabaseLocation.EUROPE_WEST1),
];

Expand Down