@@ -1143,22 +1143,114 @@ def start(self):
11431143 raise Exception ('Cluster operation failed : %s' % (json .dumps (resp .get ('messages' , {}).get ('messages' , {}))))
11441144 return resp
11451145
1146- def stop (self , terminate = True ):
1146+ def stop (self , terminate = True , force_stop = False ):
11471147 """
11481148 Stops or detaches the cluster
11491149
11501150 This operation is only valid for a managed cluster.
1151- :param boolean terminate: whether to delete the cluster after stopping it
1151+
1152+ :param terminate: whether to delete the cluster after stopping it
1153+ :type terminate: bool
1154+ :param force_stop: whether to try to force stop the cluster,
1155+ useful if DSS expects the cluster to already be stopped
1156+ :type force_stop: bool
11521157 """
11531158 resp = self .client ._perform_json (
11541159 "POST" , "/admin/clusters/%s/actions/stop" % (self .cluster_id ),
1155- params = {'terminate' :terminate })
1160+ params = {'terminate' : terminate , 'forceStop' : force_stop })
11561161 if resp is None :
11571162 raise Exception ('Env update returned no data' )
11581163 if resp .get ('messages' , {}).get ('error' , False ):
11591164 raise Exception ('Cluster operation failed : %s' % (json .dumps (resp .get ('messages' , {}).get ('messages' , {}))))
11601165 return resp
11611166
1167+ def kubectl_command (self , args ):
1168+ """
1169+ Runs an arbitrary kubectl command on the cluster.
1170+
1171+ This operation is only valid for a Kubernetes cluster.
1172+
1173+ :param args: the arguments to pass to kubectl (without the "kubectl")
1174+ :type args: str
1175+ :return: a dict containing the return value, output, and possible error output of the command
1176+ :rtype: dict
1177+ """
1178+ return self .client ._perform_json (
1179+ "POST" , "/admin/clusters/%s/k8s/kubectl" % self .cluster_id ,
1180+ body = {'args' : args })
1181+
1182+ @staticmethod
1183+ def _build_args (base_command , namespace , label_filter , dry_run = True ):
1184+ args = base_command
1185+ if namespace :
1186+ args += ' --namespace ' + namespace
1187+ if label_filter :
1188+ args += ' -l ' + label_filter
1189+ if dry_run :
1190+ args += ' --dry-run=client'
1191+ return args
1192+
1193+ def delete_finished_jobs (self , delete_failed = False , namespace = "" , label_filter = "" , dry_run = True ):
1194+ """
1195+ Runs a kubectl command to delete finished jobs.
1196+
1197+ This operation is only valid for a Kubernetes cluster.
1198+
1199+ :param delete_failed: if True, delete both completed and failed jobs, otherwise only delete completed jobs
1200+ :type delete_failed: bool
1201+ :param namespace: the namespace in which to delete the jobs
1202+ :type namespace: str
1203+ :param label_filter: delete only jobs matching a label filter
1204+ :type label_filter: str
1205+ :param dry_run: if True, execute the command as a "dry run"
1206+ :type dry_run: bool
1207+ :return: a dict containing the return value, output, and possible error output of the command
1208+ :rtype: dict
1209+ """
1210+ return self .client ._perform_json (
1211+ "POST" , "/admin/clusters/%s/k8s/delete-finished-jobs" % self .cluster_id ,
1212+ params = {'deleteFailed' : delete_failed , 'namespace' : namespace , 'labelFilter' : label_filter , 'dryRun' : dry_run })
1213+
1214+ def delete_succeeded_and_failed_pods (self , namespace = "" , label_filter = "" , dry_run = True ):
1215+ """
1216+ Runs a kubectl command to delete succeeded and failed pods.
1217+
1218+ This operation is only valid for a Kubernetes cluster.
1219+
1220+ :param namespace: the namespace in which to delete the pods
1221+ :type namespace: str
1222+ :param label_filter: delete only pods matching a label filter
1223+ :type label_filter: str
1224+ :param dry_run: if True, execute the command as a "dry run"
1225+ :type dry_run: bool
1226+ :return: a dict containing the return value, output, and possible error output of the command
1227+ :rtype: dict
1228+ """
1229+ return self .kubectl_command (
1230+ self ._build_args (
1231+ 'delete pods --field-selector=status.phase!=Pending,status.phase!=Running,status.phase!=Unknown' ,
1232+ namespace , label_filter , dry_run ))
1233+
1234+ def delete_all_pods (self , namespace = "" , label_filter = "" , dry_run = True ):
1235+ """
1236+ Runs a kubectl command to delete all pods.
1237+
1238+ This operation is only valid for a Kubernetes cluster.
1239+
1240+ :param namespace: the namespace in which to delete the pods
1241+ :type namespace: str
1242+ :param label_filter: delete only pods matching a label filter
1243+ :type label_filter: str
1244+ :param dry_run: if True, execute the command as a "dry run"
1245+ :type dry_run: bool
1246+ :return: a dict containing the return value, output, and possible error output of the command
1247+ :rtype: dict
1248+ """
1249+ args = 'delete pods'
1250+ if not label_filter :
1251+ args += ' --all'
1252+ return self .kubectl_command (self ._build_args (args , namespace , label_filter , dry_run ))
1253+
11621254class DSSClusterSettings (object ):
11631255 """
11641256 The settings of a cluster
0 commit comments