-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
162 lines (134 loc) · 3.94 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// Package main starts the simple server on port and serves HTML,
// CSS, and JavaScript to clients.
package main
import (
"context"
"fmt"
"html/template"
"log"
"net/http"
"os"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
)
// templates parses the specified templates and caches the parsed results
// to help speed up response times.
var templates = template.Must(template.ParseFiles("./templates/base.html", "./templates/body.html"))
var labelSelector = "acend-userconfig=true"
var usernameKey = "username"
var passwordKey = "password"
var clusterName = "training"
var clusterDomain = "cluster.acend.ch"
var token = ""
type Trainee struct {
Username string
Password string
}
// logging is middleware for wrapping any handler we want to track response
// times for and to see what resources are requested.
func logging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
req := fmt.Sprintf("%s %s", r.Method, r.URL)
log.Println(req)
next.ServeHTTP(w, r)
log.Println(req, "completed in", time.Now().Sub(start))
})
}
// index is the handler responsible for rending the index page for the site.
func index(teacher bool) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println(r)
if !teacher {
t := r.URL.Query().Get("token")
if token != "" && t != token {
http.Error(w, fmt.Sprintf("you are not allowed to access this page"), http.StatusForbidden)
return
}
}
ctx := context.Background()
config := ctrl.GetConfigOrDie()
clientset := kubernetes.NewForConfigOrDie(config)
// Define the options to list secrets
listOptions := metav1.ListOptions{
LabelSelector: labelSelector,
}
secretList, err := clientset.CoreV1().Secrets("").List(ctx, listOptions)
if err != nil {
panic(err.Error())
}
var trainees []Trainee
for _, secret := range secretList.Items {
var trainee = Trainee{
Username: string(secret.Data[usernameKey]),
Password: string(secret.Data[passwordKey]),
}
trainees = append(trainees, trainee)
}
data := map[string]interface{}{
"clusterName": clusterName,
"clusterDomain": clusterDomain,
"trainees": trainees,
"teacher": teacher,
"token": token,
}
err2 := templates.ExecuteTemplate(w, "base", &data)
if err2 != nil {
http.Error(w, fmt.Sprintf("index: couldn't parse template: %v", err), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
})
}
// public serves static assets such as CSS and JavaScript to clients.
func public() http.Handler {
return http.StripPrefix("/public/", http.FileServer(http.Dir("./public")))
}
func health() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
}
func main() {
mux := http.NewServeMux()
mux.Handle("/health/", logging(health()))
mux.Handle("/public/", logging(public()))
mux.Handle("/", logging(index(false)))
mux.Handle("/teacher", logging(index(true)))
port, ok := os.LookupEnv("PORT")
if !ok {
port = "8080"
}
if ls := os.Getenv("LABEL_SELECTOR"); ls != "" {
labelSelector = ls
}
if unk := os.Getenv("SECRET_USERNAME_KEY"); unk != "" {
usernameKey = unk
}
if pwk := os.Getenv("SECRET_PASSWORD_KEY"); pwk != "" {
passwordKey = pwk
}
if cn := os.Getenv("CLUSTER_NAME"); cn != "" {
clusterName = cn
}
if t := os.Getenv("TOKEN"); t != "" {
token = t
}
if cd := os.Getenv("CLUSTER_DOMAIN"); cd != "" {
clusterDomain = cd
}
addr := fmt.Sprintf(":%s", port)
server := http.Server{
Addr: addr,
Handler: mux,
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
IdleTimeout: 15 * time.Second,
}
log.Println("main: running simple server on port", port)
if err := server.ListenAndServe(); err != nil {
log.Fatalf("main: couldn't start simple server: %v\n", err)
}
}