Merge pull request #2686 from JanBerktold/enable-unauthenticated-monitoring

Add DRONE_PROMETHEUS_ANONYMOUS_ACCESS configuration option
This commit is contained in:
Brad Rydzewski 2019-04-25 18:08:56 -07:00 committed by GitHub
commit b7737a4a89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 56 additions and 25 deletions

View File

@ -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 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, 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). - 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 ## [1.1.0] - 2019-04-23
### Added ### Added

View File

@ -46,17 +46,17 @@ type (
Config struct { Config struct {
License string `envconfig:"DRONE_LICENSE"` License string `envconfig:"DRONE_LICENSE"`
Authn Authentication Authn Authentication
Agent Agent Agent Agent
Cron Cron Cron Cron
Cloning Cloning Cloning Cloning
Database Database Database Database
Datadog Datadog Datadog Datadog
Docker Docker Docker Docker
HTTP HTTP HTTP HTTP
Jsonnet Jsonnet Jsonnet Jsonnet
Logging Logging Logging Logging
// Prometheus Prometheus Prometheus Prometheus
Proxy Proxy Proxy Proxy
Registration Registration Registration Registration
Registries Registries Registries Registries
@ -162,6 +162,11 @@ type (
Text bool `envconfig:"DRONE_LOGS_TEXT"` 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 provides the repository configuration.
Repository struct { Repository struct {
Filter []string `envconfig:"DRONE_REPOSITORY_FILTER"` Filter []string `envconfig:"DRONE_REPOSITORY_FILTER"`

View File

@ -18,6 +18,7 @@ import (
"net/http" "net/http"
"github.com/drone/drone/cmd/drone-server/config" "github.com/drone/drone/cmd/drone-server/config"
"github.com/drone/drone/core"
"github.com/drone/drone/handler/api" "github.com/drone/drone/handler/api"
"github.com/drone/drone/handler/web" "github.com/drone/drone/handler/web"
"github.com/drone/drone/metric" "github.com/drone/drone/metric"
@ -33,9 +34,9 @@ import (
// wire set for loading the server. // wire set for loading the server.
var serverSet = wire.NewSet( var serverSet = wire.NewSet(
manager.New, manager.New,
metric.NewServer,
api.New, api.New,
web.New, web.New,
provideMetric,
provideRouter, provideRouter,
provideRPC, provideRPC,
provideServer, provideServer,
@ -53,6 +54,12 @@ func provideRouter(api api.Server, web web.Server, rpc http.Handler, metrics *me
return r 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 // provideRPC is a Wire provider function that returns an rpc
// handler that exposes the build manager to a remote agent. // handler that exposes the build manager to a remote agent.
func provideRPC(m manager.BuildManager, config config.Config) http.Handler { func provideRPC(m manager.BuildManager, config config.Config) http.Handler {

View File

@ -10,7 +10,6 @@ import (
"github.com/drone/drone/handler/api" "github.com/drone/drone/handler/api"
"github.com/drone/drone/handler/web" "github.com/drone/drone/handler/web"
"github.com/drone/drone/livelog" "github.com/drone/drone/livelog"
"github.com/drone/drone/metric"
"github.com/drone/drone/operator/manager" "github.com/drone/drone/operator/manager"
"github.com/drone/drone/pubsub" "github.com/drone/drone/pubsub"
"github.com/drone/drone/service/commit" "github.com/drone/drone/service/commit"
@ -93,7 +92,7 @@ func InitializeApplication(config2 config.Config) (application, error) {
options := provideServerOptions(config2) options := provideServerOptions(config2)
webServer := web.New(admissionService, buildStore, client, hookParser, coreLicense, licenseService, middleware, repositoryStore, session, syncer, triggerer, userStore, userService, webhookSender, options, system) webServer := web.New(admissionService, buildStore, client, hookParser, coreLicense, licenseService, middleware, repositoryStore, session, syncer, triggerer, userStore, userService, webhookSender, options, system)
handler := provideRPC(buildManager, config2) handler := provideRPC(buildManager, config2)
metricServer := metric.NewServer(session) metricServer := provideMetric(session, config2)
mux := provideRouter(server, webServer, handler, metricServer) mux := provideRouter(server, webServer, handler, metricServer)
serverServer := provideServer(mux, config2) serverServer := provideServer(mux, config2)
mainApplication := newApplication(cronScheduler, datadog, runner, serverServer, userStore) mainApplication := newApplication(cronScheduler, datadog, runner, serverServer, userStore)

View File

@ -24,15 +24,17 @@ var errAccessDenied = errors.New("Access denied")
// Server is an http Metrics server. // Server is an http Metrics server.
type Server struct { type Server struct {
metrics http.Handler metrics http.Handler
session core.Session session core.Session
anonymous bool
} }
// NewServer returns a new metrics server. // NewServer returns a new metrics server.
func NewServer(session core.Session) *Server { func NewServer(session core.Session, anonymous bool) *Server {
return &Server{ return &Server{
metrics: promhttp.Handler(), metrics: promhttp.Handler(),
session: session, session: session,
anonymous: anonymous,
} }
} }
@ -41,9 +43,9 @@ func NewServer(session core.Session) *Server {
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
user, _ := s.session.Get(r) user, _ := s.session.Get(r)
switch { switch {
case user == nil: case !s.anonymous && user == nil:
http.Error(w, errInvalidToken.Error(), 401) http.Error(w, errInvalidToken.Error(), 401)
case !user.Admin && !user.Machine: case !s.anonymous && !user.Admin && !user.Machine:
http.Error(w, errAccessDenied.Error(), 403) http.Error(w, errAccessDenied.Error(), 403)
default: default:
s.metrics.ServeHTTP(w, r) s.metrics.ServeHTTP(w, r)

View File

@ -26,7 +26,7 @@ func TestHandleMetrics(t *testing.T) {
session := mock.NewMockSession(controller) session := mock.NewMockSession(controller)
session.EXPECT().Get(r).Return(mockUser, nil) 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 { if got, want := w.Code, 200; got != want {
t.Errorf("Want status code %d, got %d", want, got) 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 := mock.NewMockSession(controller)
session.EXPECT().Get(r).Return(nil, nil) 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 { if got, want := w.Code, 401; got != want {
t.Errorf("Want status code %d, got %d", want, got) 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) { func TestHandleMetrics_AccessDenied(t *testing.T) {
controller := gomock.NewController(t) controller := gomock.NewController(t)
defer controller.Finish() defer controller.Finish()
@ -64,7 +81,7 @@ func TestHandleMetrics_AccessDenied(t *testing.T) {
session := mock.NewMockSession(controller) session := mock.NewMockSession(controller)
session.EXPECT().Get(r).Return(mockUser, nil) 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 { if got, want := w.Code, 403; got != want {
t.Errorf("Want status code %d, got %d", want, got) t.Errorf("Want status code %d, got %d", want, got)
} }