refactor: initial commit for major rewrite
This commit is contained in:
parent
3253cb8bbb
commit
bfd83f35a3
45 changed files with 439 additions and 1733 deletions
184
pkg/service/profile.go
Normal file
184
pkg/service/profile.go
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
type Profile struct {
|
||||
ID string `json:"id"` // profile ID
|
||||
Description string `json:"description"` // profile description
|
||||
Tags []string `json:"tags"` // tags used for ...
|
||||
Paths []string `json:"paths"` // paths to download
|
||||
Plugins []string `json:"plugins"` // plugins to run
|
||||
Data map[string]any `json:"data"` // include render data
|
||||
}
|
||||
|
||||
func (s *Service) GetProfiles() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
path = s.RootPath + PROFILES_RELPATH
|
||||
profiles []*Profile
|
||||
contents []byte
|
||||
err error
|
||||
)
|
||||
|
||||
// walk profiles directory to load all profiles
|
||||
err = filepath.Walk(path, func(path string, info fs.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// skip directories
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// read file contents
|
||||
var profile *Profile
|
||||
profile, err = LoadProfile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
profiles = append(profiles, profile)
|
||||
|
||||
fmt.Println(path, info.Size())
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
// marshal and send all the profiles
|
||||
contents, err = json.Marshal(profiles)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to marshal profiles: %v", err), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
_, err = w.Write(contents)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// func (s *Service) CreateProfiles() http.HandlerFunc {
|
||||
// return func(w http.ResponseWriter, r *http.Request) {
|
||||
// var (
|
||||
// path = chi.URLParam(r, "path")
|
||||
// err error
|
||||
// )
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
func (s *Service) GetProfile() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
id = chi.URLParam(r, "id")
|
||||
path = s.BuildProfilePath(id)
|
||||
profile *Profile
|
||||
contents []byte
|
||||
err error
|
||||
)
|
||||
|
||||
profile, err = LoadProfile(path)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
contents, err = json.Marshal(profile)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = w.Write(contents)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) CreateProfile() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
type input struct {
|
||||
path string `json:"path"`
|
||||
profile *Profile `json:"profile"`
|
||||
}
|
||||
var (
|
||||
body []byte
|
||||
in input
|
||||
err error
|
||||
)
|
||||
|
||||
body, err = io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// use the request info to build profile
|
||||
err = json.Unmarshal(body, &in)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// create a new profile on disk
|
||||
os.WriteFile()
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) CreateProfileVar() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {}
|
||||
}
|
||||
|
||||
func (s *Service) DeleteProfileVar() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {}
|
||||
}
|
||||
|
||||
func (s *Service) GetProfileData() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {}
|
||||
}
|
||||
|
||||
func (s *Service) GetProfileVar() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {}
|
||||
}
|
||||
|
||||
func (s *Service) CreateProfilePath() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {}
|
||||
}
|
||||
|
||||
func (s *Service) DeleteProfilePath() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {}
|
||||
}
|
||||
|
||||
func (s *Service) GetProfilePath() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {}
|
||||
}
|
||||
|
||||
func (s *Service) GetPlugins() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {}
|
||||
}
|
||||
|
||||
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) {}
|
||||
}
|
||||
38
pkg/service/routes.go
Normal file
38
pkg/service/routes.go
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (s *Service) Download() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) Upload() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) List() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) GetStatus(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
data := map[string]any{
|
||||
"code": 200,
|
||||
"message": "Configurator is healthy",
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(data)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to encode JSON: %v\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
122
pkg/service/service.go
Normal file
122
pkg/service/service.go
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
configurator "git.towk2.me/towk/configurator/pkg"
|
||||
"github.com/go-chi/chi/middleware"
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
PLUGINS_RELPATH = "/plugins"
|
||||
TEMPLATES_RELPATH = "/templates"
|
||||
PROFILES_RELPATH = "/profiles"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
RootPath string `yaml:"root,omitempty"`
|
||||
Environment map[string]string
|
||||
|
||||
// max counts
|
||||
PluginsMaxCount int
|
||||
ProfilesMaxCount int
|
||||
}
|
||||
|
||||
// New creates the directories at specified path
|
||||
func New() *Service {
|
||||
return &Service{
|
||||
RootPath: ".",
|
||||
Environment: map[string]string{
|
||||
"CONFIGURATOR_HOST_URI": "",
|
||||
"ACCESS_TOKEN": "",
|
||||
},
|
||||
PluginsMaxCount: 64,
|
||||
ProfilesMaxCount: 256,
|
||||
}
|
||||
}
|
||||
|
||||
// Serve() starts the configurator service and waits for requests.
|
||||
func (s *Service) Serve() error {
|
||||
router := chi.NewRouter()
|
||||
router.Use(middleware.RequestID)
|
||||
router.Use(middleware.RealIP)
|
||||
router.Use(middleware.Logger)
|
||||
router.Use(middleware.Recoverer)
|
||||
router.Use(middleware.StripSlashes)
|
||||
router.Use(middleware.Timeout(60 * time.Second))
|
||||
|
||||
if s.requireAuth() {
|
||||
|
||||
} else {
|
||||
// general
|
||||
router.Get("/download", s.Download())
|
||||
router.Post("/upload", s.Upload())
|
||||
router.Get("/list", s.List())
|
||||
|
||||
// profiles
|
||||
router.Get("/profiles", s.GetProfiles())
|
||||
// router.Post("/profiles", s.CreateProfiles())
|
||||
router.Get("/profile/{id}", s.GetProfile())
|
||||
router.Post("/profile/{id}", s.CreateProfile())
|
||||
router.Post("/profile/{id}/data/{varname}", s.CreateProfileVar())
|
||||
router.Delete("/profile/{id}/data/{varname}", s.DeleteProfileVar())
|
||||
router.Get("/profile/{id}/data", s.GetProfileData())
|
||||
router.Get("/profile/{id}/data/{varname}", s.GetProfileVar())
|
||||
router.Post("/profile/{id}/paths/{path}", s.CreateProfilePath())
|
||||
router.Delete("/profile/{id}/paths/{path}", s.DeleteProfilePath())
|
||||
router.Get("/profile/{id}/paths/{path}", s.GetProfilePath())
|
||||
|
||||
// plugins
|
||||
router.Get("/plugins", s.GetPlugins())
|
||||
router.Post("/plugins", s.CreatePlugins())
|
||||
router.Delete("/plugins/{id}", s.DeletePlugins())
|
||||
}
|
||||
|
||||
// always available public routes go here
|
||||
router.HandleFunc("/status", s.GetStatus)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) requireAuth() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Service) FetchJwks(uri string) {
|
||||
|
||||
}
|
||||
|
||||
func LoadProfile(path string) (*Profile, error) {
|
||||
return LoadFromJSONFile[Profile](path)
|
||||
}
|
||||
|
||||
func LoadPlugin(path string) (*configurator.Plugin, error) {
|
||||
return LoadFromJSONFile[configurator.Plugin](path)
|
||||
}
|
||||
|
||||
func LoadFromJSONFile[T any](path string) (*T, error) {
|
||||
var (
|
||||
res *T
|
||||
contents []byte
|
||||
err error
|
||||
)
|
||||
|
||||
contents, err = os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read plugin file: %v", err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(contents, &res)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal plugin: %v", err)
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (s *Service) BuildProfilePath(id string) string {
|
||||
return s.RootPath + PLUGINS_RELPATH + "/" + id
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue