Add /config/:section endpoint
parent
17460e397b
commit
d0f63ca0e0
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue