From b1f2b249e086d610910b403e1274ebd62f6dbfe6 Mon Sep 17 00:00:00 2001 From: corya-akamai <136115382+corya-akamai@users.noreply.github.com> Date: Fri, 1 Nov 2024 15:09:38 -0400 Subject: [PATCH] feat: [UIE-8194] - DBaaS Upgrades and Maintenance 1 (#11196) --- ...r-11196-upcoming-features-1730465602676.md | 5 + packages/api-v4/src/databases/databases.ts | 15 +++ packages/api-v4/src/databases/types.ts | 103 ++++++++++-------- ...r-11196-upcoming-features-1730465663102.md | 5 + packages/manager/src/factories/databases.ts | 23 ++++ .../src/queries/databases/databases.ts | 17 +++ 6 files changed, 124 insertions(+), 44 deletions(-) create mode 100644 packages/api-v4/.changeset/pr-11196-upcoming-features-1730465602676.md create mode 100644 packages/manager/.changeset/pr-11196-upcoming-features-1730465663102.md diff --git a/packages/api-v4/.changeset/pr-11196-upcoming-features-1730465602676.md b/packages/api-v4/.changeset/pr-11196-upcoming-features-1730465602676.md new file mode 100644 index 00000000000..aef96620c9a --- /dev/null +++ b/packages/api-v4/.changeset/pr-11196-upcoming-features-1730465602676.md @@ -0,0 +1,5 @@ +--- +"@linode/api-v4": Upcoming Features +--- + +DBaaS modify update payload to include version, add patch API ([#11196](https://github.com/linode/manager/pull/11196)) diff --git a/packages/api-v4/src/databases/databases.ts b/packages/api-v4/src/databases/databases.ts index 53e5cbea952..a735955cdd6 100644 --- a/packages/api-v4/src/databases/databases.ts +++ b/packages/api-v4/src/databases/databases.ts @@ -163,6 +163,21 @@ export const updateDatabase = ( setData(data, updateDatabaseSchema) ); +/** + * patchDatabase + * + * Patch security updates for the database (outside of the maintenance window) + */ +export const patchDatabase = (engine: Engine, databaseID: number) => + Request( + setURL( + `${API_ROOT}/databases/${encodeURIComponent( + engine + )}/instances/${encodeURIComponent(databaseID)}/patch` + ), + setMethod('POST') + ); + /** * deleteDatabase * diff --git a/packages/api-v4/src/databases/types.ts b/packages/api-v4/src/databases/types.ts index c6b93c01057..a499032962a 100644 --- a/packages/api-v4/src/databases/types.ts +++ b/packages/api-v4/src/databases/types.ts @@ -2,6 +2,8 @@ import { BaseType } from '../linodes/types'; export type DatabaseTypeClass = 'standard' | 'dedicated' | 'nanode' | 'premium'; +export type Platform = 'rdbms-default' | 'rdbms-legacy'; + export interface DatabasePriceObject { monthly: number; hourly: number; @@ -24,7 +26,7 @@ export interface DatabaseEngine { id: string; engine: Engine; version: string; - deprecated: boolean; + deprecated?: boolean; } export type DatabaseStatus = @@ -71,24 +73,30 @@ type MemberType = 'primary' | 'failover'; // DatabaseInstance is the interface for the shape of data returned by the /databases/instances endpoint. export interface DatabaseInstance { - id: number; - label: string; - engine: Engine; - type: string; - region: string; - version: string; - status: DatabaseStatus; + allow_list: string[]; cluster_size: ClusterSize; - updated: string; + connection_strings: ConnectionStrings[]; created: string; - instance_uri: string; + /** @Deprecated used by rdbms-legacy only, rdbms-default always encrypts */ + encrypted: boolean; + engine: Engine; hosts: DatabaseHosts; + id: number; + instance_uri?: string; + label: string; /** * A key/value object where the key is an IP address and the value is a member type. */ members: Record; - platform?: string; - allow_list: string[]; + oldest_restore_time?: string; + platform?: Platform; + readonly_count?: ReadonlyCount; + region: string; + status: DatabaseStatus; + type: string; + updated: string; + updates: UpdatesSchedule; + version: string; } export type ClusterSize = 1 | 2 | 3; @@ -98,15 +106,18 @@ type ReadonlyCount = 0 | 2; export type MySQLReplicationType = 'none' | 'semi_synch' | 'asynch'; export interface CreateDatabasePayload { - label: string; - region: string; - type: string; + allow_list?: string[]; cluster_size?: ClusterSize; - engine?: Engine; + /** @Deprecated used by rdbms-legacy only, rdbms-default always encrypts */ encrypted?: boolean; - ssl_connection?: boolean; + engine?: Engine; + label: string; + region: string; + /** @Deprecated used by rdbms-legacy only */ replication_type?: MySQLReplicationType | PostgresReplicationType; - allow_list?: string[]; + /** @Deprecated used by rdbms-legacy only, rdbms-default always uses TLS */ + ssl_connection?: boolean; + type: string; } type DriverTypes = 'jdbc' | 'odbc' | 'php' | 'python' | 'ruby' | 'node.js'; @@ -116,34 +127,40 @@ interface ConnectionStrings { } export type UpdatesFrequency = 'weekly' | 'monthly'; + export interface UpdatesSchedule { - frequency: UpdatesFrequency; + day_of_week: number; duration: number; + frequency: UpdatesFrequency; hour_of_day: number; - day_of_week: number; + pending?: PendingUpdates[]; week_of_month: number | null; } +/** + * Maintenance/patches for the next maintenance window + * @since V2GA */ +export interface PendingUpdates { + /** + * Optional ISO-8601 UTC timestamp + * describing the point in time by which a mandatory update must be applied. + * Not all updates have deadlines. + */ + deadline: string | null; + description: string; + /** + * Optional ISO-8601 UTC timestamp + * describing the maintenance window in which the update is planned to be applied. + * Users may trigger these updates outside a scheduled maintenance window by calling the patch API. + */ + planned_for: string | null; +} + // Database is the base interface for the shape of data returned by /databases/{engine}/instances -export interface BaseDatabase { - id: number; - label: string; - type: string; - version: string; - region: string; - status: DatabaseStatus; - cluster_size: ClusterSize; - readonly_count?: ReadonlyCount; - engine: Engine; - encrypted: boolean; - ssl_connection: boolean; - allow_list: string[]; - connection_strings: ConnectionStrings[]; - created: string; - updated: string; - hosts: DatabaseHosts; +interface BaseDatabase extends DatabaseInstance { port: number; - updates: UpdatesSchedule; + /** @Deprecated used by rdbms-legacy only, rdbms-default always uses TLS */ + ssl_connection: boolean; /** * total_disk_size_gb is feature flagged by the API. * It may not be defined. @@ -154,15 +171,10 @@ export interface BaseDatabase { * It may not be defined. */ used_disk_size_gb?: number; - /** - * A key/value object where the key is an IP address and the value is a member type. - */ - members: Record; - platform?: string; - oldest_restore_time?: string; } export interface MySQLDatabase extends BaseDatabase { + /** @Deprecated used by rdbms-legacy only */ replication_type?: MySQLReplicationType; } @@ -176,7 +188,9 @@ type ReplicationCommitTypes = | 'off'; export interface PostgresDatabase extends BaseDatabase { + /** @Deprecated used by rdbms-legacy only */ replication_type?: PostgresReplicationType; + /** @Deprecated used by rdbms-legacy only */ replication_commit_type?: ReplicationCommitTypes; } @@ -203,4 +217,5 @@ export interface UpdateDatabasePayload { allow_list?: string[]; updates?: UpdatesSchedule; type?: string; + version?: string; } diff --git a/packages/manager/.changeset/pr-11196-upcoming-features-1730465663102.md b/packages/manager/.changeset/pr-11196-upcoming-features-1730465663102.md new file mode 100644 index 00000000000..c6d0b96144c --- /dev/null +++ b/packages/manager/.changeset/pr-11196-upcoming-features-1730465663102.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Upcoming Features +--- + +DBaaS add query to patch API, modify factory to include pendingUpdates ([#11196](https://github.com/linode/manager/pull/11196)) diff --git a/packages/manager/src/factories/databases.ts b/packages/manager/src/factories/databases.ts index fe7f5f1ecc0..3877ef2a84a 100644 --- a/packages/manager/src/factories/databases.ts +++ b/packages/manager/src/factories/databases.ts @@ -179,7 +179,9 @@ export const databaseInstanceFactory = Factory.Sync.makeFactory ['mysql', 'postgresql'][i % 2] as Engine), hosts: Factory.each((i) => adb10(i) @@ -205,6 +207,20 @@ export const databaseInstanceFactory = Factory.Sync.makeFactory possibleStatuses[i % possibleStatuses.length]), type: Factory.each((i) => possibleTypes[i % possibleTypes.length]), updated: '2021-12-16T17:15:12', + updates: { + day_of_week: 1, + duration: 3, + frequency: 'weekly', + hour_of_day: 20, + pending: [ + { + deadline: null, + description: 'Log configuration options changes required', + planned_for: '2044-09-15T17:15:12', + }, + ], + week_of_month: null, + }, version: Factory.each((i) => ['8.0.30', '15.7'][i % 2]), } ); @@ -251,6 +267,13 @@ export const databaseFactory = Factory.Sync.makeFactory({ duration: 3, frequency: 'weekly', hour_of_day: 20, + pending: [ + { + deadline: null, + description: 'Log configuration options changes required', + planned_for: '2044-09-15T17:15:12', + }, + ], week_of_month: null, }, used_disk_size_gb: 5, diff --git a/packages/manager/src/queries/databases/databases.ts b/packages/manager/src/queries/databases/databases.ts index 1913ba799f3..6e958cd7bd8 100644 --- a/packages/manager/src/queries/databases/databases.ts +++ b/packages/manager/src/queries/databases/databases.ts @@ -6,6 +6,7 @@ import { getDatabases, getEngineDatabase, legacyRestoreWithBackup, + patchDatabase, resetDatabaseCredentials, restoreWithBackup, updateDatabase, @@ -135,6 +136,22 @@ export const useDatabaseMutation = (engine: Engine, id: number) => { }); }; +export const usePatchDatabaseMutation = (engine: Engine, id: number) => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: () => patchDatabase(engine, id), + onSuccess() { + queryClient.invalidateQueries({ + queryKey: databaseQueries.databases.queryKey, + }); + queryClient.invalidateQueries({ + exact: true, + queryKey: databaseQueries.database(engine, id).queryKey, + }); + }, + }); +}; + export const useCreateDatabaseMutation = () => { const queryClient = useQueryClient(); return useMutation({