Skip to content

Commit 27d44c7

Browse files
committed
Fix JWT reset after snapshot restore
1 parent 56ae6d7 commit 27d44c7

File tree

1 file changed

+61
-29
lines changed

1 file changed

+61
-29
lines changed

crate/operator/operations.py

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,7 @@ async def set_user_jwt(
11651165
:param namespace: The Kubernetes namespace of the CrateDB cluster.
11661166
:param name: The CrateDB custom resource name defining the CrateDB cluster.
11671167
:param username: The name of the user the JWT properties should be set for.
1168+
:param logger: Logger for operation tracking.
11681169
"""
11691170
cratedb = await get_cratedb_resource(namespace, name)
11701171
await cursor.execute(
@@ -1175,36 +1176,67 @@ async def set_user_jwt(
11751176

11761177
username_ident = quote_ident(username, cursor._impl)
11771178
iss = cratedb["spec"].get("grandCentral", {}).get("jwkUrl")
1178-
logger.info("Setting JWT auth properties for user '%s'", username)
1179-
if user_exists and iss:
1180-
query = (
1181-
f"ALTER USER {username_ident} SET "
1182-
f"""(jwt = {{"iss" = '{iss}', "username" = '{username}', """
1183-
f""""aud" = '{name}'}})"""
1184-
)
1185-
pod_name = get_crash_pod_name(cratedb, name)
1186-
scheme = get_crash_scheme(cratedb)
1187-
logger.info("... executing query: %s", query)
1188-
result = await execute_sql(
1189-
namespace=namespace,
1190-
name=name,
1191-
pod_name=pod_name,
1192-
scheme=scheme,
1193-
sql=query,
1194-
args=None,
1195-
logger=logger,
1179+
1180+
if not (user_exists and iss):
1181+
return
1182+
1183+
pod_name = get_crash_pod_name(cratedb, name)
1184+
scheme = get_crash_scheme(cratedb)
1185+
1186+
# Step 1: Reset JWT to NULL first
1187+
# This prevents RoleAlreadyExistsException when restoring snapshots
1188+
# where the user might have JWT properties with different aud/iss
1189+
logger.info("Resetting JWT auth properties for user '%s'", username)
1190+
reset_query = f"ALTER USER {username_ident} SET (jwt = NULL)"
1191+
logger.info("... executing query: %s", reset_query)
1192+
1193+
reset_result = await execute_sql(
1194+
namespace=namespace,
1195+
name=name,
1196+
pod_name=pod_name,
1197+
scheme=scheme,
1198+
sql=reset_query,
1199+
args=None,
1200+
logger=logger,
1201+
)
1202+
logger.info("... result: %s", reset_result)
1203+
1204+
if (reset_result.rowcount or 0) > 0:
1205+
logger.info("... JWT reset successful")
1206+
else:
1207+
logger.info(
1208+
"... JWT reset had no effect (might not have been set). %s", reset_result
11961209
)
1197-
logger.info("... result: %s", result)
1198-
if (result.rowcount or 0) > 0:
1199-
logger.info("... success")
1200-
else:
1201-
logger.info("... error. %s", result)
1202-
# Continue if the same JWT properties are already set
1203-
if (
1204-
not result.error_message
1205-
or "RoleAlreadyExistsException" not in result.error_message
1206-
):
1207-
raise kopf.TemporaryError(delay=config.BOOTSTRAP_RETRY_DELAY)
1210+
1211+
# Step 2: Set new JWT properties with current cluster's aud
1212+
logger.info("Setting JWT auth properties for user '%s'", username)
1213+
set_query = (
1214+
f"ALTER USER {username_ident} SET "
1215+
f"""(jwt = {{"iss" = '{iss}', "username" = '{username}', """
1216+
f""""aud" = '{name}'}})"""
1217+
)
1218+
logger.info("... executing query: %s", set_query)
1219+
1220+
result = await execute_sql(
1221+
namespace=namespace,
1222+
name=name,
1223+
pod_name=pod_name,
1224+
scheme=scheme,
1225+
sql=set_query,
1226+
args=None,
1227+
logger=logger,
1228+
)
1229+
logger.info("... result: %s", result)
1230+
1231+
if (result.rowcount or 0) > 0:
1232+
logger.info("... success")
1233+
else:
1234+
logger.info("... error. %s", result)
1235+
if (
1236+
not result.error_message
1237+
or "RoleAlreadyExistsException" not in result.error_message
1238+
):
1239+
raise kopf.TemporaryError(delay=config.BOOTSTRAP_RETRY_DELAY)
12081240

12091241

12101242
class StartClusterSubHandler(StateBasedSubHandler):

0 commit comments

Comments
 (0)