blob: c59ef2bfc2e66a443c9fd98edb67403bdf1942c3 [file] [log] [blame]
Giorgi Lekveishvili970316a2023-11-08 13:07:35 +04001package apprepo
2
3import (
4 "fmt"
5 "io"
6 "net/http"
7
8 "github.com/gorilla/mux"
9 "sigs.k8s.io/yaml"
10)
11
12type App interface {
13 Name() string
14 Version() string
15 Reader() (io.ReadCloser, error)
16}
17
18type Server struct {
19 schemeWithHost string
20 port int
21 apps []App
22}
23
24func NewServer(schemeWithHost string, port int, apps []App) *Server {
25 return &Server{schemeWithHost, port, apps}
26}
27
28func (s *Server) Start() error {
29 r := mux.NewRouter()
30 r.Path("/").Methods("GET").HandlerFunc(s.allApps)
31 r.Path("/app/{name}/{version}.tar.gz").Methods("GET").HandlerFunc(s.app)
32 http.Handle("/", r)
33 return http.ListenAndServe(fmt.Sprintf(":%d", s.port), nil)
34}
35
36func (s *Server) allApps(w http.ResponseWriter, r *http.Request) {
37 entries := make(map[string][]map[string]any)
38 for _, a := range s.apps {
39 e, ok := entries[a.Name()]
40 if !ok {
41 e = make([]map[string]any, 0)
42 }
43 e = append(e, map[string]any{
44 "version": a.Version(),
45 "urls": []string{fmt.Sprintf("%s/%s/%s.tar.gz", s.schemeWithHost, a.Name(), a.Version())},
46 })
47 entries[a.Name()] = e
48 }
49 resp := map[string]any{
50 "apiVersion": "v1",
51 "entries": entries,
52 }
53 b, err := yaml.Marshal(resp)
54 if err != nil {
55 http.Error(w, err.Error(), http.StatusInternalServerError)
56 return
57 }
58 w.Write(b)
59}
60
61func (s *Server) app(w http.ResponseWriter, r *http.Request) {
62 vars := mux.Vars(r)
63 name := vars["name"]
64 version := vars["version"]
65 for _, a := range s.apps {
66 if a.Name() == name && a.Version() == version {
67 r, err := a.Reader()
68 if err != nil {
69 http.Error(w, err.Error(), http.StatusInternalServerError)
70 return
71 }
72 defer r.Close()
73 io.Copy(w, r)
74 return
75 }
76 }
77 http.Error(w, "Not found", http.StatusNotFound)
78}