Skip to content

Commit

Permalink
Merge pull request #357 from jmpsec/api-settings-env
Browse files Browse the repository at this point in the history
Retrieve service settings via API
  • Loading branch information
javuto committed Nov 3, 2023
2 parents 87dc513 + 089ae84 commit d61207d
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 1 deletion.
118 changes: 117 additions & 1 deletion api/handlers-settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
4 changes: 4 additions & 0 deletions api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit d61207d

Please sign in to comment.