api.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "log"
  6. "net/http"
  7. "strings"
  8. "imuslab.com/bokofs/bokofsd/mod/diskinfo"
  9. "imuslab.com/bokofs/bokofsd/mod/diskinfo/lsblk"
  10. "imuslab.com/bokofs/bokofsd/mod/netstat"
  11. )
  12. /*
  13. API Router
  14. This module handle routing of the API calls
  15. */
  16. // Primary handler for the API router
  17. func HandlerAPIcalls() http.Handler {
  18. return http.StripPrefix("/api", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  19. // Get the disk ID from the URL path
  20. pathParts := strings.Split(r.URL.Path, "/")
  21. if len(pathParts) < 2 {
  22. http.Error(w, "Bad Request", http.StatusBadRequest)
  23. return
  24. }
  25. diskID := pathParts[1]
  26. if diskID == "" {
  27. http.Error(w, "Bad Request", http.StatusBadRequest)
  28. return
  29. }
  30. switch diskID {
  31. case "info":
  32. // Request to /api/info/*
  33. HandleInfoAPIcalls().ServeHTTP(w, r)
  34. return
  35. case "smart":
  36. // Request to /api/smart/*
  37. HandleSMARTCalls().ServeHTTP(w, r)
  38. return
  39. case "raid":
  40. // Request to /api/raid/*
  41. HandleRAIDCalls().ServeHTTP(w, r)
  42. default:
  43. http.Error(w, "Not Found", http.StatusNotFound)
  44. return
  45. }
  46. }))
  47. }
  48. // Handler for info API calls
  49. func HandleInfoAPIcalls() http.Handler {
  50. return http.StripPrefix("/info/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  51. //Check the next part of the URL
  52. pathParts := strings.Split(r.URL.Path, "/")
  53. subPath := pathParts[0]
  54. switch subPath {
  55. case "netstat":
  56. // Get the current network statistics
  57. netstatBuffer.HandleGetBufferedNetworkInterfaceStats(w, r)
  58. return
  59. case "iface":
  60. // Get the list of network interfaces
  61. netstat.HandleListNetworkInterfaces(w, r)
  62. return
  63. case "list":
  64. // List all block devices and their partitions
  65. blockDevices, err := lsblk.GetLSBLKOutput()
  66. if err != nil {
  67. log.Println("Error getting block devices:", err)
  68. http.Error(w, "Internal Server Error", http.StatusInternalServerError)
  69. return
  70. }
  71. disks := make([]*diskinfo.Disk, 0)
  72. for _, device := range blockDevices {
  73. if device.Type == "disk" {
  74. disk, err := diskinfo.GetDiskInfo(device.Name)
  75. if err != nil {
  76. log.Println("Error getting disk info:", err)
  77. http.Error(w, "Internal Server Error", http.StatusInternalServerError)
  78. return
  79. }
  80. disks = append(disks, disk)
  81. }
  82. }
  83. // Convert the block devices to JSON and write it to the response
  84. js, _ := json.Marshal(disks)
  85. w.Header().Set("Content-Type", "application/json")
  86. w.WriteHeader(http.StatusOK)
  87. w.Write(js)
  88. case "disk":
  89. // Get the disk info for a particular disk, e.g. sda
  90. if len(pathParts) < 2 {
  91. http.Error(w, "Bad Request - Invalid disk name", http.StatusBadRequest)
  92. return
  93. }
  94. diskID := pathParts[1]
  95. if diskID == "" {
  96. http.Error(w, "Bad Request - Invalid disk name", http.StatusBadRequest)
  97. return
  98. }
  99. if !diskinfo.DevicePathIsValidDisk(diskID) {
  100. log.Println("Invalid disk ID:", diskID)
  101. http.Error(w, "Bad Request", http.StatusBadRequest)
  102. return
  103. }
  104. // Handle diskinfo API calls
  105. targetDiskInfo, err := diskinfo.GetDiskInfo(diskID)
  106. if err != nil {
  107. http.Error(w, "Internal Server Error", http.StatusInternalServerError)
  108. return
  109. }
  110. // Convert the disk info to JSON and write it to the response
  111. js, _ := json.Marshal(targetDiskInfo)
  112. w.Header().Set("Content-Type", "application/json")
  113. w.WriteHeader(http.StatusOK)
  114. w.Write(js)
  115. return
  116. case "part":
  117. // Get the partition info for a particular partition, e.g. sda1
  118. if len(pathParts) < 2 {
  119. http.Error(w, "Bad Request - Missing parition name", http.StatusBadRequest)
  120. return
  121. }
  122. partID := pathParts[1]
  123. if partID == "" {
  124. http.Error(w, "Bad Request - Missing parition name", http.StatusBadRequest)
  125. return
  126. }
  127. if !diskinfo.DevicePathIsValidPartition(partID) {
  128. log.Println("Invalid partition name:", partID)
  129. http.Error(w, "Bad Request - Invalid parition name", http.StatusBadRequest)
  130. return
  131. }
  132. // Handle partinfo API calls
  133. targetPartInfo, err := diskinfo.GetPartitionInfo(partID)
  134. if err != nil {
  135. http.Error(w, "Internal Server Error", http.StatusInternalServerError)
  136. return
  137. }
  138. // Convert the partition info to JSON and write it to the response
  139. js, _ := json.Marshal(targetPartInfo)
  140. w.Header().Set("Content-Type", "application/json")
  141. w.WriteHeader(http.StatusOK)
  142. w.Write(js)
  143. return
  144. default:
  145. fmt.Println("Unknown API call:", subPath)
  146. http.Error(w, "Not Found", http.StatusNotFound)
  147. }
  148. }))
  149. }