Add /config/:section endpoint

pull/10616/head
Michael Desa 2017-12-13 09:04:44 -08:00
parent 17460e397b
commit d0f63ca0e0
3 changed files with 146 additions and 0 deletions

View File

@ -1,8 +1,10 @@
package server
import (
"fmt"
"net/http"
"github.com/bouk/httprouter"
"github.com/influxdata/chronograf"
)
@ -20,6 +22,20 @@ func newConfigResponse(config chronograf.Config) *configResponse {
}
}
type authConfigResponse struct {
Links selfLinks `json:"links"`
chronograf.AuthConfig
}
func newAuthConfigResponse(config chronograf.Config) *authConfigResponse {
return &authConfigResponse{
Links: selfLinks{
Self: "/chronograf/v1/config/auth",
},
AuthConfig: config.Auth,
}
}
// Config retrieves the global application configuration
func (s *Service) Config(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
@ -37,3 +53,31 @@ func (s *Service) Config(w http.ResponseWriter, r *http.Request) {
res := newConfigResponse(*config)
encodeJSON(w, http.StatusOK, res, s.Logger)
}
// Config retrieves the global application configuration
func (s *Service) ConfigSection(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
config, err := s.Store.Config(ctx).Get(ctx)
if err != nil {
Error(w, http.StatusBadRequest, err.Error(), s.Logger)
return
}
if config == nil {
Error(w, http.StatusBadRequest, "Configuration object was nil", s.Logger)
return
}
section := httprouter.GetParamFromContext(ctx, "section")
var res interface{}
switch section {
case "auth":
res = newAuthConfigResponse(*config)
default:
Error(w, http.StatusBadRequest, fmt.Sprintf("received unknown section %q", section), s.Logger)
return
}
encodeJSON(w, http.StatusOK, res, s.Logger)
}

View File

@ -5,6 +5,7 @@ import (
"net/http/httptest"
"testing"
"github.com/bouk/httprouter"
"github.com/influxdata/chronograf"
"github.com/influxdata/chronograf/log"
"github.com/influxdata/chronograf/mocks"
@ -74,3 +75,103 @@ func TestConfig(t *testing.T) {
})
}
}
func TestConfigSection(t *testing.T) {
type fields struct {
ConfigStore chronograf.ConfigStore
}
type args struct {
section string
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "Get auth configuration",
fields: fields{
ConfigStore: &mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
SuperAdminFirstUserOnly: true,
},
},
},
},
args: args{
section: "auth",
},
wants: wants{
statusCode: 200,
contentType: "application/json",
body: `{"superAdminFirstUserOnly": true, "links": {"self": "/chronograf/v1/config/auth"}}`,
},
},
{
name: "Get unknown configuration",
fields: fields{
ConfigStore: &mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
SuperAdminFirstUserOnly: true,
},
},
},
},
args: args{
section: "unknown",
},
wants: wants{
statusCode: 400,
contentType: "application/json",
body: `{"code":400,"message":"received unknown section \"unknown\""}`,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &Service{
Store: &mocks.Store{
ConfigStore: tt.fields.ConfigStore,
},
Logger: log.New(log.DebugLevel),
}
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "http://any.url", nil)
r = r.WithContext(httprouter.WithParams(
r.Context(),
httprouter.Params{
{
Key: "section",
Value: tt.args.section,
},
}))
s.ConfigSection(w, r)
resp := w.Result()
content := resp.Header.Get("Content-Type")
body, _ := ioutil.ReadAll(resp.Body)
if resp.StatusCode != tt.wants.statusCode {
t.Errorf("%q. Config() = %v, want %v", tt.name, resp.StatusCode, tt.wants.statusCode)
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("%q. Config() = %v, want %v", tt.name, content, tt.wants.contentType)
}
if eq, _ := jsonEqual(string(body), tt.wants.body); tt.wants.body != "" && !eq {
t.Errorf("%q. Config() = \n***%v***\n,\nwant\n***%v***", tt.name, string(body), tt.wants.body)
}
})
}
}

View File

@ -239,6 +239,7 @@ func NewMux(opts MuxOpts, service Service) http.Handler {
// Global application config for Chronograf
router.GET("/chronograf/v1/config", EnsureSuperAdmin(service.Config))
router.GET("/chronograf/v1/config/:section", EnsureSuperAdmin(service.ConfigSection))
allRoutes := &AllRoutes{
Logger: opts.Logger,