diff --git a/api/handlers-settings.go b/api/handlers-settings.go index 91a29b33..a2d8bfe3 100644 --- a/api/handlers-settings.go +++ b/api/handlers-settings.go @@ -48,7 +48,7 @@ func apiSettingsServiceHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAPISettingsReq) utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAPI, settings.NoEnvironment), false) vars := mux.Vars(r) - // Extract environment + // Extract service service, ok := vars["service"] if !ok { apiErrorResponse(w, "error getting service", http.StatusInternalServerError, nil) @@ -83,6 +83,64 @@ func apiSettingsServiceHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAPISettingsOK) } +// GET Handler for service and environment specific settings excluding JSON +func apiSettingsServiceEnvHandler(w http.ResponseWriter, r *http.Request) { + incMetric(metricAPISettingsReq) + utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAPI, settings.NoEnvironment), false) + vars := mux.Vars(r) + // Extract service + service, ok := vars["service"] + if !ok { + apiErrorResponse(w, "error getting service", http.StatusInternalServerError, nil) + incMetric(metricAPISettingsErr) + return + } + // Make sure service is valid + if !settingsmgr.VerifyType(service) { + apiErrorResponse(w, "invalid service", http.StatusInternalServerError, nil) + incMetric(metricAPISettingsErr) + return + } + // Extract environment + envVar, ok := vars["env"] + if !ok { + apiErrorResponse(w, "error getting environment", http.StatusInternalServerError, nil) + incMetric(metricAPIEnvsErr) + return + } + // Get environment by name + env, err := envs.Get(envVar) + if err != nil { + if err.Error() == "record not found" { + apiErrorResponse(w, "environment not found", http.StatusNotFound, err) + } else { + apiErrorResponse(w, "error getting environment", http.StatusInternalServerError, err) + } + incMetric(metricAPIEnvsErr) + return + } + // Get context data and check access + ctx := r.Context().Value(contextKey(contextAPI)).(contextValue) + if !apiUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, env.UUID) { + apiErrorResponse(w, "no access", http.StatusForbidden, fmt.Errorf("attempt to use API by user %s", ctx[ctxUser])) + incMetric(metricAPISettingsErr) + return + } + // Get settings + serviceSettings, err := settingsmgr.RetrieveValues(service, false, settings.NoEnvironment) + if err != nil { + apiErrorResponse(w, "error getting settings", http.StatusInternalServerError, err) + incMetric(metricAPISettingsErr) + return + } + // Serialize and serve JSON + if settingsmgr.DebugService(settings.ServiceAPI) { + log.Println("DebugService: Returned settings") + } + utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, serviceSettings) + incMetric(metricAPISettingsOK) +} + // GET Handler for service specific settings including JSON func apiSettingsServiceJSONHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAPISettingsReq) @@ -122,3 +180,61 @@ func apiSettingsServiceJSONHandler(w http.ResponseWriter, r *http.Request) { utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, serviceSettings) incMetric(metricAPISettingsOK) } + +// GET Handler for service and environment specific settings including JSON +func apiSettingsServiceEnvJSONHandler(w http.ResponseWriter, r *http.Request) { + incMetric(metricAPISettingsReq) + utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAPI, settings.NoEnvironment), false) + vars := mux.Vars(r) + // Extract environment + service, ok := vars["service"] + if !ok { + apiErrorResponse(w, "error getting service", http.StatusInternalServerError, nil) + incMetric(metricAPISettingsErr) + return + } + // Make sure service is valid + if !settingsmgr.VerifyType(service) { + apiErrorResponse(w, "invalid service", http.StatusInternalServerError, nil) + incMetric(metricAPISettingsErr) + return + } + // Extract environment + envVar, ok := vars["env"] + if !ok { + apiErrorResponse(w, "error getting environment", http.StatusInternalServerError, nil) + incMetric(metricAPIEnvsErr) + return + } + // Get environment by name + env, err := envs.Get(envVar) + if err != nil { + if err.Error() == "record not found" { + apiErrorResponse(w, "environment not found", http.StatusNotFound, err) + } else { + apiErrorResponse(w, "error getting environment", http.StatusInternalServerError, err) + } + incMetric(metricAPIEnvsErr) + return + } + // Get context data and check access + ctx := r.Context().Value(contextKey(contextAPI)).(contextValue) + if !apiUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, env.UUID) { + apiErrorResponse(w, "no access", http.StatusForbidden, fmt.Errorf("attempt to use API by user %s", ctx[ctxUser])) + incMetric(metricAPISettingsErr) + return + } + // Get settings + serviceSettings, err := settingsmgr.RetrieveValues(service, true, settings.NoEnvironment) + if err != nil { + apiErrorResponse(w, "error getting settings", http.StatusInternalServerError, err) + incMetric(metricAPISettingsErr) + return + } + // Serialize and serve JSON + if settingsmgr.DebugService(settings.ServiceAPI) { + log.Println("DebugService: Returned settings") + } + utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, serviceSettings) + incMetric(metricAPISettingsOK) +} diff --git a/api/main.go b/api/main.go index 77578716..0fc5b32c 100644 --- a/api/main.go +++ b/api/main.go @@ -544,8 +544,12 @@ func osctrlAPIService() { routerAPI.Handle(_apiPath(apiSettingsPath)+"/", handlerAuthCheck(http.HandlerFunc(apiSettingsHandler))).Methods("GET") routerAPI.Handle(_apiPath(apiSettingsPath)+"/{service}", handlerAuthCheck(http.HandlerFunc(apiSettingsServiceHandler))).Methods("GET") routerAPI.Handle(_apiPath(apiSettingsPath)+"/{service}/", handlerAuthCheck(http.HandlerFunc(apiSettingsServiceHandler))).Methods("GET") + routerAPI.Handle(_apiPath(apiSettingsPath)+"/{service}/{env}", handlerAuthCheck(http.HandlerFunc(apiSettingsServiceEnvHandler))).Methods("GET") + routerAPI.Handle(_apiPath(apiSettingsPath)+"/{service}/{env}/", handlerAuthCheck(http.HandlerFunc(apiSettingsServiceEnvHandler))).Methods("GET") routerAPI.Handle(_apiPath(apiSettingsPath)+"/{service}/json", handlerAuthCheck(http.HandlerFunc(apiSettingsServiceJSONHandler))).Methods("GET") routerAPI.Handle(_apiPath(apiSettingsPath)+"/{service}/json/", handlerAuthCheck(http.HandlerFunc(apiSettingsServiceJSONHandler))).Methods("GET") + routerAPI.Handle(_apiPath(apiSettingsPath)+"/{service}/json/{env}", handlerAuthCheck(http.HandlerFunc(apiSettingsServiceEnvJSONHandler))).Methods("GET") + routerAPI.Handle(_apiPath(apiSettingsPath)+"/{service}/json/{env}/", handlerAuthCheck(http.HandlerFunc(apiSettingsServiceEnvJSONHandler))).Methods("GET") // Launch listeners for API server serviceListener := apiConfig.Listener + ":" + apiConfig.Port