11import click
22import json
3+ import yaml
34from tabulate import tabulate
4- from sagemaker .hyperpod .cli . clients . kubernetes_client import KubernetesClient
5+ from sagemaker .hyperpod .space . hyperpod_space import HPSpace
56from sagemaker .hyperpod .cli .space_utils import generate_click_command
67from hyperpod_space_template .registry import SCHEMA_REGISTRY
8+ from hyperpod_space_template .v1_0 .model import SpaceConfig
79from sagemaker .hyperpod .common .telemetry .telemetry_logging import (
810 _hyperpod_telemetry_emitter ,
911)
1719)
1820def space_create (version , config ):
1921 """Create a space resource."""
20-
2122 try :
22- name = config .get ("name" )
23- namespace = config .get ("namespace" )
24- space_spec = config .get ("space_spec" )
25-
26- k8s_client = KubernetesClient ()
27- k8s_client .create_space (namespace , space_spec )
23+ space_config = SpaceConfig (** config )
24+ space = HPSpace (config = space_config )
25+ space .create ()
2826
29- click .echo (f"Space '{ name } ' created successfully in namespace '{ namespace } '" )
27+ click .echo (f"Space '{ space_config . name } ' created successfully in namespace '{ space_config . namespace } '" )
3028 except Exception as e :
3129 click .echo (f"Error creating space: { e } " , err = True )
3230
@@ -36,24 +34,38 @@ def space_create(version, config):
3634@click .option ("--output" , "-o" , type = click .Choice (["table" , "json" ]), default = "table" )
3735def space_list (namespace , output ):
3836 """List space resources."""
39- k8s_client = KubernetesClient ()
40-
4137 try :
42- resources = k8s_client . list_spaces ( namespace )
38+ spaces = HPSpace . list ( namespace = namespace )
4339
4440 if output == "json" :
45- click .echo (json .dumps (resources , indent = 2 ))
41+ spaces_data = []
42+ for space in spaces :
43+ space_dict = space .config .model_dump ()
44+ spaces_data .append (space_dict )
45+ click .echo (json .dumps (spaces_data , indent = 2 ))
4646 else :
47- items = resources .get ("items" , [])
48- if items :
47+ if spaces :
4948 table_data = []
50- for item in items :
49+ for space in spaces :
50+ # Extract status conditions from raw resource
51+ available = ""
52+ progressing = ""
53+ degraded = ""
54+
55+ if space .status and 'conditions' in space .status :
56+ conditions = {c ['type' ]: c ['status' ] for c in space .status ['conditions' ]}
57+ available = conditions .get ('Available' , '' )
58+ progressing = conditions .get ('Progressing' , '' )
59+ degraded = conditions .get ('Degraded' , '' )
60+
5161 table_data .append ([
52- item ["metadata" ]["name" ],
53- item ["metadata" ]["namespace" ],
54- item .get ("status" , {}).get ("phase" , "Unknown" )
62+ space .config .name ,
63+ namespace ,
64+ available ,
65+ progressing ,
66+ degraded
5567 ])
56- click .echo (tabulate (table_data , headers = ["NAME" , "NAMESPACE" , "STATUS " ]))
68+ click .echo (tabulate (table_data , headers = ["NAME" , "NAMESPACE" , "AVAILABLE" , "PROGRESSING" , "DEGRADED " ]))
5769 else :
5870 click .echo ("No spaces found" )
5971 except Exception as e :
@@ -66,17 +78,16 @@ def space_list(namespace, output):
6678@click .option ("--output" , "-o" , type = click .Choice (["yaml" , "json" ]), default = "yaml" )
6779def space_describe (name , namespace , output ):
6880 """Describe a space resource."""
69- k8s_client = KubernetesClient ()
70-
7181 try :
72- resource = k8s_client .get_space (namespace , name )
73- resource ["metadata" ].pop ('managedFields' , None )
82+ current_space = HPSpace .get (name = name , namespace = namespace )
83+
84+ # Combine config and raw resource data
85+ current_space .raw_resource .get ('metadata' , {}).pop ('managedFields' , None )
7486
7587 if output == "json" :
76- click .echo (json .dumps (resource , indent = 2 ))
88+ click .echo (json .dumps (current_space . raw_resource , indent = 2 ))
7789 else :
78- import yaml
79- click .echo (yaml .dump (resource , default_flow_style = False ))
90+ click .echo (yaml .dump (current_space .raw_resource , default_flow_style = False ))
8091 except Exception as e :
8192 click .echo (f"Error describing space '{ name } ': { e } " , err = True )
8293
@@ -86,10 +97,9 @@ def space_describe(name, namespace, output):
8697@click .option ("--namespace" , "-n" , required = False , default = "default" , help = "Kubernetes namespace" )
8798def space_delete (name , namespace ):
8899 """Delete a space resource."""
89- k8s_client = KubernetesClient ()
90-
91100 try :
92- k8s_client .delete_space (namespace , name )
101+ current_space = HPSpace .get (name = name , namespace = namespace )
102+ current_space .delete ()
93103
94104 click .echo (f"Space '{ name } ' deleted successfully" )
95105 except Exception as e :
@@ -104,39 +114,26 @@ def space_delete(name, namespace):
104114)
105115def space_update (version , config ):
106116 """Update a space resource."""
107- k8s_client = KubernetesClient ()
108-
109117 try :
110- name = config [" name" ]
111- namespace = config [ "namespace" ]
112- space_spec = config . get ( "space_spec" , {})
118+ current_space = HPSpace . get ( name = config [' name' ], namespace = config [ 'namespace' ])
119+ if not config . get ( "display_name" ):
120+ config [ "display_name" ] = current_space . config . display_name
113121
114- k8s_client .patch_space (
115- namespace = namespace ,
116- name = name ,
117- body = space_spec
118- )
122+ current_space .update (** config )
119123
120- click .echo (f"Space '{ name } ' updated successfully" )
124+ click .echo (f"Space '{ current_space . config . name } ' updated successfully" )
121125 except Exception as e :
122- click .echo (f"Error updating space ' { name } ' : { e } " , err = True )
126+ click .echo (f"Error updating space: { e } " , err = True )
123127
124128
125129@click .command ("hyp-space" )
126130@click .option ("--name" , required = True , help = "Name of the space" )
127131@click .option ("--namespace" , "-n" , required = False , default = "default" , help = "Kubernetes namespace" )
128132def space_start (name , namespace ):
129133 """Start a space resource."""
130- k8s_client = KubernetesClient ()
131-
132134 try :
133- # Patch the resource to set desired status to "Running"
134- patch_body = {"spec" : {"desiredStatus" : "Running" }}
135- k8s_client .patch_space (
136- namespace = namespace ,
137- name = name ,
138- body = patch_body
139- )
135+ current_space = HPSpace .get (name = name , namespace = namespace )
136+ current_space .start ()
140137
141138 click .echo (f"Space '{ name } ' start requested" )
142139 except Exception as e :
@@ -148,16 +145,9 @@ def space_start(name, namespace):
148145@click .option ("--namespace" , "-n" , required = False , default = "default" , help = "Kubernetes namespace" )
149146def space_stop (name , namespace ):
150147 """Stop a space resource."""
151- k8s_client = KubernetesClient ()
152-
153148 try :
154- # Patch the resource to set desired status to "Stopped"
155- patch_body = {"spec" : {"desiredStatus" : "Stopped" }}
156- k8s_client .patch_space (
157- namespace = namespace ,
158- name = name ,
159- body = patch_body
160- )
149+ current_space = HPSpace .get (name = name , namespace = namespace )
150+ current_space .stop ()
161151
162152 click .echo (f"Space '{ name } ' stop requested" )
163153 except Exception as e :
@@ -167,31 +157,13 @@ def space_stop(name, namespace):
167157@click .command ("hyp-space" )
168158@click .option ("--name" , required = True , help = "Name of the space" )
169159@click .option ("--namespace" , "-n" , required = False , default = "default" , help = "Kubernetes namespace" )
170- def space_get_logs (name , namespace ):
160+ @click .option ("--pod-name" , required = False , help = "Name of the pod to get logs from" )
161+ @click .option ("--container" , required = False , help = "Name of the container to get logs from" )
162+ def space_get_logs (name , namespace , pod_name , container ):
171163 """Get logs for a space resource."""
172- k8s_client = KubernetesClient ()
173-
174164 try :
175- # Get pods associated with the space
176- pods = k8s_client .list_pods_with_labels (
177- namespace = namespace ,
178- label_selector = f"sagemaker.aws.com/space-name={ name } "
179- )
180-
181- if not pods .items :
182- click .echo (f"No pods found for space '{ name } '" )
183- return
184-
185- # Get logs from the first pod
186- pod_name = pods .items [0 ].metadata .name
187- logs = k8s_client .get_logs_for_pod (
188- pod_name = pod_name ,
189- namespace = namespace ,
190- )
191-
165+ current_space = HPSpace .get (name = name , namespace = namespace )
166+ logs = current_space .get_logs (pod_name = pod_name , container = container )
192167 click .echo (logs )
193168 except Exception as e :
194169 click .echo (f"Error getting logs for space '{ name } ': { e } " , err = True )
195-
196-
197-
0 commit comments