@@ -2,6 +2,7 @@ package handlers
22
33import (
44 "net/http"
5+ "strconv"
56 "time"
67
78 "github.com/gin-gonic/gin"
@@ -202,3 +203,286 @@ func (h *KubernetesHandler) ListContexts(c *gin.Context) {
202203 },
203204 })
204205}
206+
207+ // GetPodLogs returns logs from a pod
208+ // GET /v1/kubernetes/pods/:namespace/:podName/logs
209+ func (h * KubernetesHandler ) GetPodLogs (c * gin.Context ) {
210+ if h .discovery == nil {
211+ c .JSON (http .StatusServiceUnavailable , types.Response {
212+ Success : false ,
213+ Error : & types.ErrorInfo {
214+ Code : "kubernetes_discovery_unavailable" ,
215+ Message : "Kubernetes discovery not configured" ,
216+ },
217+ })
218+ return
219+ }
220+
221+ namespace := c .Param ("namespace" )
222+ podName := c .Param ("podName" )
223+
224+ if namespace == "" || podName == "" {
225+ c .JSON (http .StatusBadRequest , types.Response {
226+ Success : false ,
227+ Error : & types.ErrorInfo {
228+ Code : "missing_params" ,
229+ Message : "namespace and podName are required" ,
230+ },
231+ })
232+ return
233+ }
234+
235+ ctx := c .Query ("context" )
236+
237+ opts := types.PodLogsOptions {
238+ Container : c .Query ("container" ),
239+ SinceTime : c .Query ("since_time" ),
240+ Previous : c .Query ("previous" ) == "true" ,
241+ Timestamps : c .Query ("timestamps" ) == "true" ,
242+ }
243+
244+ if tailLines := c .Query ("tail_lines" ); tailLines != "" {
245+ if n , err := strconv .Atoi (tailLines ); err == nil {
246+ opts .TailLines = n
247+ }
248+ }
249+
250+ logs , err := h .discovery .GetPodLogs (ctx , namespace , podName , opts )
251+ if err != nil {
252+ c .JSON (http .StatusInternalServerError , types.Response {
253+ Success : false ,
254+ Error : & types.ErrorInfo {
255+ Code : "get_pod_logs_failed" ,
256+ Message : err .Error (),
257+ },
258+ })
259+ return
260+ }
261+
262+ c .JSON (http .StatusOK , types.Response {
263+ Success : true ,
264+ Data : logs ,
265+ Meta : & types.MetaInfo {
266+ Timestamp : time .Now (),
267+ },
268+ })
269+ }
270+
271+ // ListPods returns pods in a namespace
272+ // GET /v1/kubernetes/pods/:namespace
273+ func (h * KubernetesHandler ) ListPods (c * gin.Context ) {
274+ if h .discovery == nil {
275+ c .JSON (http .StatusServiceUnavailable , types.Response {
276+ Success : false ,
277+ Error : & types.ErrorInfo {
278+ Code : "kubernetes_discovery_unavailable" ,
279+ Message : "Kubernetes discovery not configured" ,
280+ },
281+ })
282+ return
283+ }
284+
285+ namespace := c .Param ("namespace" )
286+ if namespace == "" {
287+ c .JSON (http .StatusBadRequest , types.Response {
288+ Success : false ,
289+ Error : & types.ErrorInfo {
290+ Code : "missing_namespace" ,
291+ Message : "namespace is required" ,
292+ },
293+ })
294+ return
295+ }
296+
297+ ctx := c .Query ("context" )
298+
299+ opts := types.ListPodsOptions {
300+ LabelSelector : c .Query ("label_selector" ),
301+ FieldSelector : c .Query ("field_selector" ),
302+ ServiceName : c .Query ("service_name" ),
303+ }
304+
305+ pods , err := h .discovery .ListPods (ctx , namespace , opts )
306+ if err != nil {
307+ c .JSON (http .StatusInternalServerError , types.Response {
308+ Success : false ,
309+ Error : & types.ErrorInfo {
310+ Code : "list_pods_failed" ,
311+ Message : err .Error (),
312+ },
313+ })
314+ return
315+ }
316+
317+ c .JSON (http .StatusOK , types.Response {
318+ Success : true ,
319+ Data : pods ,
320+ Meta : & types.MetaInfo {
321+ Count : len (pods ),
322+ Timestamp : time .Now (),
323+ },
324+ })
325+ }
326+
327+ // GetPod returns details for a specific pod
328+ // GET /v1/kubernetes/pods/:namespace/:podName
329+ func (h * KubernetesHandler ) GetPod (c * gin.Context ) {
330+ if h .discovery == nil {
331+ c .JSON (http .StatusServiceUnavailable , types.Response {
332+ Success : false ,
333+ Error : & types.ErrorInfo {
334+ Code : "kubernetes_discovery_unavailable" ,
335+ Message : "Kubernetes discovery not configured" ,
336+ },
337+ })
338+ return
339+ }
340+
341+ namespace := c .Param ("namespace" )
342+ podName := c .Param ("podName" )
343+
344+ if namespace == "" || podName == "" {
345+ c .JSON (http .StatusBadRequest , types.Response {
346+ Success : false ,
347+ Error : & types.ErrorInfo {
348+ Code : "missing_params" ,
349+ Message : "namespace and podName are required" ,
350+ },
351+ })
352+ return
353+ }
354+
355+ ctx := c .Query ("context" )
356+
357+ pod , err := h .discovery .GetPod (ctx , namespace , podName )
358+ if err != nil {
359+ c .JSON (http .StatusNotFound , types.Response {
360+ Success : false ,
361+ Error : & types.ErrorInfo {
362+ Code : "pod_not_found" ,
363+ Message : err .Error (),
364+ },
365+ })
366+ return
367+ }
368+
369+ c .JSON (http .StatusOK , types.Response {
370+ Success : true ,
371+ Data : pod ,
372+ Meta : & types.MetaInfo {
373+ Timestamp : time .Now (),
374+ },
375+ })
376+ }
377+
378+ // GetEvents returns Kubernetes events for a namespace
379+ // GET /v1/kubernetes/events/:namespace
380+ func (h * KubernetesHandler ) GetEvents (c * gin.Context ) {
381+ if h .discovery == nil {
382+ c .JSON (http .StatusServiceUnavailable , types.Response {
383+ Success : false ,
384+ Error : & types.ErrorInfo {
385+ Code : "kubernetes_discovery_unavailable" ,
386+ Message : "Kubernetes discovery not configured" ,
387+ },
388+ })
389+ return
390+ }
391+
392+ namespace := c .Param ("namespace" )
393+ if namespace == "" {
394+ c .JSON (http .StatusBadRequest , types.Response {
395+ Success : false ,
396+ Error : & types.ErrorInfo {
397+ Code : "missing_namespace" ,
398+ Message : "namespace is required" ,
399+ },
400+ })
401+ return
402+ }
403+
404+ ctx := c .Query ("context" )
405+
406+ opts := types.GetEventsOptions {
407+ ResourceKind : c .Query ("resource_kind" ),
408+ ResourceName : c .Query ("resource_name" ),
409+ }
410+
411+ if limit := c .Query ("limit" ); limit != "" {
412+ if n , err := strconv .Atoi (limit ); err == nil {
413+ opts .Limit = n
414+ }
415+ }
416+
417+ events , err := h .discovery .GetEvents (ctx , namespace , opts )
418+ if err != nil {
419+ c .JSON (http .StatusInternalServerError , types.Response {
420+ Success : false ,
421+ Error : & types.ErrorInfo {
422+ Code : "get_events_failed" ,
423+ Message : err .Error (),
424+ },
425+ })
426+ return
427+ }
428+
429+ c .JSON (http .StatusOK , types.Response {
430+ Success : true ,
431+ Data : events ,
432+ Meta : & types.MetaInfo {
433+ Count : len (events ),
434+ Timestamp : time .Now (),
435+ },
436+ })
437+ }
438+
439+ // GetEndpoints returns endpoints for a service
440+ // GET /v1/kubernetes/endpoints/:namespace/:serviceName
441+ func (h * KubernetesHandler ) GetEndpoints (c * gin.Context ) {
442+ if h .discovery == nil {
443+ c .JSON (http .StatusServiceUnavailable , types.Response {
444+ Success : false ,
445+ Error : & types.ErrorInfo {
446+ Code : "kubernetes_discovery_unavailable" ,
447+ Message : "Kubernetes discovery not configured" ,
448+ },
449+ })
450+ return
451+ }
452+
453+ namespace := c .Param ("namespace" )
454+ serviceName := c .Param ("serviceName" )
455+
456+ if namespace == "" || serviceName == "" {
457+ c .JSON (http .StatusBadRequest , types.Response {
458+ Success : false ,
459+ Error : & types.ErrorInfo {
460+ Code : "missing_params" ,
461+ Message : "namespace and serviceName are required" ,
462+ },
463+ })
464+ return
465+ }
466+
467+ ctx := c .Query ("context" )
468+
469+ endpoints , err := h .discovery .GetEndpoints (ctx , namespace , serviceName )
470+ if err != nil {
471+ c .JSON (http .StatusNotFound , types.Response {
472+ Success : false ,
473+ Error : & types.ErrorInfo {
474+ Code : "endpoints_not_found" ,
475+ Message : err .Error (),
476+ },
477+ })
478+ return
479+ }
480+
481+ c .JSON (http .StatusOK , types.Response {
482+ Success : true ,
483+ Data : endpoints ,
484+ Meta : & types.MetaInfo {
485+ Timestamp : time .Now (),
486+ },
487+ })
488+ }
0 commit comments