mirror of
				https://github.com/ClusterCockpit/cc-backend
				synced 2025-10-30 23:45:06 +01:00 
			
		
		
		
	Add buildInfo to frontend footer
This commit is contained in:
		| @@ -47,12 +47,12 @@ import ( | ||||
| ) | ||||
|  | ||||
| const logoString = ` | ||||
|  ____ _           _             ____           _          _ _    | ||||
| / ___| |_   _ ___| |_ ___ _ __ / ___|___   ___| | ___ __ (_) |_  | ||||
|  ____ _           _             ____           _          _ _ | ||||
| / ___| |_   _ ___| |_ ___ _ __ / ___|___   ___| | ___ __ (_) |_ | ||||
| | |   | | | | / __| __/ _ \ '__| |   / _ \ / __| |/ / '_ \| | __| | ||||
| | |___| | |_| \__ \ ||  __/ |  | |__| (_) | (__|   <| |_) | | |_  | ||||
| | |___| | |_| \__ \ ||  __/ |  | |__| (_) | (__|   <| |_) | | |_ | ||||
| \____|_|\__,_|___/\__\___|_|   \____\___/ \___|_|\_\ .__/|_|\__| | ||||
|                                                     |_|           | ||||
|                                                     |_| | ||||
| ` | ||||
|  | ||||
| var ( | ||||
| @@ -226,18 +226,19 @@ func main() { | ||||
| 	} | ||||
|  | ||||
| 	r := mux.NewRouter() | ||||
| 	buildInfo := web.Build{Version: version, Hash: hash, Buildtime: buildTime} | ||||
|  | ||||
| 	r.HandleFunc("/login", func(rw http.ResponseWriter, r *http.Request) { | ||||
| 		rw.Header().Add("Content-Type", "text/html; charset=utf-8") | ||||
| 		web.RenderTemplate(rw, r, "login.tmpl", &web.Page{Title: "Login"}) | ||||
| 		web.RenderTemplate(rw, r, "login.tmpl", &web.Page{Title: "Login", Build: buildInfo}) | ||||
| 	}).Methods(http.MethodGet) | ||||
| 	r.HandleFunc("/imprint", func(rw http.ResponseWriter, r *http.Request) { | ||||
| 		rw.Header().Add("Content-Type", "text/html; charset=utf-8") | ||||
| 		web.RenderTemplate(rw, r, "imprint.tmpl", &web.Page{Title: "Imprint"}) | ||||
| 		web.RenderTemplate(rw, r, "imprint.tmpl", &web.Page{Title: "Imprint", Build: buildInfo}) | ||||
| 	}) | ||||
| 	r.HandleFunc("/privacy", func(rw http.ResponseWriter, r *http.Request) { | ||||
| 		rw.Header().Add("Content-Type", "text/html; charset=utf-8") | ||||
| 		web.RenderTemplate(rw, r, "privacy.tmpl", &web.Page{Title: "Privacy"}) | ||||
| 		web.RenderTemplate(rw, r, "privacy.tmpl", &web.Page{Title: "Privacy", Build: buildInfo}) | ||||
| 	}) | ||||
|  | ||||
| 	// Some routes, such as /login or /query, should only be accessible to a user that is logged in. | ||||
| @@ -256,6 +257,7 @@ func main() { | ||||
| 				web.RenderTemplate(rw, r, "login.tmpl", &web.Page{ | ||||
| 					Title: "Login failed - ClusterCockpit", | ||||
| 					Error: err.Error(), | ||||
| 					Build: buildInfo, | ||||
| 				}) | ||||
| 			})).Methods(http.MethodPost) | ||||
|  | ||||
| @@ -265,6 +267,7 @@ func main() { | ||||
| 			web.RenderTemplate(rw, r, "login.tmpl", &web.Page{ | ||||
| 				Title: "Bye - ClusterCockpit", | ||||
| 				Info:  "Logout sucessful", | ||||
| 				Build: buildInfo, | ||||
| 			}) | ||||
| 		}))).Methods(http.MethodPost) | ||||
|  | ||||
| @@ -279,6 +282,7 @@ func main() { | ||||
| 					web.RenderTemplate(rw, r, "login.tmpl", &web.Page{ | ||||
| 						Title: "Authentication failed - ClusterCockpit", | ||||
| 						Error: err.Error(), | ||||
| 						Build: buildInfo, | ||||
| 					}) | ||||
| 				}) | ||||
| 		}) | ||||
| @@ -287,7 +291,7 @@ func main() { | ||||
| 	if flagDev { | ||||
| 		r.Handle("/playground", playground.Handler("GraphQL playground", "/query")) | ||||
| 		r.PathPrefix("/swagger/").Handler(httpSwagger.Handler( | ||||
| 			httpSwagger.URL("http://localhost:8080/swagger/doc.json"))).Methods(http.MethodGet) | ||||
| 		httpSwagger.URL("http://clustercockpit.localhost:8082/swagger/doc.json"))).Methods(http.MethodGet) | ||||
| 	} | ||||
| 	secured.Handle("/query", graphQLEndpoint) | ||||
|  | ||||
| @@ -316,7 +320,7 @@ func main() { | ||||
| 	}) | ||||
|  | ||||
| 	// Mount all /monitoring/... and /api/... routes. | ||||
| 	routerConfig.SetupRoutes(secured) | ||||
| 	routerConfig.SetupRoutes(secured, version, hash, buildTime) | ||||
| 	api.MountRoutes(secured) | ||||
|  | ||||
| 	if config.Keys.EmbedStaticFiles { | ||||
|   | ||||
| @@ -253,7 +253,7 @@ func buildFilterPresets(query url.Values) map[string]interface{} { | ||||
| 	return filterPresets | ||||
| } | ||||
|  | ||||
| func SetupRoutes(router *mux.Router) { | ||||
| func SetupRoutes(router *mux.Router, version string, hash string, buildTime string) { | ||||
| 	userCfgRepo := repository.GetUserCfgRepo() | ||||
| 	for _, route := range routes { | ||||
| 		route := route | ||||
| @@ -271,7 +271,7 @@ func SetupRoutes(router *mux.Router) { | ||||
| 			} | ||||
|  | ||||
| 			username, isAdmin, isSupporter := "", true, true | ||||
| 			 | ||||
|  | ||||
| 			if user := auth.GetUser(r.Context()); user != nil { | ||||
| 				username = user.Username | ||||
| 				isAdmin = user.HasRole(auth.RoleAdmin) | ||||
| @@ -281,6 +281,7 @@ func SetupRoutes(router *mux.Router) { | ||||
| 			page := web.Page{ | ||||
| 				Title:  title, | ||||
| 				User:   web.User{Username: username, IsAdmin: isAdmin, IsSupporter: isSupporter}, | ||||
| 				Build:  web.Build{Version: version, Hash: hash, Buildtime: buildTime}, | ||||
| 				Config: conf, | ||||
| 				Infos:  infos, | ||||
| 			} | ||||
|   | ||||
| @@ -52,3 +52,21 @@ footer { | ||||
|     margin: 0rem 0.8rem; | ||||
|     white-space: nowrap; | ||||
| } | ||||
|  | ||||
| .build-list { | ||||
| 		color: gray; | ||||
| 		font-size: 12px; | ||||
|     list-style-type: none; | ||||
|     padding-left: 0; | ||||
|     width: 100%; | ||||
|     display: flex; | ||||
|     flex-wrap: wrap; | ||||
|     justify-content: right; | ||||
|     margin-top: 0px; | ||||
|     margin-bottom: 5px; | ||||
| } | ||||
|  | ||||
| .build-list-item { | ||||
|     margin: 0rem 0.8rem; | ||||
|     white-space: nowrap; | ||||
| } | ||||
|   | ||||
| @@ -40,6 +40,11 @@ | ||||
|                     <li class="footer-list-item"><a class="link-secondary fs-5" href="/imprint" title="Imprint" rel="nofollow">Imprint</a></li> | ||||
|                     <li class="footer-list-item"><a class="link-secondary fs-5" href="/privacy" title="Privacy Policy" rel="nofollow">Privacy Policy</a></li> | ||||
|                 </ul> | ||||
|                 <ul class="build-list"> | ||||
|                   <li class="build-list-item">Version {{ .Build.Version }}</li> | ||||
|                   <li class="build-list-item">Hash {{ .Build.Hash }}</li> | ||||
|                   <li class="build-list-item">Built {{ .Build.Buildtime }}</li> | ||||
|                 </ul> | ||||
|             </footer> | ||||
|         {{end}} | ||||
|  | ||||
|   | ||||
| @@ -59,11 +59,18 @@ type User struct { | ||||
| 	IsSupporter bool | ||||
| } | ||||
|  | ||||
| type Build struct { | ||||
| 	Version string | ||||
| 	Hash string | ||||
| 	Buildtime string | ||||
| } | ||||
|  | ||||
| type Page struct { | ||||
| 	Title         string                 // Page title | ||||
| 	Error         string                 // For generic use (e.g. the exact error message on /login) | ||||
| 	Info          string                 // For generic use (e.g. "Logout successfull" on /login) | ||||
| 	User          User                   // Information about the currently logged in user | ||||
| 	Build         Build									 // Latest information about the application | ||||
| 	Clusters      []schema.ClusterConfig // List of all clusters for use in the Header | ||||
| 	FilterPresets map[string]interface{} // For pages with the Filter component, this can be used to set initial filters. | ||||
| 	Infos         map[string]interface{} // For generic use (e.g. username for /monitoring/user/<id>, job id for /monitoring/job/<id>) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user