Skip to content

Commit

Permalink
Allow enabling and disabling PITR on Firestore databases (#6427)
Browse files Browse the repository at this point in the history
Also show Point In Time Recovery setting, earliest version time, and version retention period on get
  • Loading branch information
rwhogg authored Oct 10, 2023
1 parent 83e61b6 commit 0866cf9
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 6 deletions.
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;
}

0 comments on commit 0866cf9

Please sign in to comment.