diff --git a/lookup-service/service/caches/environments.py b/lookup-service/service/caches/environments.py index 95f471eb..f51be742 100644 --- a/lookup-service/service/caches/environments.py +++ b/lookup-service/service/caches/environments.py @@ -21,6 +21,7 @@ class WorkshopEnvironment: portal: "TrainingPortal" name: str + uid: str generation: int workshop: str title: str @@ -37,6 +38,7 @@ def __init__( self, portal: "TrainingPortal", name: str, + uid: str, generation: int, workshop: str, title: str, @@ -50,6 +52,7 @@ def __init__( ) -> None: self.portal = portal self.name = name + self.uid = uid self.generation = generation self.workshop = workshop self.title = title diff --git a/lookup-service/service/handlers/clusters.py b/lookup-service/service/handlers/clusters.py index e8e09d64..e2ff556c 100644 --- a/lookup-service/service/handlers/clusters.py +++ b/lookup-service/service/handlers/clusters.py @@ -205,31 +205,42 @@ async def trainingportals_event(event: kopf.RawEvent, **_): status = xgetattr(body, "status", {}) portal_name = xgetattr(metadata, "name") + portal_uid = xgetattr(metadata, "uid") - if xgetattr(event, "type") == "DELETED": - logger.info( - "Discard training portal %s of cluster %s", - portal_name, - self.cluster_name, - ) + with synchronized(self.cluster_config): + if xgetattr(event, "type") == "DELETED": + logger.info( + "Discard training portal %s with uid %s of cluster %s", + portal_name, + portal_uid, + self.cluster_name, + ) - self.cluster_config.remove_portal(portal_name) + portal_state = self.cluster_config.get_portal(portal_name) - else: - credentials = PortalCredentials( - client_id=xgetattr(status, "educates.clients.robot.id"), - client_secret=xgetattr(status, "educates.clients.robot.secret"), - username=xgetattr(status, "educates.credentials.robot.username"), - password=xgetattr(status, "educates.credentials.robot.password"), - ) + if portal_state: + self.cluster_config.remove_portal(portal_name) + + # Mark as stopped in case any workshop environments + # which reference it still haven't been cleaned up. + + portal_state.phase = "Stopped" + + else: + credentials = PortalCredentials( + client_id=xgetattr(status, "educates.clients.robot.id"), + client_secret=xgetattr(status, "educates.clients.robot.secret"), + username=xgetattr(status, "educates.credentials.robot.username"), + password=xgetattr(status, "educates.credentials.robot.password"), + ) - with synchronized(self.cluster_config): portal_state = self.cluster_config.get_portal(portal_name) if not portal_state: logger.info( - "Registering training portal %s of cluster %s", + "Registering training portal %s with uid %s of cluster %s", portal_name, + portal_uid, self.cluster_name, ) @@ -237,7 +248,7 @@ async def trainingportals_event(event: kopf.RawEvent, **_): TrainingPortal( cluster=self.cluster_config, name=portal_name, - uid=xgetattr(metadata, "uid"), + uid=portal_uid, generation=xgetattr(metadata, "generation"), labels=xgetattr(spec, "portal.labels", {}), url=xgetattr(status, "educates.url"), @@ -252,11 +263,13 @@ async def trainingportals_event(event: kopf.RawEvent, **_): else: logger.info( - "Updating training portal %s of cluster %s", + "Updating training portal %s with uid %s of cluster %s", portal_name, + portal_uid, self.cluster_name, ) + portal_state.uid = portal_uid portal_state.generation = xgetattr(metadata, "generation") portal_state.labels = xgetattr(spec, "portal.labels", {}) portal_state.url = xgetattr(status, "educates.url") @@ -266,8 +279,7 @@ async def trainingportals_event(event: kopf.RawEvent, **_): spec, "portal.sessions.maximum", 0 ) - with synchronized(portal_state): - portal_state.recalculate_capacity() + portal_state.recalculate_capacity() @kopf.on.event( "workshopenvironments.training.educates.dev", @@ -285,17 +297,23 @@ async def workshopenvironments_event(event: kopf.RawEvent, **_): portal_name = xgetattr(metadata, "labels", {}).get( "training.educates.dev/portal.name" ) + portal_uid = xgetattr(metadata, "labels", {}).get( + "training.educates.dev/portal.uid" + ) + environment_name = xgetattr(metadata, "name") + environment_uid = xgetattr(metadata, "uid") + workshop_name = xgetattr(spec, "workshop.name") workshop_generation = xgetattr(status, "educates.workshop.generation", 0) workshop_spec = xgetattr(status, "educates.workshop.spec", {}) - portal = self.cluster_config.get_portal(portal_name) + with synchronized(self.cluster_config): + portal = self.cluster_config.get_portal(portal_name) - if xgetattr(event, "type") == "DELETED": - if portal: - with synchronized(portal): + if xgetattr(event, "type") == "DELETED": + if portal: logger.info( "Discard workshop environment %s for workshop %s from portal %s of cluster %s", # pylint: disable=line-too-long environment_name, @@ -307,34 +325,54 @@ async def workshopenvironments_event(event: kopf.RawEvent, **_): portal.remove_environment(environment_name) portal.recalculate_capacity() - else: - logger.info( - "Discard workshop environment %s for workshop %s from portal %s of cluster %s as portal not found", # pylint: disable=line-too-long - environment_name, - workshop_name, - portal_name, - self.cluster_name, - ) + if portal.phase == "Unknown" and not portal.get_environments(): + logger.info( + "Discard unknown training portal %s with uid %s of cluster %s", + portal_name, + portal_uid, + self.cluster_name, + ) - else: - while not portal: - logger.warning( - "Portal %s not found for workshop environment %s of cluster %s, sleeping...", # pylint: disable=line-too-long - portal_name, - environment_name, - self.cluster_name, - ) + self.cluster_config.remove_portal(portal_name) - # TODO How should we fail this if the portal is not found - # after a certain number of retries? Will continually - # retrying hold up ability to handle other events for the - # same resource type? + else: + logger.info( + "Discard workshop environment %s for workshop %s from portal %s of cluster %s as portal not found", # pylint: disable=line-too-long + environment_name, + workshop_name, + portal_name, + self.cluster_name, + ) + + else: + if not portal: + logger.info( + "Registering unknown training portal %s with uid %s of cluster %s", + portal_name, + portal_uid, + self.cluster_name, + ) - await asyncio.sleep(2.0) + portal = TrainingPortal( + cluster=self.cluster_config, + name=portal_name, + uid=portal_uid, + generation=0, + labels={}, + url="", + phase="Unknown", + credentials=PortalCredentials( + client_id="", + client_secret="", + username="", + password="", + ), + capacity=0, + allocated=0, + ) - portal = self.cluster_config.get_portal(portal_name) + self.cluster_config.add_portal(portal) - with synchronized(portal): environment_state = portal.get_environment(environment_name) if not environment_state: @@ -350,6 +388,7 @@ async def workshopenvironments_event(event: kopf.RawEvent, **_): WorkshopEnvironment( portal=portal, name=environment_name, + uid=environment_uid, generation=workshop_generation, workshop=workshop_name, title=xgetattr(workshop_spec, "title"), @@ -408,19 +447,27 @@ async def workshopsessions_event(event: kopf.RawEvent, **_): portal_name = xgetattr(metadata, "labels", {}).get( "training.educates.dev/portal.name" ) + portal_uid = xgetattr(metadata, "labels", {}).get( + "training.educates.dev/portal.uid" + ) + environment_name = xgetattr(metadata, "labels", {}).get( "training.educates.dev/environment.name" ) + environment_uid = xgetattr(metadata, "labels", {}).get( + "training.educates.dev/environment.uid" + ) + session_name = xgetattr(metadata, "name") - portal = self.cluster_config.get_portal(portal_name) + with synchronized(self.cluster_config): + portal = self.cluster_config.get_portal(portal_name) - if xgetattr(event, "type") == "DELETED": - if portal: - environment = portal.get_environment(environment_name) + if xgetattr(event, "type") == "DELETED": + if portal: + environment = portal.get_environment(environment_name) - if environment: - with synchronized(portal): + if environment: logger.info( "Discard workshop session %s for environment %s from portal %s of cluster %s", # pylint: disable=line-too-long session_name, @@ -432,9 +479,38 @@ async def workshopsessions_event(event: kopf.RawEvent, **_): environment.remove_session(session_name) portal.recalculate_capacity() + if environment.phase == "Unknown" and not environment.get_sessions(): + logger.info( + "Discard unknown workshop environment %s from portal %s of cluster %s", # pylint: disable=line-too-long + environment_name, + portal_name, + self.cluster_name, + ) + + portal.remove_environment(environment_name) + + if portal.phase == "Unknown" and not portal.get_environments(): + logger.info( + "Discard unknown training portal %s with uid %s of cluster %s", + portal_name, + portal_uid, + self.cluster_name, + ) + + self.cluster_config.remove_portal(portal_name) + + else: + logger.info( + "Discard workshop session %s for environment %s from portal %s of cluster %s as environment not found", # pylint: disable=line-too-long + session_name, + environment_name, + portal_name, + self.cluster_name, + ) + else: logger.info( - "Discard workshop session %s for environment %s from portal %s of cluster %s as environment not found", # pylint: disable=line-too-long + "Discard workshop session %s for environment %s from portal %s of cluster %s as portal not found", # pylint: disable=line-too-long session_name, environment_name, portal_name, @@ -442,54 +518,62 @@ async def workshopsessions_event(event: kopf.RawEvent, **_): ) else: - logger.info( - "Discard workshop session %s for environment %s from portal %s of cluster %s as portal not found", # pylint: disable=line-too-long - session_name, - environment_name, - portal_name, - self.cluster_name, - ) - - else: - portal = self.cluster_config.get_portal(portal_name) - - while not portal: - logger.warning( - "Portal %s not found for workshop session %s of cluster %s, sleeping...", - portal_name, - session_name, - self.cluster_name, - ) - - # TODO How should we fail this if the portal is not found - # after a certain number of retries? Will continually - # retrying hold up ability to handle other events for the - # same resource type? - - await asyncio.sleep(2.0) + if not portal: + logger.info( + "Registering unknown training portal %s with uid %s of cluster %s", + portal_name, + portal_uid, + self.cluster_name, + ) - portal = self.cluster_config.get_portal(portal_name) + portal = TrainingPortal( + cluster=self.cluster_config, + name=portal_name, + uid=portal_uid, + generation=0, + labels={}, + url="", + phase="Unknown", + credentials=PortalCredentials( + client_id="", + client_secret="", + username="", + password="", + ), + capacity=0, + allocated=0, + ) - environment = portal.get_environment(environment_name) + self.cluster_config.add_portal(portal) - while not environment: - logger.warning( - "Environment %s not found for workshop session %s of cluster %s, sleeping...", # pylint: disable=line-too-long - environment_name, - session_name, - self.cluster_name, - ) + environment = portal.get_environment(environment_name) - # TODO How should we fail this if the portal is not found - # after a certain number of retries? Will continually - # retrying hold up ability to handle other events for the - # same resource type? + if not environment: + logger.info( + "Registering unknown workshop environment %s from portal %s of cluster %s", + environment_name, + portal_name, + self.cluster_name, + ) - await asyncio.sleep(2.0) + environment = WorkshopEnvironment( + portal=portal, + name=environment_name, + uid=environment_uid, + generation=0, + workshop="", + title="", + description="", + labels={}, + capacity=0, + reserved=0, + allocated=0, + available=0, + phase="Unknown", + ) - environment = portal.get_environment(environment_name) + portal.add_environment(environment) - with synchronized(portal): session_state = environment.get_session(session_name) if not session_state: diff --git a/lookup-service/service/routes/clusters.py b/lookup-service/service/routes/clusters.py index 08ff7746..d61ff934 100644 --- a/lookup-service/service/routes/clusters.py +++ b/lookup-service/service/routes/clusters.py @@ -102,6 +102,42 @@ async def api_get_v1_clusters_portals(request: web.Request) -> web.Response: return web.json_response(data) +@login_required +@roles_accepted("admin") +async def api_get_v1_clusters_portals_details(request: web.Request) -> web.Response: + """Returns details for the specified portal running on a cluster.""" + + cluster_name = request.match_info["cluster"] + portal_name = request.match_info["portal"] + + service_state = request.app["service_state"] + cluster_database = service_state.cluster_database + + cluster = cluster_database.get_cluster(cluster_name) + + if not cluster: + return web.Response(text="Cluster not available", status=403) + + portal = cluster.get_portal(portal_name) + + if not portal: + return web.Response(text="Portal not available", status=403) + + details = { + "name": portal.name, + "uid": portal.uid, + "generation": portal.generation, + "labels": portal.labels, + "cluster": portal.cluster.name, + "url": portal.url, + "capacity": portal.capacity, + "allocated": portal.allocated, + "phase": portal.phase, + } + + return web.json_response(details) + + @login_required @roles_accepted("admin") async def api_get_v1_clusters_portals_environments( @@ -131,6 +167,7 @@ async def api_get_v1_clusters_portals_environments( "environments": [ { "name": environment.name, + "uid": environment.uid, "generation": environment.generation, "workshop": environment.workshop, "title": environment.title, @@ -182,6 +219,7 @@ async def api_get_v1_clusters_portals_environments_details( details = { "name": environment.name, + "uid": environment.uid, "generation": environment.generation, "workshop": environment.workshop, "title": environment.title, @@ -350,6 +388,10 @@ async def api_get_v1_clusters_portals_environments_users_sessions( web.get("/api/v1/clusters/{cluster}", api_get_v1_clusters_details), web.get("/api/v1/clusters/{cluster}/kubeconfig", api_get_v1_clusters_kubeconfig), web.get("/api/v1/clusters/{cluster}/portals", api_get_v1_clusters_portals), + web.get( + "/api/v1/clusters/{cluster}/portals/{portal}", + api_get_v1_clusters_portals_details, + ), web.get( "/api/v1/clusters/{cluster}/portals/{portal}/environments", api_get_v1_clusters_portals_environments, diff --git a/session-manager/handlers/trainingportal.py b/session-manager/handlers/trainingportal.py index bbd2d6be..3186ec2b 100644 --- a/session-manager/handlers/trainingportal.py +++ b/session-manager/handlers/trainingportal.py @@ -86,6 +86,8 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, # Calculate name for the portal namespace. portal_name = name + portal_uid = uid + portal_namespace = f"{portal_name}-ui" # Calculate access details for the portal. The hostname used to access the @@ -388,6 +390,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/policy.engine": CLUSTER_SECURITY_POLICY_ENGINE, f"training.{OPERATOR_API_GROUP}/policy.name": "baseline", }, @@ -444,6 +447,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, }, }, "roleRef": { @@ -472,6 +476,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, }, }, "roleRef": { @@ -530,6 +535,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, }, }, } @@ -544,6 +550,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, }, }, "type": "kubernetes.io/service-account-token", @@ -557,6 +564,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, }, }, "roleRef": { @@ -584,6 +592,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, }, }, "spec": { @@ -604,6 +613,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, }, }, "data": { @@ -620,6 +630,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/portal.services.dashboard": "true", }, }, @@ -633,6 +644,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "deployment": "training-portal", f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/portal.services.dashboard": "true", }, }, @@ -850,6 +862,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, }, }, "spec": { @@ -868,6 +881,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, }, "annotations": {}, }, @@ -936,6 +950,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, }, }, "spec": { @@ -969,6 +984,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, }, }, "spec": { @@ -997,6 +1013,7 @@ def training_portal_create(name, uid, body, spec, status, patch, runtime, retry, "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, }, }, "spec": { diff --git a/session-manager/handlers/workshopallocation.py b/session-manager/handlers/workshopallocation.py index bac8ee3f..de4d8439 100644 --- a/session-manager/handlers/workshopallocation.py +++ b/session-manager/handlers/workshopallocation.py @@ -147,8 +147,16 @@ def workshop_allocation_create( portal_name = meta.get("labels", {}).get( f"training.{OPERATOR_API_GROUP}/portal.name", "" ) + portal_uid = meta.get("labels", {}).get( + f"training.{OPERATOR_API_GROUP}/portal.uid", "" + ) environment_name = spec["environment"]["name"] + + environment_uid = meta.get("labels", {}).get( + f"training.{OPERATOR_API_GROUP}/environment.uid", "" + ) + workshop_namespace = environment_name session_name = spec["session"]["name"] @@ -448,7 +456,9 @@ def workshop_allocation_create( f"training.{OPERATOR_API_GROUP}/component.group": "objects", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, f"training.{OPERATOR_API_GROUP}/session.objects": "true", } diff --git a/session-manager/handlers/workshopenvironment.py b/session-manager/handlers/workshopenvironment.py index 110b07e7..133448c0 100644 --- a/session-manager/handlers/workshopenvironment.py +++ b/session-manager/handlers/workshopenvironment.py @@ -123,6 +123,8 @@ def workshop_environment_create( # created. environment_name = name + environment_uid = uid + workshop_namespace = environment_name # Can optionally be passed name of the training portal via a label when the @@ -131,6 +133,9 @@ def workshop_environment_create( portal_name = meta.get("labels", {}).get( f"training.{OPERATOR_API_GROUP}/portal.name", "" ) + portal_uid = meta.get("labels", {}).get( + f"training.{OPERATOR_API_GROUP}/portal.uid", "" + ) # The name of the workshop to be deployed can differ and is taken from the # specification of the workshop environment. Lookup the workshop resource @@ -464,7 +469,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/policy.engine": CLUSTER_SECURITY_POLICY_ENGINE, f"training.{OPERATOR_API_GROUP}/policy.name": "privileged", }, @@ -526,7 +533,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "roleRef": { @@ -558,7 +567,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "roleRef": { @@ -622,7 +633,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -696,7 +709,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "data": { @@ -849,7 +864,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "rules": [ @@ -877,7 +894,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -928,7 +947,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -973,7 +994,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -1020,7 +1043,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -1096,7 +1121,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, } @@ -1131,7 +1158,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -1158,7 +1187,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/environment.services.mirror": "true", }, }, @@ -1175,7 +1206,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/environment.services.mirror": "true", }, }, @@ -1285,7 +1318,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -1339,7 +1374,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/environment.services.images": "true", }, }, @@ -1354,7 +1391,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/environment.services.images": "true", }, }, @@ -1416,7 +1455,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -1488,7 +1529,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -1531,7 +1574,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "data": {"config.yaml": yaml.dump(artifacts_config, Dumper=yaml.Dumper)}, @@ -1559,7 +1604,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -1639,7 +1686,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/environment.services.assets": "true", }, }, @@ -1654,7 +1703,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/environment.services.assets": "true", }, }, @@ -1737,7 +1788,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -1809,7 +1862,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -1829,7 +1884,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "data": {}, @@ -1888,7 +1945,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -1965,7 +2024,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, } @@ -1979,7 +2040,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "roleRef": { @@ -2006,7 +2069,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -2020,7 +2085,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -2070,7 +2137,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, }, }, "spec": { @@ -2151,7 +2220,9 @@ def workshop_environment_create( f"training.{OPERATOR_API_GROUP}/component": "environment", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/environment.objects": "true", } ) diff --git a/session-manager/handlers/workshoprequest.py b/session-manager/handlers/workshoprequest.py index 1515b8de..1ffce18e 100644 --- a/session-manager/handlers/workshoprequest.py +++ b/session-manager/handlers/workshoprequest.py @@ -32,7 +32,12 @@ def workshop_request_create(name, uid, namespace, spec, patch, logger, **_): # resource anyway. First lookup up the desired workshop environment # and determine if it exists and is valid. - portal_name = spec.get("portal", {}).get("name", "") + # NOTE: Details of the portal are not actually available so this will + # result in empty strings. As WorkshopRequest isn't being used anymore + # no big deal. + + # portal_name = spec.get("portal", {}).get("name", "") + # portal_uid = spec.get("portal", {}).get("uid", "") environment_name = spec["environment"]["name"] @@ -120,8 +125,9 @@ def _generate_random_session_id(n=5): "metadata": { "name": session_name, "labels": { - f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, - f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + # f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + # f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, + # f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, }, }, "spec": { diff --git a/session-manager/handlers/workshopsession.py b/session-manager/handlers/workshopsession.py index 4ef346cb..843c2437 100644 --- a/session-manager/handlers/workshopsession.py +++ b/session-manager/handlers/workshopsession.py @@ -98,7 +98,9 @@ def _setup_session_namespace( primary_namespace_body, workshop_name, portal_name, + portal_uid, environment_name, + environment_uid, session_name, workshop_namespace, session_namespace, @@ -202,7 +204,9 @@ def _setup_session_namespace( f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -277,7 +281,9 @@ def _setup_session_namespace( f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -311,7 +317,9 @@ def _setup_session_namespace( f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -342,7 +350,9 @@ def _setup_session_namespace( f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -386,7 +396,9 @@ def _setup_session_namespace( f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -407,7 +419,9 @@ def _setup_session_namespace( f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, } ) @@ -427,7 +441,9 @@ def _setup_session_namespace( f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, } ) @@ -443,7 +459,9 @@ def _setup_session_namespace( f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, } ) @@ -459,7 +477,9 @@ def _setup_session_namespace( f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, } ) @@ -548,6 +568,8 @@ def workshop_session_create(name, body, meta, uid, spec, status, patch, retry, * session_id = spec["session"]["id"] session_namespace = f"{workshop_namespace}-{session_id}" + environment_uid = environment_instance.obj["metadata"]["uid"] + # Can optionally be passed name of the training portal via a label # when the workshop environment is created as a child to a training # portal. @@ -555,6 +577,9 @@ def workshop_session_create(name, body, meta, uid, spec, status, patch, retry, * portal_name = meta.get("labels", {}).get( f"training.{OPERATOR_API_GROUP}/portal.name", "" ) + portal_uid = meta.get("labels", {}).get( + f"training.{OPERATOR_API_GROUP}/portal.uid", "" + ) # We pull details of the workshop to be deployed from the status of the # environment custom resource. This is a copy of the specification from the @@ -722,7 +747,9 @@ def resolve_security_policy(name): f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, f"training.{OPERATOR_API_GROUP}/policy.engine": CLUSTER_SECURITY_POLICY_ENGINE, f"training.{OPERATOR_API_GROUP}/policy.name": namespace_security_policy, @@ -814,7 +841,9 @@ def resolve_security_policy(name): f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -849,6 +878,7 @@ def resolve_security_policy(name): "labels": { f"training.{OPERATOR_API_GROUP}/component": "portal", f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, }, }, "type": "kubernetes.io/service-account-token", @@ -885,7 +915,9 @@ def resolve_security_policy(name): f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -930,7 +962,9 @@ def resolve_security_policy(name): namespace_instance.obj, workshop_name, portal_name, + portal_uid, environment_name, + environment_uid, session_name, workshop_namespace, session_namespace, @@ -1074,7 +1108,9 @@ def resolve_security_policy(name): f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -1113,7 +1149,9 @@ def resolve_security_policy(name): f"training.{OPERATOR_API_GROUP}/component.group": "variables", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -1170,7 +1208,9 @@ def resolve_security_policy(name): f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, f"training.{OPERATOR_API_GROUP}/policy.engine": CLUSTER_SECURITY_POLICY_ENGINE, f"training.{OPERATOR_API_GROUP}/policy.name": target_security_policy, @@ -1203,7 +1243,9 @@ def resolve_security_policy(name): namespace_instance.obj, workshop_name, portal_name, + portal_uid, environment_name, + environment_uid, session_name, workshop_namespace, session_namespace, @@ -1253,7 +1295,9 @@ def resolve_security_policy(name): f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, f"training.{OPERATOR_API_GROUP}/session.objects": "true", } @@ -1389,7 +1433,9 @@ def resolve_security_policy(name): namespace_instance.obj, workshop_name, portal_name, + portal_uid, environment_name, + environment_uid, session_name, workshop_namespace, session_namespace, @@ -1534,7 +1580,9 @@ def resolve_security_policy(name): f"training.{OPERATOR_API_GROUP}/application": "workshop", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, f"training.{OPERATOR_API_GROUP}/session.services.workshop": "true", }, @@ -1551,7 +1599,9 @@ def resolve_security_policy(name): f"training.{OPERATOR_API_GROUP}/application": "workshop", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, f"training.{OPERATOR_API_GROUP}/session.services.workshop": "true", }, @@ -2012,7 +2062,9 @@ def vendir_secrets_required(contents): f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -2150,7 +2202,9 @@ def _apply_environment_patch(patch): f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -2298,7 +2352,9 @@ def _apply_environment_patch(patch): f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -2359,7 +2415,9 @@ def _apply_environment_patch(patch): f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -2535,7 +2593,9 @@ def _apply_environment_patch(patch): f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -2562,7 +2622,9 @@ def _apply_environment_patch(patch): f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -2586,7 +2648,9 @@ def _apply_environment_patch(patch): f"training.{OPERATOR_API_GROUP}/application": "registry", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, f"training.{OPERATOR_API_GROUP}/session.services.registry": "true", }, @@ -2605,7 +2669,9 @@ def _apply_environment_patch(patch): f"training.{OPERATOR_API_GROUP}/application": "registry", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, f"training.{OPERATOR_API_GROUP}/session.services.registry": "true", }, @@ -2726,7 +2792,9 @@ def _apply_environment_patch(patch): f"training.{OPERATOR_API_GROUP}/application": "registry", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -2749,7 +2817,9 @@ def _apply_environment_patch(patch): f"training.{OPERATOR_API_GROUP}/application": "registry", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -2830,7 +2900,9 @@ def _apply_environment_patch(patch): f"training.{OPERATOR_API_GROUP}/component": "session", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -2893,7 +2965,9 @@ def _apply_environment_patch(patch): f"training.{OPERATOR_API_GROUP}/application": "workshop", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, @@ -3035,7 +3109,9 @@ def _apply_environment_patch(patch): f"training.{OPERATOR_API_GROUP}/application": "workshop", f"training.{OPERATOR_API_GROUP}/workshop.name": workshop_name, f"training.{OPERATOR_API_GROUP}/portal.name": portal_name, + f"training.{OPERATOR_API_GROUP}/portal.uid": portal_uid, f"training.{OPERATOR_API_GROUP}/environment.name": environment_name, + f"training.{OPERATOR_API_GROUP}/environment.uid": environment_uid, f"training.{OPERATOR_API_GROUP}/session.name": session_name, }, }, diff --git a/training-portal/src/project/apps/workshops/manager/environments.py b/training-portal/src/project/apps/workshops/manager/environments.py index 42a22eac..787238c2 100644 --- a/training-portal/src/project/apps/workshops/manager/environments.py +++ b/training-portal/src/project/apps/workshops/manager/environments.py @@ -500,6 +500,7 @@ def process_workshop_environment(portal, workshop, position): "name": environment.name, "labels": { f"training.{settings.OPERATOR_API_GROUP}/portal.name": portal.name, + f"training.{settings.OPERATOR_API_GROUP}/portal.uid": portal.uid, }, "ownerReferences": [ { diff --git a/training-portal/src/project/apps/workshops/manager/sessions.py b/training-portal/src/project/apps/workshops/manager/sessions.py index 6c11532d..a1864c65 100644 --- a/training-portal/src/project/apps/workshops/manager/sessions.py +++ b/training-portal/src/project/apps/workshops/manager/sessions.py @@ -72,6 +72,7 @@ def create_request_resources(session): f"training.{settings.OPERATOR_API_GROUP}/component.group": "variables", f"training.{settings.OPERATOR_API_GROUP}/workshop.name": session.environment.workshop.name, f"training.{settings.OPERATOR_API_GROUP}/portal.name": settings.PORTAL_NAME, + f"training.{settings.OPERATOR_API_GROUP}/portal.uid": settings.PORTAL_UID, f"training.{settings.OPERATOR_API_GROUP}/environment.name": session.environment.name, f"training.{settings.OPERATOR_API_GROUP}/session.name": session.name, }, @@ -109,7 +110,9 @@ def create_request_resources(session): f"training.{settings.OPERATOR_API_GROUP}/component": "request", f"training.{settings.OPERATOR_API_GROUP}/workshop.name": session.environment.workshop.name, f"training.{settings.OPERATOR_API_GROUP}/portal.name": settings.PORTAL_NAME, + f"training.{settings.OPERATOR_API_GROUP}/portal.uid": settings.PORTAL_UID, f"training.{settings.OPERATOR_API_GROUP}/environment.name": session.environment.name, + f"training.{settings.OPERATOR_API_GROUP}/environment.uid": session.environment.uid, f"training.{settings.OPERATOR_API_GROUP}/session.name": session.name, }, "ownerReferences": [ @@ -233,7 +236,9 @@ def create_workshop_session(session, secret): "name": session.name, "labels": { f"training.{settings.OPERATOR_API_GROUP}/portal.name": settings.PORTAL_NAME, + f"training.{settings.OPERATOR_API_GROUP}/portal.uid": settings.PORTAL_UID, f"training.{settings.OPERATOR_API_GROUP}/environment.name": session.environment.name, + f"training.{settings.OPERATOR_API_GROUP}/environment.uid": session.environment.uid, }, "ownerReferences": [ {