diff --git a/lookup-service/service/routes/workshops.py b/lookup-service/service/routes/workshops.py index 4f47dddf..a4812592 100644 --- a/lookup-service/service/routes/workshops.py +++ b/lookup-service/service/routes/workshops.py @@ -86,6 +86,8 @@ async def api_post_v1_workshops(request: web.Request) -> web.Response: data = await request.json() + service_state = request.app["service_state"] + client = request["remote_client"] tenant_name = data.get("tenantName") @@ -121,8 +123,6 @@ async def api_post_v1_workshops(request: web.Request) -> web.Response: # Check that client is allowed access to this tenant. - client = request["remote_client"] - if not client.allowed_access_to_tenant(tenant_name): logger.warning( "Client %r not allowed access to tenant %r", client.name, tenant_name @@ -130,9 +130,32 @@ async def api_post_v1_workshops(request: web.Request) -> web.Response: return web.Response(text="Client not allowed access to tenant", status=403) - # Find the portals accessible to the tenant which hosts the workshop. + # If a user ID is supplied, check all of the portals to see if this user + # already has a workshop session for this workshop. This is done before + # checking whether a portal is accessible to the tenant so depends on the + # user ID being unique across all tenants. We do it before checking access + # to the tenant so that we can return a session if the user already has one + # even if the tenant no longer has access because of label changes. + + cluster_database = service_state.cluster_database + + if user_id: + for cluster in cluster_database.get_clusters(): + for portal in cluster.get_portals(): + session = portal.find_existing_workshop_session_for_user( + user_id, workshop_name + ) + + if session: + data = await session.reacquire_workshop_session(index_url) + + if data: + data["tenantName"] = tenant_name + return web.json_response(data) + + # Get the list of portals hosting the workshop and calculate the subset that + # are accessible to the tenant. - service_state = request.app["service_state"] tenant_database = service_state.tenant_database tenant = tenant_database.get_tenant(tenant_name) @@ -142,9 +165,6 @@ async def api_post_v1_workshops(request: web.Request) -> web.Response: return web.Response(text="Tenant not available", status=503) - # Get the list of portals hosting the workshop and calculate the subset - # that are accessible to the tenant. - accessible_portals = tenant.portals_which_are_accessible() selected_portals = [] @@ -166,22 +186,6 @@ async def api_post_v1_workshops(request: web.Request) -> web.Response: return web.Response(text="Workshop not available", status=503) - # If a user ID is supplied, check each of the portals to see if this user - # already has a workshop session for this workshop. - - if user_id: - for portal in selected_portals: - session = portal.find_existing_workshop_session_for_user( - user_id, workshop_name - ) - - if session: - data = await session.reacquire_workshop_session(index_url) - - if data: - data["tenantName"] = tenant_name - return web.json_response(data) - # Find the set of workshop environments for the specified workshop that are # in a running state. If there are no such environments, then the workshop # is not available. diff --git a/project-docs/release-notes/version-3.0.1.md b/project-docs/release-notes/version-3.0.1.md index 977bf340..d5993e89 100644 --- a/project-docs/release-notes/version-3.0.1.md +++ b/project-docs/release-notes/version-3.0.1.md @@ -8,6 +8,25 @@ For details on significant changes in future versions, including feature deprecations and removals which may necessitate updates to existing workshops, see [Upcoming changes](upcoming-changes). +Features Changed +---------------- + +* When requesting a workshop session using the lookup service, a search for an + existing session for that workshop and user is now made against all training + portals across all clusters. This is done before filtering out what training + portals are accessible to a tenant. This is done so an existing workshop + session is found even if labels for clusters or portals had been changed such + that the training portal is no longer mapped to the tenant. Such changes to + labels may have been made to prevent creation of new workshop sessions against + a cluster or training portal when rolling over to a new cluster and waiting + for existing workshop sessions on the old cluster to expire. Note that this + relies on client side user IDs to be unique across all tenants hosted by the + clusters the lookup service monitors. If a single lookup service is being used + by multiple distinct custom front end web portals and it is possible the same + user ID could be used by more than one front end, it is recommended that the + front end incorporate the tenant name as part of the client side user ID + passed to the lookup service. + Bugs Fixed ----------