fix regression with rpc v1 client
This commit is contained in:
commit
b52456f652
14 changed files with 137 additions and 55 deletions
|
@ -10,6 +10,11 @@ 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).
|
||||
- enable optional prometheus metrics guest access, by [@janberktold](https://github.com/janberktold)
|
||||
|
||||
### Fixed
|
||||
|
||||
- retrieve latest build by branch, by [@tboerger](https://github.com/tboerger).
|
||||
|
||||
### Fixed
|
||||
|
||||
|
@ -21,8 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- specify a user for the pipeline step, by [@bradrydzewski](https://github.com/bradrydzewski). [#2651](https://github.com/drone/drone/issues/2651).
|
||||
- support for Gitea oauth2, by [@techknowlogick](https://github.com/techknowlogick). [#2622](https://github.com/drone/drone/pull/2622).
|
||||
- ping the docker daemon before starting the agent, by [@bradrydzewski](https://github.com/bradrydzewski). [#2495](https://github.com/drone/drone/issues/2495).
|
||||
- support for Cron job name in Yaml trigger block, by [@bradrydzewski](https://github.com/bradrydzewski). [#2628](https://github.com/drone/drone/issues/2628).
|
||||
- support for Cron job name in Yaml when block, by [@bradrydzewski](https://github.com/bradrydzewski). [#2628](https://github.com/drone/drone/issues/2628).
|
||||
- support for Cron job name in Yaml trigger block, by [@bradrydzewski](https://github.com/bradrydzewski). [#2628](https://github.com/drone/drone/issues/2628).
|
||||
- support for Cron job name in Yaml when block, by [@bradrydzewski](https://github.com/bradrydzewski). [#2628](https://github.com/drone/drone/issues/2628).
|
||||
- sqlite username column changed to case-insensitive, by [@bradrydzewski](https://github.com/bradrydzewski).
|
||||
- endpoint to purge repository from database, by [@bradrydzewski](https://github.com/bradrydzewski).
|
||||
- support for per-organization secrets, by [@bradrydzewski](https://github.com/bradrydzewski).
|
||||
|
|
|
@ -8,6 +8,7 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"time"
|
||||
|
||||
"github.com/drone/drone-runtime/engine/docker"
|
||||
|
@ -20,13 +21,20 @@ import (
|
|||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var envfile string
|
||||
flag.StringVar(&envfile, "env-file", ".env", "Read in a file of environment variables")
|
||||
flag.Parse()
|
||||
|
||||
godotenv.Load(envfile)
|
||||
config, err := config.Environ()
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatalln("invalid configuration")
|
||||
logger := logrus.WithError(err)
|
||||
logger.Fatalln("invalid configuration")
|
||||
}
|
||||
|
||||
initLogging(config)
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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"
|
||||
|
@ -31,12 +32,19 @@ import (
|
|||
"github.com/unrolled/secure"
|
||||
)
|
||||
|
||||
type (
|
||||
healthzHandler http.Handler
|
||||
metricsHandler http.Handler
|
||||
rpcHandlerV1 http.Handler
|
||||
rpcHandlerV2 http.Handler
|
||||
)
|
||||
|
||||
// wire set for loading the server.
|
||||
var serverSet = wire.NewSet(
|
||||
manager.New,
|
||||
metric.NewServer,
|
||||
api.New,
|
||||
web.New,
|
||||
provideMetric,
|
||||
provideRouter,
|
||||
provideRPC,
|
||||
provideRPC2,
|
||||
|
@ -46,26 +54,34 @@ var serverSet = wire.NewSet(
|
|||
|
||||
// provideRouter is a Wire provider function that returns a
|
||||
// router that is serves the provided handlers.
|
||||
func provideRouter(api api.Server, web web.Server, rpc http.Handler, rpcv2 rpc2.Server, metrics *metric.Server) *chi.Mux {
|
||||
func provideRouter(api api.Server, web web.Server, rpcv1 rpcHandlerV1, rpcv2 rpcHandlerV2, metrics *metric.Server) *chi.Mux {
|
||||
r := chi.NewRouter()
|
||||
r.Mount("/metrics", metrics)
|
||||
r.Mount("/api", api.Handler())
|
||||
r.Mount("/rpc/v2", rpcv2)
|
||||
r.Mount("/rpc", rpc)
|
||||
r.Mount("/rpc", rpcv1)
|
||||
r.Mount("/", web.Handler())
|
||||
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 {
|
||||
return rpc.NewServer(m, config.RPC.Secret)
|
||||
func provideRPC(m manager.BuildManager, config config.Config) rpcHandlerV1 {
|
||||
v := rpc.NewServer(m, config.RPC.Secret)
|
||||
return rpcHandlerV1(v)
|
||||
}
|
||||
|
||||
// provideRPC2 is a Wire provider function that returns an rpc
|
||||
// handler that exposes the build manager to a remote agent.
|
||||
func provideRPC2(m manager.BuildManager, config config.Config) rpc2.Server {
|
||||
return rpc2.NewServer(m, config.RPC.Secret)
|
||||
func provideRPC2(m manager.BuildManager, config config.Config) rpcHandlerV2 {
|
||||
v := rpc2.NewServer(m, config.RPC.Secret)
|
||||
return rpcHandlerV2(v)
|
||||
}
|
||||
|
||||
// provideServer is a Wire provider function that returns an
|
||||
|
|
|
@ -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"
|
||||
|
@ -94,7 +93,7 @@ func InitializeApplication(config2 config.Config) (application, error) {
|
|||
webServer := web.New(admissionService, buildStore, client, hookParser, coreLicense, licenseService, middleware, repositoryStore, session, syncer, triggerer, userStore, userService, webhookSender, options, system)
|
||||
handler := provideRPC(buildManager, config2)
|
||||
rpc2Server := provideRPC2(buildManager, config2)
|
||||
metricServer := metric.NewServer(session)
|
||||
metricServer := provideMetric(session, config2)
|
||||
mux := provideRouter(server, webServer, handler, rpc2Server, metricServer)
|
||||
serverServer := provideServer(mux, config2)
|
||||
mainApplication := newApplication(cronScheduler, datadog, runner, serverServer, userStore)
|
||||
|
|
|
@ -36,6 +36,7 @@ func HandleLast(
|
|||
namespace = chi.URLParam(r, "owner")
|
||||
name = chi.URLParam(r, "name")
|
||||
ref = r.FormValue("ref")
|
||||
branch = r.FormValue("branch")
|
||||
)
|
||||
repo, err := repos.FindName(r.Context(), namespace, name)
|
||||
if err != nil {
|
||||
|
@ -45,6 +46,9 @@ func HandleLast(
|
|||
if ref == "" {
|
||||
ref = fmt.Sprintf("refs/heads/%s", repo.Branch)
|
||||
}
|
||||
if branch != "" {
|
||||
ref = fmt.Sprintf("refs/heads/%s", branch)
|
||||
}
|
||||
build, err := builds.FindRef(r.Context(), repo.ID, ref)
|
||||
if err != nil {
|
||||
render.NotFound(w, err)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -27,7 +27,7 @@ type Server struct {
|
|||
}
|
||||
|
||||
// NewServer returns a new metrics server.
|
||||
func NewServer(session core.Session) *Server {
|
||||
func NewServer(session core.Session, anonymous bool) *Server {
|
||||
return new(Server)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -261,7 +261,7 @@ func (s *Client) send(ctx context.Context, path string, in, out interface{}) err
|
|||
|
||||
// Check the response for a 204 no content. This indicates
|
||||
// the response body is empty and should be discarded.
|
||||
if res.StatusCode == 204 {
|
||||
if res.StatusCode == 204 || out == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ func TestAccept(t *testing.T) {
|
|||
|
||||
client := NewClient("http://drone.company.com", "correct-horse-battery-staple")
|
||||
gock.InterceptClient(client.client.HTTPClient)
|
||||
err := client.Accept(noContext, 1, "localhost")
|
||||
_, err := client.Accept(noContext, 1, "localhost")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
|
|
@ -4,18 +4,6 @@
|
|||
|
||||
// +build !oss
|
||||
|
||||
/*
|
||||
|
||||
/stage POST (request)
|
||||
/stage/{stage}?machine= POST (accept, details)
|
||||
/stage/{stage} PUT (beforeAll, afterAll)
|
||||
/stage/{stage}/steps/{step} PUT (before, after)
|
||||
/build/{build}/watch POST (watch)
|
||||
/stage/{stage}/logs/batch POST (batch)
|
||||
/stage/{stage}/logs/upload POST (upload)
|
||||
|
||||
*/
|
||||
|
||||
package rpc2
|
||||
|
||||
import (
|
||||
|
@ -55,7 +43,11 @@ func NewServer(manager manager.BuildManager, secret string) Server {
|
|||
func authorization(token string) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if token == r.Header.Get("X-Drone-Token") {
|
||||
// prevents system administrators from accidentally
|
||||
// exposing drone without credentials.
|
||||
if token == "" {
|
||||
w.WriteHeader(403)
|
||||
} else if token == r.Header.Get("X-Drone-Token") {
|
||||
next.ServeHTTP(w, r)
|
||||
} else {
|
||||
w.WriteHeader(401)
|
||||
|
|
33
operator/manager/rpc2/server_oss.go
Normal file
33
operator/manager/rpc2/server_oss.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2019 Drone IO, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build oss
|
||||
|
||||
package rpc2
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/drone/drone/operator/manager"
|
||||
)
|
||||
|
||||
// Server wraps the chi Router in a custom type for wire
|
||||
// injection purposes.
|
||||
type Server http.Handler
|
||||
|
||||
// NewServer returns a new rpc server that enables remote
|
||||
// interaction with the build controller using the http transport.
|
||||
func NewServer(manager manager.BuildManager, secret string) Server {
|
||||
return Server(http.NotFoundHandler())
|
||||
}
|
|
@ -579,12 +579,13 @@ func (r *Runner) poll(ctx context.Context) error {
|
|||
if err == db.ErrOptimisticLock {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
logger.WithFields(
|
||||
logrus.Fields{
|
||||
"stage-id": p.ID,
|
||||
"build-id": p.BuildID,
|
||||
"repo-id": p.RepoID,
|
||||
}).Warnln("runner: cannot ack stage")
|
||||
logger.WithError(err).
|
||||
WithFields(
|
||||
logrus.Fields{
|
||||
"stage-id": p.ID,
|
||||
"build-id": p.BuildID,
|
||||
"repo-id": p.RepoID,
|
||||
}).Warnln("runner: cannot ack stage")
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue