77
88import httpx
99
10- import yaml
11-
1210from easykube import (
1311 Configuration ,
1412 ApiError ,
@@ -65,9 +63,14 @@ class Provider(base.Provider):
6563 """
6664 Base class for Cluster API providers.
6765 """
68- def __init__ (self ):
66+ def __init__ (
67+ self ,
68+ # The label to use to find the default kubeconfig secret
69+ default_kubeconfig_secret_label : str = "apps.azimuth-cloud.io/default-kubeconfig"
70+ ):
6971 # Get the easykube configuration from the environment
7072 self ._ekconfig = Configuration .from_environment ()
73+ self ._default_kubeconfig_secret_label = default_kubeconfig_secret_label
7174
7275 def session (self , cloud_session : cloud_base .ScopedSession ) -> 'Session' :
7376 """
@@ -78,16 +81,22 @@ def session(self, cloud_session: cloud_base.ScopedSession) -> 'Session':
7881 namespace = get_namespace (client , cloud_session .tenancy ())
7982 # Set the target namespace as the default namespace for the client
8083 client .default_namespace = namespace
81- return Session (client , cloud_session )
84+ return Session (client , cloud_session , self . _default_kubeconfig_secret_label )
8285
8386
8487class Session (base .Session ):
8588 """
8689 Base class for a scoped session.
8790 """
88- def __init__ (self , client : SyncClient , cloud_session : cloud_base .ScopedSession ):
91+ def __init__ (
92+ self ,
93+ client : SyncClient ,
94+ cloud_session : cloud_base .ScopedSession ,
95+ default_kubeconfig_secret_label : str
96+ ):
8997 self ._client = client
9098 self ._cloud_session = cloud_session
99+ self ._default_kubeconfig_secret_label = default_kubeconfig_secret_label
91100
92101 def _log (self , message , * args , level = logging .INFO , ** kwargs ):
93102 logger .log (
@@ -234,6 +243,23 @@ def find_app(self, id: str) -> dto.App:
234243 app = self ._client .api (APPS_API_VERSION ).resource ("apps" ).fetch (id )
235244 return self ._from_api_app (app )
236245
246+ def _find_default_kubeconfig_secret (self ) -> t .Optional [t .Dict [str , t .Any ]]:
247+ """
248+ Attempts to locate a default kubeconfig secret in the namespace.
249+ """
250+ # Find the first secret with the expected label
251+ secret = self ._client .api ("v1" ).resource ("secrets" ).first (
252+ labels = { self ._default_kubeconfig_secret_label : PRESENT }
253+ )
254+ if secret :
255+ # Use the first key in the secret (we expect it to be the only key)
256+ try :
257+ return secret .metadata .name , next (iter (secret .get ("data" , {}).keys ()))
258+ except StopIteration :
259+ # Fall through to the exception
260+ pass
261+ raise errors .BadInputError ("Unable to determine Kubernetes cluster for app." )
262+
237263 @convert_exceptions
238264 def create_app (
239265 self ,
@@ -247,12 +273,15 @@ def create_app(
247273 """
248274 Create a new app in the tenancy.
249275 """
250- # For now, we require a Kubernetes cluster
251- if not kubernetes_cluster :
252- raise errors .BadInputError ("No Kubernetes cluster specified." )
253276 # This driver requires the Zenith identity realm to be specified
254277 if not zenith_identity_realm_name :
255278 raise errors .BadInputError ("No Zenith identity realm specified." )
279+ # Decide which kubeconfig to use
280+ if kubernetes_cluster :
281+ kubeconfig_secret_name = f"{ kubernetes_cluster .id } -kubeconfig"
282+ kubeconfig_secret_key = "value"
283+ else :
284+ kubeconfig_secret_name , kubeconfig_secret_key = self ._find_default_kubeconfig_secret ()
256285 # NOTE(mkjpryor)
257286 # We know that the target namespace exists because it has a cluster in
258287 return self ._from_api_app (
@@ -266,9 +295,11 @@ def create_app(
266295 "app.kubernetes.io/managed-by" : "azimuth" ,
267296 },
268297 # If the app belongs to a cluster, store that in an annotation
269- "annotations" : {
270- "azimuth.stackhpc.com/cluster" : kubernetes_cluster .id ,
271- },
298+ "annotations" : (
299+ { "azimuth.stackhpc.com/cluster" : kubernetes_cluster .id }
300+ if kubernetes_cluster
301+ else {}
302+ ),
272303 },
273304 "spec" : {
274305 "template" : {
@@ -277,9 +308,8 @@ def create_app(
277308 "version" : template .versions [0 ].name ,
278309 },
279310 "kubeconfigSecret" : {
280- # Use the kubeconfig for the cluster
281- "name" : f"{ kubernetes_cluster .id } -kubeconfig" ,
282- "key" : "value" ,
311+ "name" : kubeconfig_secret_name ,
312+ "key" : kubeconfig_secret_key ,
283313 },
284314 "zenithIdentityRealmName" : zenith_identity_realm_name ,
285315 "values" : values ,
0 commit comments