api.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright © 2021 Ettore Di Giacinto <[email protected]>
  2. //
  3. // This program is free software; you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation; either version 2 of the License, or
  6. // (at your option) any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License along
  14. // with this program; if not, see <http://www.gnu.org/licenses/>.
  15. package api
  16. import (
  17. "context"
  18. "embed"
  19. "io/fs"
  20. "net/http"
  21. "time"
  22. "github.com/labstack/echo/v4"
  23. "github.com/mudler/edgevpn/pkg/blockchain"
  24. "github.com/mudler/edgevpn/pkg/edgevpn"
  25. "github.com/mudler/edgevpn/pkg/edgevpn/types"
  26. )
  27. //go:embed public
  28. var embededFiles embed.FS
  29. func getFileSystem() http.FileSystem {
  30. fsys, err := fs.Sub(embededFiles, "public")
  31. if err != nil {
  32. panic(err)
  33. }
  34. return http.FS(fsys)
  35. }
  36. func API(l string, defaultInterval, timeout time.Duration, ledger *blockchain.Ledger) error {
  37. ec := echo.New()
  38. assetHandler := http.FileServer(getFileSystem())
  39. // Get data from ledger
  40. ec.GET("/api/files", func(c echo.Context) error {
  41. list := []*types.File{}
  42. for _, v := range ledger.CurrentData()[edgevpn.FilesLedgerKey] {
  43. machine := &types.File{}
  44. v.Unmarshal(machine)
  45. list = append(list, machine)
  46. }
  47. return c.JSON(http.StatusOK, list)
  48. })
  49. ec.GET("/api/summary", func(c echo.Context) error {
  50. files := len(ledger.CurrentData()[edgevpn.FilesLedgerKey])
  51. machines := len(ledger.CurrentData()[edgevpn.MachinesLedgerKey])
  52. users := len(ledger.CurrentData()[edgevpn.UsersLedgerKey])
  53. services := len(ledger.CurrentData()[edgevpn.ServicesLedgerKey])
  54. blockchain := ledger.Index()
  55. return c.JSON(http.StatusOK, struct {
  56. Files, Machines, Users, Services, BlockChain int
  57. }{files, machines, users, services, blockchain})
  58. })
  59. ec.GET("/api/machines", func(c echo.Context) error {
  60. list := []*types.Machine{}
  61. for _, v := range ledger.CurrentData()[edgevpn.MachinesLedgerKey] {
  62. machine := &types.Machine{}
  63. v.Unmarshal(machine)
  64. list = append(list, machine)
  65. }
  66. return c.JSON(http.StatusOK, list)
  67. })
  68. ec.GET("/api/users", func(c echo.Context) error {
  69. user := []*types.User{}
  70. for _, v := range ledger.CurrentData()[edgevpn.UsersLedgerKey] {
  71. u := &types.User{}
  72. v.Unmarshal(u)
  73. user = append(user, u)
  74. }
  75. return c.JSON(http.StatusOK, user)
  76. })
  77. ec.GET("/api/services", func(c echo.Context) error {
  78. list := []*types.Service{}
  79. for _, v := range ledger.CurrentData()[edgevpn.ServicesLedgerKey] {
  80. srvc := &types.Service{}
  81. v.Unmarshal(srvc)
  82. list = append(list, srvc)
  83. }
  84. return c.JSON(http.StatusOK, list)
  85. })
  86. ec.GET("/*", echo.WrapHandler(http.StripPrefix("/", assetHandler)))
  87. ec.GET("/api/blockchain", func(c echo.Context) error {
  88. return c.JSON(http.StatusOK, ledger.LastBlock())
  89. })
  90. ec.GET("/api/ledger", func(c echo.Context) error {
  91. return c.JSON(http.StatusOK, ledger.CurrentData())
  92. })
  93. ec.GET("/api/ledger/:bucket/:key", func(c echo.Context) error {
  94. bucket := c.Param("bucket")
  95. key := c.Param("key")
  96. return c.JSON(http.StatusOK, ledger.CurrentData()[bucket][key])
  97. })
  98. ec.GET("/api/ledger/:bucket", func(c echo.Context) error {
  99. bucket := c.Param("bucket")
  100. return c.JSON(http.StatusOK, ledger.CurrentData()[bucket])
  101. })
  102. announcing := struct{ State string }{"Announcing"}
  103. // Store arbitrary data
  104. ec.PUT("/api/ledger/:bucket/:key/:value", func(c echo.Context) error {
  105. bucket := c.Param("bucket")
  106. key := c.Param("key")
  107. value := c.Param("value")
  108. ledger.Persist(context.Background(), defaultInterval, timeout, bucket, key, value)
  109. return c.JSON(http.StatusOK, announcing)
  110. })
  111. // Delete data from ledger
  112. ec.DELETE("/api/ledger/:bucket", func(c echo.Context) error {
  113. bucket := c.Param("bucket")
  114. ledger.AnnounceDeleteBucket(context.Background(), defaultInterval, timeout, bucket)
  115. return c.JSON(http.StatusOK, announcing)
  116. })
  117. ec.DELETE("/api/ledger/:bucket/:key", func(c echo.Context) error {
  118. bucket := c.Param("bucket")
  119. key := c.Param("key")
  120. ledger.AnnounceDeleteBucketKey(context.Background(), defaultInterval, timeout, bucket, key)
  121. return c.JSON(http.StatusOK, announcing)
  122. })
  123. return ec.Start(l)
  124. }