clustersendpoints.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package clusters
  2. import (
  3. "errors"
  4. "io/ioutil"
  5. "net/http"
  6. "github.com/julienschmidt/httprouter"
  7. "github.com/opencost/opencost/pkg/log"
  8. "github.com/opencost/opencost/pkg/util/json"
  9. )
  10. // DataEnvelope is a generic wrapper struct for http response data
  11. type DataEnvelope struct {
  12. Code int `json:"code"`
  13. Status string `json:"status"`
  14. Data interface{} `json:"data"`
  15. }
  16. // ClusterManagerHTTPService is an implementation of HTTPService which provides
  17. // the frontend with the ability to manage stored cluster definitions.
  18. type ClusterManagerHTTPService struct {
  19. manager *ClusterManager
  20. }
  21. // NewClusterManagerHTTPService creates a new cluster management http service
  22. func NewClusterManagerHTTPService(manager *ClusterManager) *ClusterManagerHTTPService {
  23. return &ClusterManagerHTTPService{
  24. manager: manager,
  25. }
  26. }
  27. // Register assigns the endpoints and returns an error on failure.
  28. func (cme *ClusterManagerHTTPService) Register(router *httprouter.Router) error {
  29. router.GET("/clusters", cme.GetAllClusters)
  30. router.PUT("/clusters", cme.PutCluster)
  31. router.DELETE("/clusters/:id", cme.DeleteCluster)
  32. return nil
  33. }
  34. func (cme *ClusterManagerHTTPService) GetAllClusters(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
  35. w.Header().Set("Content-Type", "application/json")
  36. clusters := cme.manager.GetAll()
  37. w.Write(wrapData(clusters, nil))
  38. }
  39. func (cme *ClusterManagerHTTPService) PutCluster(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
  40. w.Header().Set("Content-Type", "application/json")
  41. data, err := ioutil.ReadAll(r.Body)
  42. if err != nil {
  43. w.Write(wrapData(nil, err))
  44. return
  45. }
  46. var clusterDef ClusterDefinition
  47. err = json.Unmarshal(data, &clusterDef)
  48. if err != nil {
  49. w.Write(wrapData(nil, err))
  50. return
  51. }
  52. cd, err := cme.manager.AddOrUpdate(clusterDef)
  53. if err != nil {
  54. w.Write(wrapData(nil, err))
  55. return
  56. }
  57. w.Write(wrapData(cd, nil))
  58. }
  59. func (cme *ClusterManagerHTTPService) DeleteCluster(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
  60. w.Header().Set("Content-Type", "application/json")
  61. clusterID := ps.ByName("id")
  62. if clusterID == "" {
  63. w.Write(wrapData(nil, errors.New("Failed to locate cluster with empty id.")))
  64. return
  65. }
  66. err := cme.manager.Remove(clusterID)
  67. if err != nil {
  68. w.Write(wrapData(nil, err))
  69. return
  70. }
  71. w.Write(wrapData("success", nil))
  72. }
  73. func wrapData(data interface{}, err error) []byte {
  74. var resp []byte
  75. if err != nil {
  76. log.Infof("Error returned to client: %s", err.Error())
  77. resp, _ = json.Marshal(&DataEnvelope{
  78. Code: http.StatusInternalServerError,
  79. Status: "error",
  80. Data: err.Error(),
  81. })
  82. } else {
  83. resp, _ = json.Marshal(&DataEnvelope{
  84. Code: http.StatusOK,
  85. Status: "success",
  86. Data: data,
  87. })
  88. }
  89. return resp
  90. }