Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Added support for enabling, disabling, and displaying Point In Time Recovery enablement state on Firestore databases (#6388)
22 changes: 21 additions & 1 deletion src/commands/firestore-databases-create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export const command = new Command("firestore:databases:create <database>")
"--delete-protection <deleteProtectionState>",
"Whether or not to prevent deletion of database, for example 'ENABLED' or 'DISABLED'. Default is 'DISABLED'"
)
.option(
"--point-in-time-recovery <enablement>",
"Whether to enable the PITR feature on this database, for example 'ENABLED' or 'DISABLED'. Default is 'DISABLED'"
)
.before(requirePermissions, ["datastore.databases.create"])
.before(warnEmulatorNotSupported, Emulators.FIRESTORE)
.action(async (database: string, options: FirestoreOptions) => {
Expand Down Expand Up @@ -45,12 +49,28 @@ export const command = new Command("firestore:databases:create <database>")
? types.DatabaseDeleteProtectionState.ENABLED
: types.DatabaseDeleteProtectionState.DISABLED;

if (
options.pointInTimeRecovery &&
options.pointInTimeRecovery !== types.PointInTimeRecoveryEnablementOption.ENABLED &&
options.pointInTimeRecovery !== types.PointInTimeRecoveryEnablementOption.DISABLED
) {
logger.error(
"Invalid value for flag --point-in-time-recovery. See firebase firestore:databases:create --help for more info."
);
return;
}
const pointInTimeRecoveryEnablement: types.PointInTimeRecoveryEnablement =
options.pointInTimeRecovery === types.PointInTimeRecoveryEnablementOption.ENABLED
? types.PointInTimeRecoveryEnablement.ENABLED
: types.PointInTimeRecoveryEnablement.DISABLED;

const databaseResp: types.DatabaseResp = await api.createDatabase(
options.project,
database,
options.location,
type,
deleteProtectionState
deleteProtectionState,
pointInTimeRecoveryEnablement
);

if (options.json) {
Expand Down
24 changes: 22 additions & 2 deletions src/commands/firestore-databases-update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ export const command = new Command("firestore:databases:update <database>")
"--delete-protection <deleteProtectionState>",
"Whether or not to prevent deletion of database, for example 'ENABLED' or 'DISABLED'. Default is 'DISABLED'"
)
.option(
"--point-in-time-recovery <enablement>",
"Whether to enable the PITR feature on this database, for example 'ENABLED' or 'DISABLED'. Default is 'DISABLED'"
)
.before(requirePermissions, ["datastore.databases.update"])
.before(warnEmulatorNotSupported, Emulators.FIRESTORE)
.action(async (database: string, options: FirestoreOptions) => {
const api = new fsi.FirestoreApi();

if (!options.type && !options.deleteProtection) {
if (!options.type && !options.deleteProtection && !options.pointInTimeRecovery) {
logger.error(
"Missing properties to update. See firebase firestore:databases:update --help for more info."
);
Expand All @@ -44,11 +48,27 @@ export const command = new Command("firestore:databases:update <database>")
? types.DatabaseDeleteProtectionState.ENABLED
: types.DatabaseDeleteProtectionState.DISABLED;

if (
options.pointInTimeRecovery &&
options.pointInTimeRecovery !== types.PointInTimeRecoveryEnablementOption.ENABLED &&
options.pointInTimeRecovery !== types.PointInTimeRecoveryEnablementOption.DISABLED
) {
logger.error(
"Invalid value for flag --point-in-time-recovery. See firebase firestore:databases:update --help for more info."
);
return;
}
const pointInTimeRecoveryEnablement: types.PointInTimeRecoveryEnablement =
options.pointInTimeRecovery === types.PointInTimeRecoveryEnablementOption.ENABLED
? types.PointInTimeRecoveryEnablement.ENABLED
: types.PointInTimeRecoveryEnablement.DISABLED;

const databaseResp: types.DatabaseResp = await api.updateDatabase(
options.project,
database,
type,
deleteProtectionState
deleteProtectionState,
pointInTimeRecoveryEnablement
);

if (options.json) {
Expand Down
14 changes: 14 additions & 0 deletions src/firestore/api-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,21 @@ export enum DatabaseDeleteProtectionState {
DISABLED = "DELETE_PROTECTION_DISABLED",
}

export enum PointInTimeRecoveryEnablementOption {
ENABLED = "ENABLED",
DISABLED = "DISABLED",
}

export enum PointInTimeRecoveryEnablement {
ENABLED = "POINT_IN_TIME_RECOVERY_ENABLED",
DISABLED = "POINT_IN_TIME_RECOVERY_DISABLED",
}

export interface DatabaseReq {
locationId?: string;
type?: DatabaseType;
deleteProtectionState?: DatabaseDeleteProtectionState;
pointInTimeRecoveryEnablement?: PointInTimeRecoveryEnablement;
}

export interface DatabaseResp {
Expand All @@ -122,5 +133,8 @@ export interface DatabaseResp {
appEngineIntegrationMode: string;
keyPrefix: string;
deleteProtectionState: DatabaseDeleteProtectionState;
pointInTimeRecoveryEnablement: PointInTimeRecoveryEnablement;
etag: string;
versionRetentionPeriod: string;
earliestVersionTime: string;
}
15 changes: 12 additions & 3 deletions src/firestore/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,10 @@ export class FirestoreApi {
["Last Update Time", clc.yellow(database.updateTime)],
["Type", clc.yellow(database.type)],
["Location", clc.yellow(database.locationId)],
["Delete Protection State", clc.yellow(database.deleteProtectionState)]
["Delete Protection State", clc.yellow(database.deleteProtectionState)],
["Point In Time Recovery", clc.yellow(database.pointInTimeRecoveryEnablement)],
["Earliest Version Time", clc.yellow(database.earliestVersionTime)],
["Version Retention Period", clc.yellow(database.versionRetentionPeriod)]
);
logger.info(table.toString());
}
Expand Down Expand Up @@ -716,19 +719,22 @@ export class FirestoreApi {
* @param locationId the id of the region the database will be created in
* @param type FIRESTORE_NATIVE or DATASTORE_MODE
* @param deleteProtectionState DELETE_PROTECTION_ENABLED or DELETE_PROTECTION_DISABLED
* @param pointInTimeRecoveryEnablement POINT_IN_TIME_RECOVERY_ENABLED or POINT_IN_TIME_RECOVERY_DISABLED
*/
async createDatabase(
project: string,
databaseId: string,
locationId: string,
type: types.DatabaseType,
deleteProtectionState: types.DatabaseDeleteProtectionState
deleteProtectionState: types.DatabaseDeleteProtectionState,
pointInTimeRecoveryEnablement: types.PointInTimeRecoveryEnablement
): Promise<types.DatabaseResp> {
const url = `/projects/${project}/databases`;
const payload: types.DatabaseReq = {
type,
locationId,
deleteProtectionState,
pointInTimeRecoveryEnablement,
};
const options = { queryParams: { databaseId: databaseId } };
const res = await this.apiClient.post<types.DatabaseReq, { response?: types.DatabaseResp }>(
Expand All @@ -750,17 +756,20 @@ export class FirestoreApi {
* @param databaseId the name of the Firestore Database
* @param type FIRESTORE_NATIVE or DATASTORE_MODE
* @param deleteProtectionState DELETE_PROTECTION_ENABLED or DELETE_PROTECTION_DISABLED
* @param pointInTimeRecoveryEnablement POINT_IN_TIME_RECOVERY_ENABLED or POINT_IN_TIME_RECOVERY_DISABLED
*/
async updateDatabase(
project: string,
databaseId: string,
type?: types.DatabaseType,
deleteProtectionState?: types.DatabaseDeleteProtectionState
deleteProtectionState?: types.DatabaseDeleteProtectionState,
pointInTimeRecoveryEnablement?: types.PointInTimeRecoveryEnablement
): Promise<types.DatabaseResp> {
const url = `/projects/${project}/databases/${databaseId}`;
const payload: types.DatabaseReq = {
type,
deleteProtectionState,
pointInTimeRecoveryEnablement,
};
const res = await this.apiClient.patch<types.DatabaseReq, { response?: types.DatabaseResp }>(
url,
Expand Down
1 change: 1 addition & 0 deletions src/firestore/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export interface FirestoreOptions extends Options {
location?: string;
type?: types.DatabaseType;
deleteProtection?: types.DatabaseDeleteProtectionStateOption;
pointInTimeRecoveryEnablement?: types.PointInTimeRecoveryEnablementOption;
}