postgresql-charms-single-kernel 16.1.0__py3-none-any.whl → 16.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {postgresql_charms_single_kernel-16.1.0.dist-info → postgresql_charms_single_kernel-16.1.1.dist-info}/METADATA +1 -1
- {postgresql_charms_single_kernel-16.1.0.dist-info → postgresql_charms_single_kernel-16.1.1.dist-info}/RECORD +5 -5
- single_kernel_postgresql/utils/postgresql.py +76 -8
- {postgresql_charms_single_kernel-16.1.0.dist-info → postgresql_charms_single_kernel-16.1.1.dist-info}/WHEEL +0 -0
- {postgresql_charms_single_kernel-16.1.0.dist-info → postgresql_charms_single_kernel-16.1.1.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: postgresql-charms-single-kernel
|
|
3
|
-
Version: 16.1.
|
|
3
|
+
Version: 16.1.1
|
|
4
4
|
Summary: Shared and reusable code for PostgreSQL-related charms
|
|
5
5
|
Author-email: Canonical Data Platform <data-platform@lists.launchpad.net>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -4,8 +4,8 @@ single_kernel_postgresql/config/__init__.py,sha256=k9Ud5ZZNd3l0nn8xi8AIlT45oZk8h
|
|
|
4
4
|
single_kernel_postgresql/config/literals.py,sha256=88r33TBX7SXqgpV6EEXtZmSJrfOtsFiVJ_omop0RuBo,643
|
|
5
5
|
single_kernel_postgresql/utils/__init__.py,sha256=VwAEW3wYjs99q38bid47aS6Os4s3catK4H5HfdPkp94,121
|
|
6
6
|
single_kernel_postgresql/utils/filesystem.py,sha256=CJ2iXqFPKM0NfqqZSTDlENOrM0RW7rmTmcuzwV0bR9A,552
|
|
7
|
-
single_kernel_postgresql/utils/postgresql.py,sha256=
|
|
8
|
-
postgresql_charms_single_kernel-16.1.
|
|
9
|
-
postgresql_charms_single_kernel-16.1.
|
|
10
|
-
postgresql_charms_single_kernel-16.1.
|
|
11
|
-
postgresql_charms_single_kernel-16.1.
|
|
7
|
+
single_kernel_postgresql/utils/postgresql.py,sha256=IiEOFzrpiDXRWgwnvywiul9f8gU8hxCBaSqVFUyFgjU,79617
|
|
8
|
+
postgresql_charms_single_kernel-16.1.1.dist-info/METADATA,sha256=UD9GAm4GA4tQKAaWsDiR5uyN-k921jq2nt8Uwq6sqsE,484
|
|
9
|
+
postgresql_charms_single_kernel-16.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
10
|
+
postgresql_charms_single_kernel-16.1.1.dist-info/top_level.txt,sha256=fH85HKyfDV3--1JuYe-rWJmN5XTlXVXGOBO5iNA36Rk,25
|
|
11
|
+
postgresql_charms_single_kernel-16.1.1.dist-info/RECORD,,
|
|
@@ -114,6 +114,10 @@ class PostgreSQLCreateUserError(PostgreSQLBaseError):
|
|
|
114
114
|
self.message = message
|
|
115
115
|
|
|
116
116
|
|
|
117
|
+
class PostgreSQLUpdateUserError(PostgreSQLBaseError):
|
|
118
|
+
"""Exception raised when creating a user fails."""
|
|
119
|
+
|
|
120
|
+
|
|
117
121
|
class PostgreSQLUndefinedHostError(PostgreSQLBaseError):
|
|
118
122
|
"""Exception when host is not set."""
|
|
119
123
|
|
|
@@ -146,6 +150,10 @@ class PostgreSQLGetPostgreSQLVersionError(PostgreSQLBaseError):
|
|
|
146
150
|
"""Exception raised when retrieving PostgreSQL version fails."""
|
|
147
151
|
|
|
148
152
|
|
|
153
|
+
class PostgreSQLListDatabasesError(PostgreSQLBaseError):
|
|
154
|
+
"""Exception raised when retrieving the databases."""
|
|
155
|
+
|
|
156
|
+
|
|
149
157
|
class PostgreSQLListAccessibleDatabasesForUserError(PostgreSQLBaseError):
|
|
150
158
|
"""Exception raised when retrieving the accessible databases for a user fails."""
|
|
151
159
|
|
|
@@ -439,14 +447,28 @@ class PostgreSQL:
|
|
|
439
447
|
Returns:
|
|
440
448
|
A tuple containing the adjusted user definition and a list of additional statements.
|
|
441
449
|
"""
|
|
450
|
+
db_roles, connect_statements = self._adjust_user_roles(user, roles, database)
|
|
451
|
+
if db_roles:
|
|
452
|
+
str_roles = [f'"{role}"' for role in db_roles]
|
|
453
|
+
user_definition += f" IN ROLE {', '.join(str_roles)}"
|
|
454
|
+
return user_definition, connect_statements
|
|
455
|
+
|
|
456
|
+
def _adjust_user_roles(
|
|
457
|
+
self, user: str, roles: Optional[List[str]], database: Optional[str]
|
|
458
|
+
) -> Tuple[List[str], List[str]]:
|
|
459
|
+
"""Adjusts the user definition to include additional statements.
|
|
460
|
+
|
|
461
|
+
Returns:
|
|
462
|
+
A tuple containing the adjusted user definition and a list of additional statements.
|
|
463
|
+
"""
|
|
464
|
+
db_roles = []
|
|
442
465
|
connect_statements = []
|
|
443
466
|
if database:
|
|
444
467
|
if roles is not None and not any(
|
|
445
|
-
|
|
446
|
-
for role in roles
|
|
447
|
-
if role in [ROLE_STATS, ROLE_READ, ROLE_DML, ROLE_BACKUP, ROLE_DBA]
|
|
468
|
+
role in [ROLE_STATS, ROLE_READ, ROLE_DML, ROLE_BACKUP, ROLE_DBA] for role in roles
|
|
448
469
|
):
|
|
449
|
-
|
|
470
|
+
db_roles.append(f"charmed_{database}_admin")
|
|
471
|
+
db_roles.append(f"charmed_{database}_dml")
|
|
450
472
|
else:
|
|
451
473
|
connect_statements.append(
|
|
452
474
|
SQL("GRANT CONNECT ON DATABASE {} TO {};").format(
|
|
@@ -454,9 +476,7 @@ class PostgreSQL:
|
|
|
454
476
|
)
|
|
455
477
|
)
|
|
456
478
|
if roles is not None and any(
|
|
457
|
-
|
|
458
|
-
for role in roles
|
|
459
|
-
if role
|
|
479
|
+
role
|
|
460
480
|
in [
|
|
461
481
|
ROLE_STATS,
|
|
462
482
|
ROLE_READ,
|
|
@@ -466,6 +486,7 @@ class PostgreSQL:
|
|
|
466
486
|
ROLE_ADMIN,
|
|
467
487
|
ROLE_DATABASES_OWNER,
|
|
468
488
|
]
|
|
489
|
+
for role in roles
|
|
469
490
|
):
|
|
470
491
|
for system_database in ["postgres", "template1"]:
|
|
471
492
|
connect_statements.append(
|
|
@@ -473,7 +494,7 @@ class PostgreSQL:
|
|
|
473
494
|
Identifier(system_database), Identifier(user)
|
|
474
495
|
)
|
|
475
496
|
)
|
|
476
|
-
return
|
|
497
|
+
return db_roles, connect_statements
|
|
477
498
|
|
|
478
499
|
def _process_extra_user_roles(
|
|
479
500
|
self, user: str, extra_user_roles: Optional[List[str]] = None
|
|
@@ -1841,3 +1862,50 @@ $$ LANGUAGE plpgsql security definer;""" # noqa: S608
|
|
|
1841
1862
|
finally:
|
|
1842
1863
|
if connection:
|
|
1843
1864
|
connection.close()
|
|
1865
|
+
|
|
1866
|
+
def list_databases(self, prefix: Optional[str] = None) -> List[str]:
|
|
1867
|
+
"""List non-system databases starting with prefix."""
|
|
1868
|
+
prefix_stmt = (
|
|
1869
|
+
SQL(" AND datname LIKE {}").format(Literal(prefix + "%")) if prefix else SQL("")
|
|
1870
|
+
)
|
|
1871
|
+
try:
|
|
1872
|
+
with self._connect_to_database() as connection, connection.cursor() as cursor:
|
|
1873
|
+
cursor.execute(
|
|
1874
|
+
SQL(
|
|
1875
|
+
"SELECT datname FROM pg_database WHERE datistemplate = false AND datname <>'postgres'{};"
|
|
1876
|
+
).format(prefix_stmt)
|
|
1877
|
+
)
|
|
1878
|
+
return [row[0] for row in cursor.fetchall()]
|
|
1879
|
+
except psycopg2.Error as e:
|
|
1880
|
+
raise PostgreSQLListDatabasesError() from e
|
|
1881
|
+
finally:
|
|
1882
|
+
if connection:
|
|
1883
|
+
connection.close()
|
|
1884
|
+
|
|
1885
|
+
def add_user_to_databases(
|
|
1886
|
+
self, user: str, databases: List[str], extra_user_roles: Optional[List[str]] = None
|
|
1887
|
+
) -> None:
|
|
1888
|
+
"""Grant user access to database."""
|
|
1889
|
+
try:
|
|
1890
|
+
roles, _ = self._process_extra_user_roles(user, extra_user_roles)
|
|
1891
|
+
connect_stmt = []
|
|
1892
|
+
for database in databases:
|
|
1893
|
+
db_roles, db_connect_stmt = self._adjust_user_roles(user, roles, database)
|
|
1894
|
+
roles += db_roles
|
|
1895
|
+
connect_stmt += db_connect_stmt
|
|
1896
|
+
with self._connect_to_database() as connection, connection.cursor() as cursor:
|
|
1897
|
+
cursor.execute(SQL("RESET ROLE;"))
|
|
1898
|
+
cursor.execute(SQL("BEGIN;"))
|
|
1899
|
+
cursor.execute(SQL("SET LOCAL log_statement = 'none';"))
|
|
1900
|
+
cursor.execute(SQL("COMMIT;"))
|
|
1901
|
+
|
|
1902
|
+
# Add extra user roles to the new user.
|
|
1903
|
+
for role in roles:
|
|
1904
|
+
cursor.execute(
|
|
1905
|
+
SQL("GRANT {} TO {};").format(Identifier(role), Identifier(user))
|
|
1906
|
+
)
|
|
1907
|
+
for statement in connect_stmt:
|
|
1908
|
+
cursor.execute(statement)
|
|
1909
|
+
except psycopg2.Error as e:
|
|
1910
|
+
logger.error(f"Failed to create user: {e}")
|
|
1911
|
+
raise PostgreSQLUpdateUserError() from e
|
|
File without changes
|
|
File without changes
|