mirror of
https://github.com/outbackdingo/matchbox.git
synced 2026-01-27 10:19:35 +00:00
bootcfg/http: Replace capnslog with logrus
This commit is contained in:
@@ -44,7 +44,7 @@ func (s *Server) cloudHandler(core server.Server) ContextHandler {
|
||||
if group.Metadata != nil {
|
||||
err = json.Unmarshal(group.Metadata, &data)
|
||||
if err != nil {
|
||||
log.Errorf("error unmarshalling metadata: %v", err)
|
||||
s.logger.Errorf("error unmarshalling metadata: %v", err)
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
@@ -55,7 +55,7 @@ func (s *Server) cloudHandler(core server.Server) ContextHandler {
|
||||
|
||||
// render the template of a cloud config with data
|
||||
var buf bytes.Buffer
|
||||
err = renderTemplate(&buf, data, contents)
|
||||
err = s.renderTemplate(&buf, data, contents)
|
||||
if err != nil {
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
@@ -63,14 +63,14 @@ func (s *Server) cloudHandler(core server.Server) ContextHandler {
|
||||
|
||||
config := buf.String()
|
||||
if !cloudinit.IsCloudConfig(config) && !cloudinit.IsScript(config) {
|
||||
log.Error("error parsing user-data")
|
||||
s.logger.Error("error parsing user-data")
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
if cloudinit.IsCloudConfig(config) {
|
||||
if _, err = cloudinit.NewCloudConfig(config); err != nil {
|
||||
log.Errorf("error parsing cloud config: %v", err)
|
||||
s.logger.Errorf("error parsing cloud config: %v", err)
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
logtest "github.com/Sirupsen/logrus/hooks/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
@@ -32,7 +33,8 @@ coreos:
|
||||
Profiles: map[string]*storagepb.Profile{fake.Group.Profile: fake.Profile},
|
||||
CloudConfigs: map[string]string{fake.Profile.CloudId: content},
|
||||
}
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: store})
|
||||
h := srv.cloudHandler(c)
|
||||
ctx := withGroup(context.Background(), fake.Group)
|
||||
@@ -46,7 +48,8 @@ coreos:
|
||||
}
|
||||
|
||||
func TestCloudHandler_MissingCtxProfile(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: &fake.EmptyStore{}})
|
||||
h := srv.cloudHandler(c)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -56,7 +59,8 @@ func TestCloudHandler_MissingCtxProfile(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCloudHandler_MissingCloudConfig(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: &fake.EmptyStore{}})
|
||||
h := srv.cloudHandler(c)
|
||||
ctx := withProfile(context.Background(), fake.Profile)
|
||||
@@ -76,7 +80,8 @@ coreos:
|
||||
Profiles: map[string]*storagepb.Profile{fake.Group.Profile: fake.Profile},
|
||||
CloudConfigs: map[string]string{fake.Profile.CloudId: content},
|
||||
}
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: store})
|
||||
h := srv.cloudHandler(c)
|
||||
ctx := withGroup(context.Background(), fake.Group)
|
||||
|
||||
@@ -38,7 +38,7 @@ func (s *Server) genericHandler(core server.Server) ContextHandler {
|
||||
if group.Metadata != nil {
|
||||
err = json.Unmarshal(group.Metadata, &data)
|
||||
if err != nil {
|
||||
log.Errorf("error unmarshalling metadata: %v", err)
|
||||
s.logger.Errorf("error unmarshalling metadata: %v", err)
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
@@ -50,7 +50,7 @@ func (s *Server) genericHandler(core server.Server) ContextHandler {
|
||||
|
||||
// render the template of a generic config with data
|
||||
var buf bytes.Buffer
|
||||
err = renderTemplate(&buf, data, contents)
|
||||
err = s.renderTemplate(&buf, data, contents)
|
||||
if err != nil {
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
logtest "github.com/Sirupsen/logrus/hooks/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
@@ -26,7 +27,8 @@ SERVICE=etcd2
|
||||
Profiles: map[string]*storagepb.Profile{fake.Group.Profile: fake.Profile},
|
||||
GenericConfigs: map[string]string{fake.Profile.GenericId: content},
|
||||
}
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: store})
|
||||
h := srv.genericHandler(c)
|
||||
ctx := withGroup(context.Background(), fake.Group)
|
||||
@@ -40,7 +42,8 @@ SERVICE=etcd2
|
||||
}
|
||||
|
||||
func TestGenericHandler_MissingCtxProfile(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: &fake.EmptyStore{}})
|
||||
h := srv.genericHandler(c)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -50,7 +53,8 @@ func TestGenericHandler_MissingCtxProfile(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGenericHandler_MissingCloudConfig(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: &fake.EmptyStore{}})
|
||||
h := srv.genericHandler(c)
|
||||
ctx := withProfile(context.Background(), fake.Profile)
|
||||
@@ -68,7 +72,8 @@ KEY={{.missing_key}}
|
||||
Profiles: map[string]*storagepb.Profile{fake.Group.Profile: fake.Profile},
|
||||
GenericConfigs: map[string]string{fake.Profile.GenericId: content},
|
||||
}
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: store})
|
||||
h := srv.cloudHandler(c)
|
||||
ctx := withGroup(context.Background(), fake.Group)
|
||||
|
||||
@@ -20,7 +20,7 @@ initrdefi {{ range $element := .Initrd }}"{{$element}}" {{end}}
|
||||
|
||||
// grubHandler returns a handler which renders a GRUB2 config for the
|
||||
// requester.
|
||||
func grubHandler() ContextHandler {
|
||||
func (s *Server) grubHandler() ContextHandler {
|
||||
fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
profile, err := profileFromContext(ctx)
|
||||
if err != nil {
|
||||
@@ -30,12 +30,12 @@ func grubHandler() ContextHandler {
|
||||
var buf bytes.Buffer
|
||||
err = grubTemplate.Execute(&buf, profile.Boot)
|
||||
if err != nil {
|
||||
log.Errorf("error rendering template: %v", err)
|
||||
s.logger.Errorf("error rendering template: %v", err)
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
if _, err := buf.WriteTo(w); err != nil {
|
||||
log.Errorf("error writing to response: %v", err)
|
||||
s.logger.Errorf("error writing to response: %v", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,15 +23,6 @@ func requireGET(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(fn)
|
||||
}
|
||||
|
||||
// logRequest logs HTTP requests.
|
||||
func logRequest(next http.Handler) http.Handler {
|
||||
fn := func(w http.ResponseWriter, req *http.Request) {
|
||||
log.Debugf("HTTP %s %v", req.Method, req.URL)
|
||||
next.ServeHTTP(w, req)
|
||||
}
|
||||
return http.HandlerFunc(fn)
|
||||
}
|
||||
|
||||
// versionHandler shows the server name and version for root requests.
|
||||
// Otherwise, a 404 is returned.
|
||||
func versionHandler() http.Handler {
|
||||
@@ -45,12 +36,21 @@ func versionHandler() http.Handler {
|
||||
return http.HandlerFunc(fn)
|
||||
}
|
||||
|
||||
// logRequest logs HTTP requests.
|
||||
func (s *Server) logRequest(next http.Handler) http.Handler {
|
||||
fn := func(w http.ResponseWriter, req *http.Request) {
|
||||
s.logger.Debugf("HTTP %s %v", req.Method, req.URL)
|
||||
next.ServeHTTP(w, req)
|
||||
}
|
||||
return http.HandlerFunc(fn)
|
||||
}
|
||||
|
||||
// selectGroup selects the Group whose selectors match the query parameters,
|
||||
// adds the Group to the ctx, and calls the next handler. The next handler
|
||||
// should handle a missing Group.
|
||||
func selectGroup(core server.Server, next ContextHandler) ContextHandler {
|
||||
func (s *Server) selectGroup(core server.Server, next ContextHandler) ContextHandler {
|
||||
fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
attrs := labelsFromRequest(req)
|
||||
attrs := labelsFromRequest(s.logger, req)
|
||||
// match machine request
|
||||
group, err := core.SelectGroup(ctx, &pb.SelectGroupRequest{Labels: attrs})
|
||||
if err == nil {
|
||||
@@ -65,9 +65,9 @@ func selectGroup(core server.Server, next ContextHandler) ContextHandler {
|
||||
// selectProfile selects the Profile for the given query parameters, adds the
|
||||
// Profile to the ctx, and calls the next handler. The next handler should
|
||||
// handle a missing profile.
|
||||
func selectProfile(core server.Server, next ContextHandler) ContextHandler {
|
||||
func (s *Server) selectProfile(core server.Server, next ContextHandler) ContextHandler {
|
||||
fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
attrs := labelsFromRequest(req)
|
||||
attrs := labelsFromRequest(s.logger, req)
|
||||
// match machine request
|
||||
profile, err := core.SelectProfile(ctx, &pb.SelectProfileRequest{Labels: attrs})
|
||||
if err == nil {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
logtest "github.com/Sirupsen/logrus/hooks/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
@@ -42,7 +43,9 @@ func TestSelectGroup(t *testing.T) {
|
||||
store := &fake.FixedStore{
|
||||
Groups: map[string]*storagepb.Group{fake.Group.Id: fake.Group},
|
||||
}
|
||||
srv := server.NewServer(&server.Config{Store: store})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: store})
|
||||
next := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
group, err := groupFromContext(ctx)
|
||||
assert.Nil(t, err)
|
||||
@@ -53,7 +56,7 @@ func TestSelectGroup(t *testing.T) {
|
||||
// - query params are used to match uuid=a1b2c3d4 to fake.Group
|
||||
// - the fake.Group is added to the context
|
||||
// - next handler is called
|
||||
h := selectGroup(srv, ContextHandlerFunc(next))
|
||||
h := srv.selectGroup(c, ContextHandlerFunc(next))
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "?uuid=a1b2c3d4", nil)
|
||||
h.ServeHTTP(context.Background(), w, req)
|
||||
@@ -65,7 +68,9 @@ func TestSelectProfile(t *testing.T) {
|
||||
Groups: map[string]*storagepb.Group{fake.Group.Id: fake.Group},
|
||||
Profiles: map[string]*storagepb.Profile{fake.Group.Profile: fake.Profile},
|
||||
}
|
||||
srv := server.NewServer(&server.Config{Store: store})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: store})
|
||||
next := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
profile, err := profileFromContext(ctx)
|
||||
assert.Nil(t, err)
|
||||
@@ -76,7 +81,7 @@ func TestSelectProfile(t *testing.T) {
|
||||
// - query params are used to match uuid=a1b2c3d4 to fake.Group's fakeProfile
|
||||
// - the fake.Profile is added to the context
|
||||
// - next handler is called
|
||||
h := selectProfile(srv, ContextHandlerFunc(next))
|
||||
h := srv.selectProfile(c, ContextHandlerFunc(next))
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "?uuid=a1b2c3d4", nil)
|
||||
h.ServeHTTP(context.Background(), w, req)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
@@ -49,7 +50,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
|
||||
// labelsFromRequest returns request query parameters.
|
||||
func labelsFromRequest(req *http.Request) map[string]string {
|
||||
func labelsFromRequest(logger *logrus.Logger, req *http.Request) map[string]string {
|
||||
values := req.URL.Query()
|
||||
labels := map[string]string{}
|
||||
for key := range values {
|
||||
@@ -58,6 +59,9 @@ func labelsFromRequest(req *http.Request) map[string]string {
|
||||
// set mac if and only if it parses
|
||||
if hw, err := parseMAC(values.Get(key)); err == nil {
|
||||
labels[key] = hw.String()
|
||||
} else {
|
||||
// invalid MAC arguments may be common
|
||||
logger.Debugf("error parsing MAC address: %s", err)
|
||||
}
|
||||
default:
|
||||
// matchers don't use multi-value keys, drop later values
|
||||
@@ -71,8 +75,6 @@ func labelsFromRequest(req *http.Request) map[string]string {
|
||||
func parseMAC(s string) (net.HardwareAddr, error) {
|
||||
macAddr, err := net.ParseMAC(s)
|
||||
if err != nil {
|
||||
// invalid MAC arguments may be common
|
||||
log.Debugf("error parsing MAC address: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
return macAddr, err
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
logtest "github.com/Sirupsen/logrus/hooks/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
@@ -23,6 +24,7 @@ func TestNewHandler(t *testing.T) {
|
||||
|
||||
func TestLabelsFromRequest(t *testing.T) {
|
||||
emptyMap := map[string]string{}
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
cases := []struct {
|
||||
urlString string
|
||||
labels map[string]string
|
||||
@@ -41,6 +43,6 @@ func TestLabelsFromRequest(t *testing.T) {
|
||||
for _, c := range cases {
|
||||
req, err := http.NewRequest("GET", c.urlString, nil)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, c.labels, labelsFromRequest(req))
|
||||
assert.Equal(t, c.labels, labelsFromRequest(logger, req))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,9 +41,9 @@ func (s *Server) ignitionHandler(core server.Server) ContextHandler {
|
||||
if isIgnition(profile.IgnitionId) {
|
||||
_, err := ignition.Parse([]byte(contents))
|
||||
if err != nil {
|
||||
log.Warningf("warning parsing Ignition JSON: %v", err)
|
||||
s.logger.Warningf("warning parsing Ignition JSON: %v", err)
|
||||
}
|
||||
writeJSON(w, []byte(contents))
|
||||
s.writeJSON(w, []byte(contents))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ func (s *Server) ignitionHandler(core server.Server) ContextHandler {
|
||||
if group.Metadata != nil {
|
||||
err = json.Unmarshal(group.Metadata, &data)
|
||||
if err != nil {
|
||||
log.Errorf("error unmarshalling metadata: %v", err)
|
||||
s.logger.Errorf("error unmarshalling metadata: %v", err)
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
@@ -66,7 +66,7 @@ func (s *Server) ignitionHandler(core server.Server) ContextHandler {
|
||||
|
||||
// render the template for an Ignition config with data
|
||||
var buf bytes.Buffer
|
||||
err = renderTemplate(&buf, data, contents)
|
||||
err = s.renderTemplate(&buf, data, contents)
|
||||
if err != nil {
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
@@ -75,11 +75,11 @@ func (s *Server) ignitionHandler(core server.Server) ContextHandler {
|
||||
// Parse fuze config into an Ignition config
|
||||
config, err := fuze.ParseAsV2_0_0(buf.Bytes())
|
||||
if err == nil {
|
||||
renderJSON(w, config)
|
||||
s.renderJSON(w, config)
|
||||
return
|
||||
}
|
||||
|
||||
log.Errorf("error parsing Ignition config: %v", err)
|
||||
s.logger.Errorf("error parsing Ignition config: %v", err)
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
logtest "github.com/Sirupsen/logrus/hooks/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
@@ -28,7 +29,8 @@ func TestIgnitionHandler_V2JSON(t *testing.T) {
|
||||
Profiles: map[string]*storagepb.Profile{fake.Group.Profile: profile},
|
||||
IgnitionConfigs: map[string]string{"file.ign": content},
|
||||
}
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: store})
|
||||
h := srv.ignitionHandler(c)
|
||||
ctx := withGroup(context.Background(), fake.Group)
|
||||
@@ -57,7 +59,8 @@ systemd:
|
||||
Profiles: map[string]*storagepb.Profile{fake.Group.Profile: testProfileIgnitionYAML},
|
||||
IgnitionConfigs: map[string]string{testProfileIgnitionYAML.IgnitionId: content},
|
||||
}
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: store})
|
||||
h := srv.ignitionHandler(c)
|
||||
ctx := withGroup(context.Background(), fake.Group)
|
||||
@@ -74,7 +77,8 @@ systemd:
|
||||
}
|
||||
|
||||
func TestIgnitionHandler_MissingCtxProfile(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: &fake.EmptyStore{}})
|
||||
h := srv.ignitionHandler(c)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -84,7 +88,8 @@ func TestIgnitionHandler_MissingCtxProfile(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIgnitionHandler_MissingIgnitionConfig(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: &fake.EmptyStore{}})
|
||||
h := srv.ignitionHandler(c)
|
||||
ctx := withProfile(context.Background(), fake.Profile)
|
||||
@@ -106,7 +111,8 @@ systemd:
|
||||
Profiles: map[string]*storagepb.Profile{fake.Group.Profile: fake.Profile},
|
||||
IgnitionConfigs: map[string]string{fake.Profile.IgnitionId: content},
|
||||
}
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: store})
|
||||
h := srv.ignitionHandler(c)
|
||||
ctx := withGroup(context.Background(), fake.Group)
|
||||
|
||||
@@ -40,12 +40,12 @@ func (s *Server) ipxeHandler() ContextHandler {
|
||||
var buf bytes.Buffer
|
||||
err = ipxeTemplate.Execute(&buf, profile.Boot)
|
||||
if err != nil {
|
||||
log.Errorf("error rendering template: %v", err)
|
||||
s.logger.Errorf("error rendering template: %v", err)
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
if _, err := buf.WriteTo(w); err != nil {
|
||||
log.Errorf("error writing to response: %v", err)
|
||||
s.logger.Errorf("error writing to response: %v", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
logtest "github.com/Sirupsen/logrus/hooks/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
@@ -22,7 +23,8 @@ func TestIPXEInspect(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIPXEHandler(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
h := srv.ipxeHandler()
|
||||
ctx := withProfile(context.Background(), fake.Profile)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -40,7 +42,8 @@ boot
|
||||
}
|
||||
|
||||
func TestIPXEHandler_MissingCtxProfile(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
h := srv.ipxeHandler()
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/", nil)
|
||||
@@ -49,7 +52,8 @@ func TestIPXEHandler_MissingCtxProfile(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIPXEHandler_RenderTemplateError(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
h := srv.ipxeHandler()
|
||||
// a Profile with nil NetBoot forces a template.Execute error
|
||||
ctx := withProfile(context.Background(), &storagepb.Profile{Boot: nil})
|
||||
@@ -60,7 +64,8 @@ func TestIPXEHandler_RenderTemplateError(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIPXEHandler_WriteError(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
h := srv.ipxeHandler()
|
||||
ctx := withProfile(context.Background(), fake.Profile)
|
||||
w := NewUnwriteableResponseWriter()
|
||||
|
||||
@@ -24,7 +24,7 @@ func (s *Server) metadataHandler() ContextHandler {
|
||||
if group.Metadata != nil {
|
||||
err = json.Unmarshal(group.Metadata, &data)
|
||||
if err != nil {
|
||||
log.Errorf("error unmarshalling metadata: %v", err)
|
||||
s.logger.Errorf("error unmarshalling metadata: %v", err)
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
logtest "github.com/Sirupsen/logrus/hooks/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
@@ -15,7 +16,8 @@ import (
|
||||
)
|
||||
|
||||
func TestMetadataHandler(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
h := srv.metadataHandler()
|
||||
ctx := withGroup(context.Background(), fake.Group)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -36,7 +38,8 @@ func TestMetadataHandler(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMetadataHandler_MetadataEdgeCases(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
h := srv.metadataHandler()
|
||||
// groups with different metadata
|
||||
cases := []struct {
|
||||
@@ -64,7 +67,8 @@ func TestMetadataHandler_MetadataEdgeCases(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMetadataHandler_MissingCtxGroup(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
h := srv.metadataHandler()
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/", nil)
|
||||
|
||||
@@ -32,7 +32,7 @@ func (s *Server) pixiecoreHandler(core server.Server) ContextHandler {
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
renderJSON(w, profile.Boot)
|
||||
s.renderJSON(w, profile.Boot)
|
||||
}
|
||||
return ContextHandlerFunc(fn)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
logtest "github.com/Sirupsen/logrus/hooks/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
@@ -34,7 +35,8 @@ func TestPixiecoreHandler(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPixiecoreHandler_InvalidMACAddress(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: &fake.EmptyStore{}})
|
||||
h := srv.pixiecoreHandler(c)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -45,7 +47,8 @@ func TestPixiecoreHandler_InvalidMACAddress(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPixiecoreHandler_NoMatchingGroup(t *testing.T) {
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: &fake.EmptyStore{}})
|
||||
h := srv.pixiecoreHandler(c)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -58,7 +61,8 @@ func TestPixiecoreHandler_NoMatchingProfile(t *testing.T) {
|
||||
store := &fake.FixedStore{
|
||||
Groups: map[string]*storagepb.Group{fake.Group.Id: fake.Group},
|
||||
}
|
||||
srv := NewServer(&Config{})
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
c := server.NewServer(&server.Config{Store: store})
|
||||
h := srv.pixiecoreHandler(c)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
@@ -14,38 +14,38 @@ const (
|
||||
|
||||
// renderJSON encodes structs to JSON, writes the response to the
|
||||
// ResponseWriter, and logs encoding errors.
|
||||
func renderJSON(w http.ResponseWriter, v interface{}) {
|
||||
func (s *Server) renderJSON(w http.ResponseWriter, v interface{}) {
|
||||
js, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
log.Errorf("error JSON encoding: %v", err)
|
||||
s.logger.Errorf("error JSON encoding: %v", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
writeJSON(w, js)
|
||||
s.writeJSON(w, js)
|
||||
}
|
||||
|
||||
// writeJSON writes the given bytes with a JSON Content-Type.
|
||||
func writeJSON(w http.ResponseWriter, data []byte) {
|
||||
func (s *Server) writeJSON(w http.ResponseWriter, data []byte) {
|
||||
w.Header().Set(contentType, jsonContentType)
|
||||
_, err := w.Write(data)
|
||||
if err != nil {
|
||||
log.Errorf("error writing to response: %v", err)
|
||||
s.logger.Errorf("error writing to response: %v", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func renderTemplate(w io.Writer, data interface{}, contents ...string) (err error) {
|
||||
func (s *Server) renderTemplate(w io.Writer, data interface{}, contents ...string) (err error) {
|
||||
tmpl := template.New("").Option("missingkey=error")
|
||||
for _, content := range contents {
|
||||
tmpl, err = tmpl.Parse(content)
|
||||
if err != nil {
|
||||
log.Errorf("error parsing template: %v", err)
|
||||
s.logger.Errorf("error parsing template: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
err = tmpl.Execute(w, data)
|
||||
if err != nil {
|
||||
log.Errorf("error rendering template: %v", err)
|
||||
s.logger.Errorf("error rendering template: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -6,39 +6,48 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
logtest "github.com/Sirupsen/logrus/hooks/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRenderJSON(t *testing.T) {
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
w := httptest.NewRecorder()
|
||||
data := map[string][]string{
|
||||
"a": []string{"b", "c"},
|
||||
}
|
||||
renderJSON(w, data)
|
||||
srv.renderJSON(w, data)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, jsonContentType, w.HeaderMap.Get(contentType))
|
||||
assert.Equal(t, `{"a":["b","c"]}`, w.Body.String())
|
||||
}
|
||||
|
||||
func TestRenderJSON_EncodingError(t *testing.T) {
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
w := httptest.NewRecorder()
|
||||
// channels cannot be JSON encoded
|
||||
renderJSON(w, make(chan struct{}))
|
||||
srv.renderJSON(w, make(chan struct{}))
|
||||
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
assert.Empty(t, w.Body.String())
|
||||
}
|
||||
|
||||
func TestRenderJSON_EncodeError(t *testing.T) {
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
w := httptest.NewRecorder()
|
||||
// channels cannot be JSON encoded
|
||||
renderJSON(w, make(chan struct{}))
|
||||
srv.renderJSON(w, make(chan struct{}))
|
||||
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
assert.Empty(t, w.Body.String())
|
||||
}
|
||||
|
||||
func TestRenderJSON_WriteError(t *testing.T) {
|
||||
logger, _ := logtest.NewNullLogger()
|
||||
srv := NewServer(&Config{Logger: logger})
|
||||
w := NewUnwriteableResponseWriter()
|
||||
renderJSON(w, map[string]string{"a": "b"})
|
||||
srv.renderJSON(w, map[string]string{"a": "b"})
|
||||
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
assert.Empty(t, w.Body.String())
|
||||
}
|
||||
|
||||
@@ -3,17 +3,16 @@ package http
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/coreos/pkg/capnslog"
|
||||
"github.com/Sirupsen/logrus"
|
||||
|
||||
"github.com/coreos/coreos-baremetal/bootcfg/server"
|
||||
"github.com/coreos/coreos-baremetal/bootcfg/sign"
|
||||
)
|
||||
|
||||
var log = capnslog.NewPackageLogger("github.com/coreos/coreos-baremetal/bootcfg", "http")
|
||||
|
||||
// Config configures a Server.
|
||||
type Config struct {
|
||||
Core server.Server
|
||||
Core server.Server
|
||||
Logger *logrus.Logger
|
||||
// Path to static assets
|
||||
AssetsPath string
|
||||
// config signers (.sig and .asc)
|
||||
@@ -24,6 +23,7 @@ type Config struct {
|
||||
// Server serves boot and provisioning configs to machines via HTTP.
|
||||
type Server struct {
|
||||
core server.Server
|
||||
logger *logrus.Logger
|
||||
assetsPath string
|
||||
signer sign.Signer
|
||||
armoredSigner sign.Signer
|
||||
@@ -33,6 +33,7 @@ type Server struct {
|
||||
func NewServer(config *Config) *Server {
|
||||
return &Server{
|
||||
core: config.Core,
|
||||
logger: config.Logger,
|
||||
assetsPath: config.AssetsPath,
|
||||
signer: config.Signer,
|
||||
armoredSigner: config.ArmoredSigner,
|
||||
@@ -44,57 +45,57 @@ func (s *Server) HTTPHandler() http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
// bootcfg version
|
||||
mux.Handle("/", logRequest(versionHandler()))
|
||||
mux.Handle("/", s.logRequest(versionHandler()))
|
||||
// Boot via GRUB
|
||||
mux.Handle("/grub", logRequest(NewHandler(selectProfile(s.core, grubHandler()))))
|
||||
mux.Handle("/grub", s.logRequest(NewHandler(s.selectProfile(s.core, s.grubHandler()))))
|
||||
// Boot via iPXE
|
||||
mux.Handle("/boot.ipxe", logRequest(ipxeInspect()))
|
||||
mux.Handle("/boot.ipxe.0", logRequest(ipxeInspect()))
|
||||
mux.Handle("/ipxe", logRequest(NewHandler(selectProfile(s.core, s.ipxeHandler()))))
|
||||
mux.Handle("/boot.ipxe", s.logRequest(ipxeInspect()))
|
||||
mux.Handle("/boot.ipxe.0", s.logRequest(ipxeInspect()))
|
||||
mux.Handle("/ipxe", s.logRequest(NewHandler(s.selectProfile(s.core, s.ipxeHandler()))))
|
||||
// Boot via Pixiecore
|
||||
mux.Handle("/pixiecore/v1/boot/", logRequest(NewHandler(s.pixiecoreHandler(s.core))))
|
||||
mux.Handle("/pixiecore/v1/boot/", s.logRequest(NewHandler(s.pixiecoreHandler(s.core))))
|
||||
// Ignition Config
|
||||
mux.Handle("/ignition", logRequest(NewHandler(selectGroup(s.core, s.ignitionHandler(s.core)))))
|
||||
mux.Handle("/ignition", s.logRequest(NewHandler(s.selectGroup(s.core, s.ignitionHandler(s.core)))))
|
||||
// Cloud-Config
|
||||
mux.Handle("/cloud", logRequest(NewHandler(selectGroup(s.core, s.cloudHandler(s.core)))))
|
||||
mux.Handle("/cloud", s.logRequest(NewHandler(s.selectGroup(s.core, s.cloudHandler(s.core)))))
|
||||
// Generic template
|
||||
mux.Handle("/generic", logRequest(NewHandler(selectGroup(s.core, s.genericHandler(s.core)))))
|
||||
// metadata
|
||||
mux.Handle("/metadata", logRequest(NewHandler(selectGroup(s.core, s.metadataHandler()))))
|
||||
mux.Handle("/generic", s.logRequest(NewHandler(s.selectGroup(s.core, s.genericHandler(s.core)))))
|
||||
// Metadata
|
||||
mux.Handle("/metadata", s.logRequest(NewHandler(s.selectGroup(s.core, s.metadataHandler()))))
|
||||
|
||||
// Signatures
|
||||
if s.signer != nil {
|
||||
signerChain := func(next http.Handler) http.Handler {
|
||||
return logRequest(sign.SignatureHandler(s.signer, next))
|
||||
return s.logRequest(sign.SignatureHandler(s.signer, next))
|
||||
}
|
||||
mux.Handle("/grub.sig", signerChain(NewHandler(selectProfile(s.core, grubHandler()))))
|
||||
mux.Handle("/grub.sig", signerChain(NewHandler(s.selectProfile(s.core, s.grubHandler()))))
|
||||
mux.Handle("/boot.ipxe.sig", signerChain(ipxeInspect()))
|
||||
mux.Handle("/boot.ipxe.0.sig", signerChain(ipxeInspect()))
|
||||
mux.Handle("/ipxe.sig", signerChain(NewHandler(selectProfile(s.core, s.ipxeHandler()))))
|
||||
mux.Handle("/ipxe.sig", signerChain(NewHandler(s.selectProfile(s.core, s.ipxeHandler()))))
|
||||
mux.Handle("/pixiecore/v1/boot.sig/", signerChain(NewHandler(s.pixiecoreHandler(s.core))))
|
||||
mux.Handle("/ignition.sig", signerChain(NewHandler(selectGroup(s.core, s.ignitionHandler(s.core)))))
|
||||
mux.Handle("/cloud.sig", signerChain(NewHandler(selectGroup(s.core, s.cloudHandler(s.core)))))
|
||||
mux.Handle("/generic.sig", signerChain(NewHandler(selectGroup(s.core, s.genericHandler(s.core)))))
|
||||
mux.Handle("/metadata.sig", signerChain(NewHandler(selectGroup(s.core, s.metadataHandler()))))
|
||||
mux.Handle("/ignition.sig", signerChain(NewHandler(s.selectGroup(s.core, s.ignitionHandler(s.core)))))
|
||||
mux.Handle("/cloud.sig", signerChain(NewHandler(s.selectGroup(s.core, s.cloudHandler(s.core)))))
|
||||
mux.Handle("/generic.sig", signerChain(NewHandler(s.selectGroup(s.core, s.genericHandler(s.core)))))
|
||||
mux.Handle("/metadata.sig", signerChain(NewHandler(s.selectGroup(s.core, s.metadataHandler()))))
|
||||
}
|
||||
if s.armoredSigner != nil {
|
||||
signerChain := func(next http.Handler) http.Handler {
|
||||
return logRequest(sign.SignatureHandler(s.armoredSigner, next))
|
||||
return s.logRequest(sign.SignatureHandler(s.armoredSigner, next))
|
||||
}
|
||||
mux.Handle("/grub.asc", signerChain(NewHandler(selectProfile(s.core, grubHandler()))))
|
||||
mux.Handle("/grub.asc", signerChain(NewHandler(s.selectProfile(s.core, s.grubHandler()))))
|
||||
mux.Handle("/boot.ipxe.asc", signerChain(ipxeInspect()))
|
||||
mux.Handle("/boot.ipxe.0.asc", signerChain(ipxeInspect()))
|
||||
mux.Handle("/ipxe.asc", signerChain(NewHandler(selectProfile(s.core, s.ipxeHandler()))))
|
||||
mux.Handle("/ipxe.asc", signerChain(NewHandler(s.selectProfile(s.core, s.ipxeHandler()))))
|
||||
mux.Handle("/pixiecore/v1/boot.asc/", signerChain(NewHandler(s.pixiecoreHandler(s.core))))
|
||||
mux.Handle("/ignition.asc", signerChain(NewHandler(selectGroup(s.core, s.ignitionHandler(s.core)))))
|
||||
mux.Handle("/cloud.asc", signerChain(NewHandler(selectGroup(s.core, s.cloudHandler(s.core)))))
|
||||
mux.Handle("/generic.asc", signerChain(NewHandler(selectGroup(s.core, s.genericHandler(s.core)))))
|
||||
mux.Handle("/metadata.asc", signerChain(NewHandler(selectGroup(s.core, s.metadataHandler()))))
|
||||
mux.Handle("/ignition.asc", signerChain(NewHandler(s.selectGroup(s.core, s.ignitionHandler(s.core)))))
|
||||
mux.Handle("/cloud.asc", signerChain(NewHandler(s.selectGroup(s.core, s.cloudHandler(s.core)))))
|
||||
mux.Handle("/generic.asc", signerChain(NewHandler(s.selectGroup(s.core, s.genericHandler(s.core)))))
|
||||
mux.Handle("/metadata.asc", signerChain(NewHandler(s.selectGroup(s.core, s.metadataHandler()))))
|
||||
}
|
||||
|
||||
// kernel, initrd, and TLS assets
|
||||
if s.assetsPath != "" {
|
||||
mux.Handle("/assets/", logRequest(http.StripPrefix("/assets/", http.FileServer(http.Dir(s.assetsPath)))))
|
||||
mux.Handle("/assets/", s.logRequest(http.StripPrefix("/assets/", http.FileServer(http.Dir(s.assetsPath)))))
|
||||
}
|
||||
return mux
|
||||
}
|
||||
|
||||
@@ -7,9 +7,8 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/pkg/capnslog"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/coreos/pkg/flagutil"
|
||||
|
||||
web "github.com/coreos/coreos-baremetal/bootcfg/http"
|
||||
@@ -22,7 +21,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
log = capnslog.NewPackageLogger("github.com/coreos/coreos-baremetal/cmd/bootcfg", "main")
|
||||
// Defaults to info logging
|
||||
log = logrus.New()
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -44,7 +44,7 @@ func main() {
|
||||
flag.StringVar(&flags.dataPath, "data-path", "/var/lib/bootcfg", "Path to data directory")
|
||||
flag.StringVar(&flags.assetsPath, "assets-path", "/var/lib/bootcfg/assets", "Path to static assets")
|
||||
|
||||
// Log levels https://godoc.org/github.com/coreos/pkg/capnslog#LogLevel
|
||||
// Log levels https://github.com/Sirupsen/logrus/blob/master/logrus.go#L36
|
||||
flag.StringVar(&flags.logLevel, "log-level", "info", "Set the logging level")
|
||||
|
||||
// gRPC Server TLS
|
||||
@@ -103,12 +103,11 @@ func main() {
|
||||
}
|
||||
|
||||
// logging setup
|
||||
lvl, err := capnslog.ParseLevel(strings.ToUpper(flags.logLevel))
|
||||
lvl, err := logrus.ParseLevel(flags.logLevel)
|
||||
if err != nil {
|
||||
log.Fatalf("invalid log-level: %v", err)
|
||||
}
|
||||
capnslog.SetGlobalLogLevel(lvl)
|
||||
capnslog.SetFormatter(capnslog.NewPrettyFormatter(os.Stdout, false))
|
||||
log.Level = lvl
|
||||
|
||||
// (optional) signing
|
||||
var signer, armoredSigner sign.Signer
|
||||
@@ -158,6 +157,7 @@ func main() {
|
||||
// HTTP Server
|
||||
config := &web.Config{
|
||||
Core: server,
|
||||
Logger: log,
|
||||
AssetsPath: flags.assetsPath,
|
||||
Signer: signer,
|
||||
ArmoredSigner: armoredSigner,
|
||||
|
||||
Reference in New Issue
Block a user