feat: updated server implementation
This commit is contained in:
parent
0d27f07a8b
commit
d56a9e452f
5 changed files with 348 additions and 75 deletions
51
pkg/service/constants.go
Normal file
51
pkg/service/constants.go
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
const (
|
||||||
|
RELPATH_PLUGINS = "/plugins"
|
||||||
|
RELPATH_PROFILES = "/profiles"
|
||||||
|
RELPATH_DATA = "/data"
|
||||||
|
RELPATH_METADATA = "/.configurator"
|
||||||
|
RELPATH_HELP = RELPATH_DATA + "/index.html"
|
||||||
|
|
||||||
|
DEFAULT_TIMEOUT_IN_SECS = 60
|
||||||
|
DEFAULT_PLUGINS_MAX_COUNT = 64
|
||||||
|
DEFAULT_PROFILES_MAX_COUNT = 256
|
||||||
|
DEFAULT_METADATA = ``
|
||||||
|
DEFAULT_HOME = `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
# setup environment variables</br>
|
||||||
|
export CONFIGURATOR_HOST={{ configurator.host }}</br>
|
||||||
|
export CONFIGURATOR_PATH={{ configurator.path }}</br>
|
||||||
|
export CONFIGURATOR_SERVER_ROOT={{ configurator.server_root }}</br>
|
||||||
|
</br>
|
||||||
|
# start the service</br>
|
||||||
|
configurator serve --root $HOME/apps/configurator/server --init</br>
|
||||||
|
</br>
|
||||||
|
# download a file or directory (as archive)</br>
|
||||||
|
configurator download</br>
|
||||||
|
configurator download --host http://localhost:5050 --path help.txt</br>
|
||||||
|
</br>
|
||||||
|
# download files with rendering using plugins</br>
|
||||||
|
configurator download --plugins smd,jinja2 --profile compute</br>
|
||||||
|
curl $CONFIGURATOR_HOST/download/help.txt?plugins=smd,jinja2</br>
|
||||||
|
</br>
|
||||||
|
# upload a file or directory (recursively)</br>
|
||||||
|
configurator upload</br>
|
||||||
|
configurator upload --host http://localhost:5050 --path help.txt</br>
|
||||||
|
</br>
|
||||||
|
# list the files in a directory</br>
|
||||||
|
configurator list --path help.txt</br>
|
||||||
|
configurator list --host http://localhost:5050 --path help.txt</br>
|
||||||
|
curl http://localhost:5050/list/test</br>
|
||||||
|
</p>
|
||||||
|
<body>
|
||||||
|
</html>
|
||||||
|
`
|
||||||
|
)
|
||||||
|
|
||||||
|
// configurator.host: https://example.com
|
||||||
|
// configurator.path: test
|
||||||
|
// configurator.server_root: $HOME/apps/configurator
|
||||||
120
pkg/service/plugins.go
Normal file
120
pkg/service/plugins.go
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
configurator "git.towk2.me/towk/configurator/pkg"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Service) ListPlugins() http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var (
|
||||||
|
plugins map[string]configurator.Plugin
|
||||||
|
names []string
|
||||||
|
body []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
plugins, err = LoadPluginsFromDir(s.PathForPlugins())
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for name := range plugins {
|
||||||
|
names = append(names, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err = json.Marshal(names)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) CreatePlugin() http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var (
|
||||||
|
plugin configurator.Plugin
|
||||||
|
path string
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
plugin, err = getPluginFromRequestBody(r)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper to check for valid plugin name
|
||||||
|
var hasValidName = func(name string) bool {
|
||||||
|
return name != "" && len(name) < 64
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for a valid plugin name
|
||||||
|
if !hasValidName(plugin.Name()) {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// save plugin at path using it's name
|
||||||
|
path = s.PathForPluginWithName(plugin.Name())
|
||||||
|
err = SavePluginToFile(path, &plugin)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) DeletePlugin() http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var (
|
||||||
|
path string
|
||||||
|
plugin configurator.Plugin
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
plugin, err = getPluginFromRequestBody(r)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
path = s.PathForPluginWithName(plugin.Name())
|
||||||
|
err = os.Remove(path)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPluginFromRequestBody(r *http.Request) (configurator.Plugin, error) {
|
||||||
|
var (
|
||||||
|
plugin configurator.Plugin
|
||||||
|
body []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
body, err = io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(body, &plugin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugin, nil
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
configurator "git.towk2.me/towk/configurator/pkg"
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/tidwall/sjson"
|
"github.com/tidwall/sjson"
|
||||||
)
|
)
|
||||||
|
|
@ -26,7 +25,7 @@ type Profile struct {
|
||||||
func (s *Service) GetProfiles() http.HandlerFunc {
|
func (s *Service) GetProfiles() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var (
|
var (
|
||||||
path = s.RootPath + PROFILES_RELPATH
|
path = s.RootPath + RELPATH_PROFILES
|
||||||
profiles []*Profile
|
profiles []*Profile
|
||||||
contents []byte
|
contents []byte
|
||||||
err error
|
err error
|
||||||
|
|
@ -272,44 +271,6 @@ func (s *Service) GetProfileData() http.HandlerFunc {
|
||||||
// return func(w http.ResponseWriter, r *http.Request) {}
|
// return func(w http.ResponseWriter, r *http.Request) {}
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func (s *Service) GetPlugins() http.HandlerFunc {
|
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
var (
|
|
||||||
plugins map[string]configurator.Plugin
|
|
||||||
names []string
|
|
||||||
body []byte
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
plugins, err = LoadPluginsFromDir(s.PathForPlugins())
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for name := range plugins {
|
|
||||||
names = append(names, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err = json.Marshal(names)
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Write(body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) CreatePlugins() http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) DeletePlugins() http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadProfileContents(path string) ([]byte, error) {
|
func loadProfileContents(path string) ([]byte, error) {
|
||||||
var (
|
var (
|
||||||
contents []byte
|
contents []byte
|
||||||
|
|
|
||||||
|
|
@ -3,44 +3,91 @@ package service
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.towk2.me/towk/configurator/pkg/util"
|
"git.towk2.me/towk/configurator/pkg/util"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Service) Download() http.HandlerFunc {
|
func (s *Service) Download() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var (
|
var (
|
||||||
path = strings.TrimPrefix(r.URL.Path, "/download")
|
path = s.PathForData() + strings.TrimPrefix(r.URL.Path, "/download")
|
||||||
fileInfo os.FileInfo
|
fileInfo os.FileInfo
|
||||||
out *os.File
|
out *os.File
|
||||||
|
contents []byte
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
fmt.Printf("download path: %v\n", path)
|
log.Debug().
|
||||||
|
Str("path", path).
|
||||||
|
Str("client_host", r.Host).
|
||||||
|
Msg("Service.Download()")
|
||||||
|
|
||||||
// determine if path is directory, file, or exists
|
// determine if path is directory, file, or exists
|
||||||
if fileInfo, err = os.Stat(filepath.Clean(path)); err != nil {
|
if fileInfo, err = os.Stat(path); err == nil {
|
||||||
if fileInfo.IsDir() {
|
if fileInfo.IsDir() {
|
||||||
// recursively walk dir acompressednd get all filenames
|
// create an archive of the directory and download
|
||||||
// download directory as archive
|
log.Debug().
|
||||||
out, err = os.Create(fmt.Sprintf("%s.tar", path))
|
Str("type", "directory").
|
||||||
if err != nil {
|
Msg("Service.Download()")
|
||||||
|
|
||||||
|
archivePath := fmt.Sprintf("%d.tar.gz", time.Now().Unix())
|
||||||
|
out, err = os.Create(archivePath)
|
||||||
|
if err != nil {
|
||||||
|
s.writeErrorResponse(w, fmt.Sprintf("failed to create named file: %v", err), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
err = util.CreateArchive([]string{path}, out)
|
|
||||||
if err != nil {
|
|
||||||
|
|
||||||
|
filesToArchive := []string{}
|
||||||
|
filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error {
|
||||||
|
if !d.IsDir() {
|
||||||
|
filesToArchive = append(filesToArchive, path)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
log.Debug().Strs("files", filesToArchive).Send()
|
||||||
|
err = util.CreateArchive(filesToArchive, out)
|
||||||
|
if err != nil {
|
||||||
|
s.writeErrorResponse(w, fmt.Sprintf("failed to create archive: %v", err.Error()), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
contents, err = os.ReadFile(archivePath)
|
||||||
|
if err != nil {
|
||||||
|
s.writeErrorResponse(w, fmt.Sprintf("failed to read archive: %v", err.Error()), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(contents)
|
||||||
|
|
||||||
|
err = os.Remove(archivePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("failed to remove temporary archive")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// download individual file
|
// download individual file
|
||||||
|
log.Debug().
|
||||||
|
Str("type", "file").
|
||||||
|
Msg("Service.Download()")
|
||||||
|
contents, err = os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
s.writeErrorResponse(w, fmt.Sprintf("failed to read file to download: %v", err.Error()), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
w.Write(contents)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s.writeErrorResponse(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,19 +99,54 @@ func (s *Service) Upload() http.HandlerFunc {
|
||||||
|
|
||||||
func (s *Service) List() http.HandlerFunc {
|
func (s *Service) List() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var (
|
||||||
|
path = s.PathForData() + strings.TrimPrefix(r.URL.Path, "/list")
|
||||||
|
entries []string
|
||||||
|
body []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
// show what we're listing
|
||||||
|
log.Debug().Str("path", path).Msg("Service.List()")
|
||||||
|
|
||||||
|
// walk directory and show all entries "ls"
|
||||||
|
err = filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
entries = append(entries, d.Name())
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
switch err {
|
||||||
|
case fs.ErrNotExist, fs.ErrInvalid:
|
||||||
|
http.Error(w, "No such file or directory...", http.StatusBadRequest)
|
||||||
|
case fs.ErrPermission:
|
||||||
|
http.Error(w, "Invalid permissions...", http.StatusForbidden)
|
||||||
|
default:
|
||||||
|
http.Error(w, "Something went wrong (file or directory *probably* does not exist)...", http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err = json.Marshal(entries)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) GetStatus(w http.ResponseWriter, r *http.Request) {
|
func (s *Service) GetStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
data := map[string]any{
|
err := json.NewEncoder(w).Encode(map[string]any{
|
||||||
"code": 200,
|
"code": http.StatusOK,
|
||||||
"message": "Configurator is healthy",
|
"message": "Configurator is healthy",
|
||||||
}
|
})
|
||||||
err := json.NewEncoder(w).Encode(data)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to encode JSON: %v\n", err)
|
fmt.Printf("failed to encode JSON response body: %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,36 +15,69 @@ import (
|
||||||
"git.towk2.me/towk/configurator/pkg/util"
|
"git.towk2.me/towk/configurator/pkg/util"
|
||||||
"github.com/go-chi/chi/middleware"
|
"github.com/go-chi/chi/middleware"
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
)
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
const (
|
|
||||||
PLUGINS_RELPATH = "/plugins"
|
|
||||||
TEMPLATES_RELPATH = "/templates"
|
|
||||||
PROFILES_RELPATH = "/profiles"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
|
Addr string
|
||||||
RootPath string `yaml:"root,omitempty"`
|
RootPath string `yaml:"root,omitempty"`
|
||||||
Environment map[string]string
|
Environment map[string]string
|
||||||
|
|
||||||
// max counts
|
// max counts
|
||||||
PluginsMaxCount int
|
PluginsMaxCount int
|
||||||
ProfilesMaxCount int
|
ProfilesMaxCount int
|
||||||
|
Timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates the directories at specified path
|
// New creates a new Service instance with default values
|
||||||
func New() *Service {
|
func New() *Service {
|
||||||
return &Service{
|
return &Service{
|
||||||
RootPath: ".",
|
Addr: ":5050",
|
||||||
|
RootPath: "./",
|
||||||
Environment: map[string]string{
|
Environment: map[string]string{
|
||||||
"CONFIGURATOR_HOST_URI": "",
|
"CONFIGURATOR_HOST": "",
|
||||||
|
"CONFIGURATOR_ROOT": "",
|
||||||
"ACCESS_TOKEN": "",
|
"ACCESS_TOKEN": "",
|
||||||
},
|
},
|
||||||
PluginsMaxCount: 64,
|
PluginsMaxCount: DEFAULT_PLUGINS_MAX_COUNT,
|
||||||
ProfilesMaxCount: 256,
|
ProfilesMaxCount: DEFAULT_PROFILES_MAX_COUNT,
|
||||||
|
Timeout: DEFAULT_TIMEOUT_IN_SECS,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Init() sets up the default files and directories for the service
|
||||||
|
func (s *Service) Init() error {
|
||||||
|
// create the default directories
|
||||||
|
var err error
|
||||||
|
err = os.MkdirAll(s.RootPath, 0o777)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to make service root path: %v", err)
|
||||||
|
}
|
||||||
|
err = os.MkdirAll(s.PathForPlugins(), 0o777)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to make service plugin path: %v", err)
|
||||||
|
}
|
||||||
|
err = os.MkdirAll(s.PathForProfiles(), 0o777)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to make service profile path: %v", err)
|
||||||
|
}
|
||||||
|
err = os.MkdirAll(s.PathForData(), 0o777)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to make service profile path: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the default files
|
||||||
|
err = os.WriteFile(s.PathForMetadata(), []byte(DEFAULT_METADATA), 0o777)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to make service metadata file: %v", err)
|
||||||
|
}
|
||||||
|
err = os.WriteFile(s.PathForHome(), []byte(DEFAULT_HOME), 0o777)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to make service metadata file: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Serve() starts the configurator service and waits for requests.
|
// Serve() starts the configurator service and waits for requests.
|
||||||
func (s *Service) Serve() error {
|
func (s *Service) Serve() error {
|
||||||
router := chi.NewRouter()
|
router := chi.NewRouter()
|
||||||
|
|
@ -53,15 +86,16 @@ func (s *Service) Serve() error {
|
||||||
router.Use(middleware.Logger)
|
router.Use(middleware.Logger)
|
||||||
router.Use(middleware.Recoverer)
|
router.Use(middleware.Recoverer)
|
||||||
router.Use(middleware.StripSlashes)
|
router.Use(middleware.StripSlashes)
|
||||||
router.Use(middleware.Timeout(60 * time.Second))
|
router.Use(middleware.Timeout(s.Timeout * time.Second))
|
||||||
|
|
||||||
if s.requireAuth() {
|
if s.requireAuth() {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// general
|
// general
|
||||||
|
// router.Handle("/download/*", http.StripPrefix("/download/", http.FileServer(http.Dir(s.PathForData()))))
|
||||||
router.Get("/download/*", s.Download())
|
router.Get("/download/*", s.Download())
|
||||||
router.Post("/upload", s.Upload())
|
router.Post("/upload", s.Upload())
|
||||||
router.Get("/list", s.List())
|
router.Get("/list/*", s.List())
|
||||||
|
|
||||||
// profiles
|
// profiles
|
||||||
router.Get("/profiles", s.GetProfiles())
|
router.Get("/profiles", s.GetProfiles())
|
||||||
|
|
@ -76,14 +110,14 @@ func (s *Service) Serve() error {
|
||||||
// router.Get("/profile/{id}/paths/{path}", s.GetProfilePath())
|
// router.Get("/profile/{id}/paths/{path}", s.GetProfilePath())
|
||||||
|
|
||||||
// plugins
|
// plugins
|
||||||
router.Get("/plugins", s.GetPlugins())
|
router.Get("/plugins", s.ListPlugins())
|
||||||
router.Post("/plugins", s.CreatePlugins())
|
router.Post("/plugins", s.CreatePlugin())
|
||||||
router.Delete("/plugins/{id}", s.DeletePlugins())
|
router.Delete("/plugins/{id}", s.DeletePlugin())
|
||||||
}
|
}
|
||||||
|
|
||||||
// always available public routes go here
|
// always available public routes go here
|
||||||
router.HandleFunc("/status", s.GetStatus)
|
router.HandleFunc("/status", s.GetStatus)
|
||||||
return http.ListenAndServe(":8080", router)
|
return http.ListenAndServe(s.Addr, router)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) requireAuth() bool {
|
func (s *Service) requireAuth() bool {
|
||||||
|
|
@ -225,9 +259,34 @@ func saveToJSONFile[T any](path string, data T) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) PathForProfileWithID(id string) string {
|
func (s *Service) PathForProfileWithID(id string) string {
|
||||||
return s.RootPath + PROFILES_RELPATH + "/" + id
|
return s.RootPath + RELPATH_PROFILES + "/" + id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) PathForPluginWithName(name string) string {
|
||||||
|
return s.RootPath + RELPATH_PLUGINS + "/" + name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) PathForProfiles() string {
|
||||||
|
return s.RootPath + RELPATH_PROFILES + "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) PathForPlugins() string {
|
func (s *Service) PathForPlugins() string {
|
||||||
return s.RootPath + PLUGINS_RELPATH
|
return s.RootPath + RELPATH_PLUGINS + "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) PathForData() string {
|
||||||
|
return s.RootPath + RELPATH_DATA
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) PathForMetadata() string {
|
||||||
|
return s.RootPath + RELPATH_METADATA
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) PathForHome() string {
|
||||||
|
return s.RootPath + RELPATH_HELP
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) writeErrorResponse(w http.ResponseWriter, message string, code int) {
|
||||||
|
http.Error(w, message, code)
|
||||||
|
log.Error().Msg(message)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue