diff --git a/CHANGELOG.md b/CHANGELOG.md index 72de277b..33839130 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - endpoint to trigger new build for default branch, by [@bradrydzewski](https://github.com/bradrydzewski). [#2679](https://github.com/drone/drone/issues/2679). - endpoint to trigger new build for branch, by [@bradrydzewski](https://github.com/bradrydzewski). [#2679](https://github.com/drone/drone/issues/2679). - endpoint to trigger new build for branch and sha, by [@bradrydzewski](https://github.com/bradrydzewski). [#2679](https://github.com/drone/drone/issues/2679). - +- DRONE_PROMETHEUS_ANONYMOUS_ACCESS configuration option, by [@janberktold](https://github.com/janberktold) +- ## [1.1.0] - 2019-04-23 ### Added diff --git a/cmd/drone-server/config/config.go b/cmd/drone-server/config/config.go index e77a61df..3cdd4bfc 100644 --- a/cmd/drone-server/config/config.go +++ b/cmd/drone-server/config/config.go @@ -46,17 +46,17 @@ type ( Config struct { License string `envconfig:"DRONE_LICENSE"` - Authn Authentication - Agent Agent - Cron Cron - Cloning Cloning - Database Database - Datadog Datadog - Docker Docker - HTTP HTTP - Jsonnet Jsonnet - Logging Logging - // Prometheus Prometheus + Authn Authentication + Agent Agent + Cron Cron + Cloning Cloning + Database Database + Datadog Datadog + Docker Docker + HTTP HTTP + Jsonnet Jsonnet + Logging Logging + Prometheus Prometheus Proxy Proxy Registration Registration Registries Registries @@ -162,6 +162,11 @@ type ( Text bool `envconfig:"DRONE_LOGS_TEXT"` } + // Prometheus provides the prometheus configuration. + Prometheus struct { + EnableAnonymousAccess bool `envconfig:"DRONE_PROMETHEUS_ANONYMOUS_ACCESS" default:"false"` + } + // Repository provides the repository configuration. Repository struct { Filter []string `envconfig:"DRONE_REPOSITORY_FILTER"` diff --git a/cmd/drone-server/inject_server.go b/cmd/drone-server/inject_server.go index da2fbee7..3acd3942 100644 --- a/cmd/drone-server/inject_server.go +++ b/cmd/drone-server/inject_server.go @@ -18,6 +18,7 @@ import ( "net/http" "github.com/drone/drone/cmd/drone-server/config" + "github.com/drone/drone/core" "github.com/drone/drone/handler/api" "github.com/drone/drone/handler/web" "github.com/drone/drone/metric" @@ -33,9 +34,9 @@ import ( // wire set for loading the server. var serverSet = wire.NewSet( manager.New, - metric.NewServer, api.New, web.New, + provideMetric, provideRouter, provideRPC, provideServer, @@ -53,6 +54,12 @@ func provideRouter(api api.Server, web web.Server, rpc http.Handler, metrics *me return r } +// provideMetric is a Wire provider function that returns the +// metrics server exposing metrics in prometheus format. +func provideMetric(session core.Session, config config.Config) *metric.Server { + return metric.NewServer(session, config.Prometheus.EnableAnonymousAccess) +} + // provideRPC is a Wire provider function that returns an rpc // handler that exposes the build manager to a remote agent. func provideRPC(m manager.BuildManager, config config.Config) http.Handler { diff --git a/cmd/drone-server/wire_gen.go b/cmd/drone-server/wire_gen.go index 415edb57..5b473eb7 100644 --- a/cmd/drone-server/wire_gen.go +++ b/cmd/drone-server/wire_gen.go @@ -10,7 +10,6 @@ import ( "github.com/drone/drone/handler/api" "github.com/drone/drone/handler/web" "github.com/drone/drone/livelog" - "github.com/drone/drone/metric" "github.com/drone/drone/operator/manager" "github.com/drone/drone/pubsub" "github.com/drone/drone/service/commit" @@ -93,7 +92,7 @@ func InitializeApplication(config2 config.Config) (application, error) { options := provideServerOptions(config2) webServer := web.New(admissionService, buildStore, client, hookParser, coreLicense, licenseService, middleware, repositoryStore, session, syncer, triggerer, userStore, userService, webhookSender, options, system) handler := provideRPC(buildManager, config2) - metricServer := metric.NewServer(session) + metricServer := provideMetric(session, config2) mux := provideRouter(server, webServer, handler, metricServer) serverServer := provideServer(mux, config2) mainApplication := newApplication(cronScheduler, datadog, runner, serverServer, userStore) diff --git a/metric/handler.go b/metric/handler.go index 66c5ef7f..724e3b42 100644 --- a/metric/handler.go +++ b/metric/handler.go @@ -24,15 +24,17 @@ var errAccessDenied = errors.New("Access denied") // Server is an http Metrics server. type Server struct { - metrics http.Handler - session core.Session + metrics http.Handler + session core.Session + anonymous bool } // NewServer returns a new metrics server. -func NewServer(session core.Session) *Server { +func NewServer(session core.Session, anonymous bool) *Server { return &Server{ - metrics: promhttp.Handler(), - session: session, + metrics: promhttp.Handler(), + session: session, + anonymous: anonymous, } } @@ -41,9 +43,9 @@ func NewServer(session core.Session) *Server { func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { user, _ := s.session.Get(r) switch { - case user == nil: + case !s.anonymous && user == nil: http.Error(w, errInvalidToken.Error(), 401) - case !user.Admin && !user.Machine: + case !s.anonymous && !user.Admin && !user.Machine: http.Error(w, errAccessDenied.Error(), 403) default: s.metrics.ServeHTTP(w, r) diff --git a/metric/handler_test.go b/metric/handler_test.go index 27892aaf..2931e135 100644 --- a/metric/handler_test.go +++ b/metric/handler_test.go @@ -26,7 +26,7 @@ func TestHandleMetrics(t *testing.T) { session := mock.NewMockSession(controller) session.EXPECT().Get(r).Return(mockUser, nil) - NewServer(session).ServeHTTP(w, r) + NewServer(session, false).ServeHTTP(w, r) if got, want := w.Code, 200; got != want { t.Errorf("Want status code %d, got %d", want, got) } @@ -46,13 +46,30 @@ func TestHandleMetrics_NoSession(t *testing.T) { session := mock.NewMockSession(controller) session.EXPECT().Get(r).Return(nil, nil) - NewServer(session).ServeHTTP(w, r) + NewServer(session, false).ServeHTTP(w, r) if got, want := w.Code, 401; got != want { t.Errorf("Want status code %d, got %d", want, got) } } +func TestHandleMetrics_NoSessionButAnonymousAccessEnabled(t *testing.T) { + controller := gomock.NewController(t) + defer controller.Finish() + + w := httptest.NewRecorder() + r := httptest.NewRequest("GET", "/", nil) + + session := mock.NewMockSession(controller) + session.EXPECT().Get(r).Return(nil, nil) + + NewServer(session, true).ServeHTTP(w, r) + + if got, want := w.Code, 200; got != want { + t.Errorf("Want status code %d, got %d", want, got) + } +} + func TestHandleMetrics_AccessDenied(t *testing.T) { controller := gomock.NewController(t) defer controller.Finish() @@ -64,7 +81,7 @@ func TestHandleMetrics_AccessDenied(t *testing.T) { session := mock.NewMockSession(controller) session.EXPECT().Get(r).Return(mockUser, nil) - NewServer(session).ServeHTTP(w, r) + NewServer(session, false).ServeHTTP(w, r) if got, want := w.Code, 403; got != want { t.Errorf("Want status code %d, got %d", want, got) }