feat(influxdb): add urm for scraper
parent
abe6ed3b8b
commit
6e3e4503c2
|
@ -11,13 +11,15 @@ var _ influxdb.ScraperTargetStoreService = (*ScraperTargetStoreService)(nil)
|
|||
// ScraperTargetStoreService wraps a influxdb.ScraperTargetStoreService and authorizes actions
|
||||
// against it appropriately.
|
||||
type ScraperTargetStoreService struct {
|
||||
influxdb.UserResourceMappingService
|
||||
s influxdb.ScraperTargetStoreService
|
||||
}
|
||||
|
||||
// NewScraperTargetStoreService constructs an instance of an authorizing scraper target store serivce.
|
||||
func NewScraperTargetStoreService(s influxdb.ScraperTargetStoreService) *ScraperTargetStoreService {
|
||||
func NewScraperTargetStoreService(s influxdb.ScraperTargetStoreService, urm influxdb.UserResourceMappingService) *ScraperTargetStoreService {
|
||||
return &ScraperTargetStoreService{
|
||||
s: s,
|
||||
UserResourceMappingService: urm,
|
||||
s: s,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,7 +96,7 @@ func (s *ScraperTargetStoreService) ListTargets(ctx context.Context) ([]influxdb
|
|||
}
|
||||
|
||||
// AddTarget checks to see if the authorizer on context has write access to the global scraper target resource.
|
||||
func (s *ScraperTargetStoreService) AddTarget(ctx context.Context, st *influxdb.ScraperTarget) error {
|
||||
func (s *ScraperTargetStoreService) AddTarget(ctx context.Context, st *influxdb.ScraperTarget, userID influxdb.ID) error {
|
||||
p, err := influxdb.NewPermission(influxdb.WriteAction, influxdb.ScraperResourceType, st.OrgID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -104,11 +106,11 @@ func (s *ScraperTargetStoreService) AddTarget(ctx context.Context, st *influxdb.
|
|||
return err
|
||||
}
|
||||
|
||||
return s.s.AddTarget(ctx, st)
|
||||
return s.s.AddTarget(ctx, st, userID)
|
||||
}
|
||||
|
||||
// UpdateTarget checks to see if the authorizer on context has write access to the scraper target provided.
|
||||
func (s *ScraperTargetStoreService) UpdateTarget(ctx context.Context, upd *influxdb.ScraperTarget) (*influxdb.ScraperTarget, error) {
|
||||
func (s *ScraperTargetStoreService) UpdateTarget(ctx context.Context, upd *influxdb.ScraperTarget, userID influxdb.ID) (*influxdb.ScraperTarget, error) {
|
||||
st, err := s.s.GetTargetByID(ctx, upd.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -118,7 +120,7 @@ func (s *ScraperTargetStoreService) UpdateTarget(ctx context.Context, upd *influ
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return s.s.UpdateTarget(ctx, upd)
|
||||
return s.s.UpdateTarget(ctx, upd, userID)
|
||||
}
|
||||
|
||||
// RemoveTarget checks to see if the authorizer on context has write access to the scraper target provided.
|
||||
|
|
|
@ -104,7 +104,7 @@ func TestScraperTargetStoreService_GetTargetByID(t *testing.T) {
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := authorizer.NewScraperTargetStoreService(tt.fields.ScraperTargetStoreService)
|
||||
s := authorizer.NewScraperTargetStoreService(tt.fields.ScraperTargetStoreService, mock.NewUserResourceMappingService())
|
||||
|
||||
ctx := context.Background()
|
||||
ctx = influxdbcontext.SetAuthorizer(ctx, &Authorizer{[]influxdb.Permission{tt.args.permission}})
|
||||
|
@ -228,7 +228,7 @@ func TestScraperTargetStoreService_ListTargets(t *testing.T) {
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := authorizer.NewScraperTargetStoreService(tt.fields.ScraperTargetStoreService)
|
||||
s := authorizer.NewScraperTargetStoreService(tt.fields.ScraperTargetStoreService, mock.NewUserResourceMappingService())
|
||||
|
||||
ctx := context.Background()
|
||||
ctx = influxdbcontext.SetAuthorizer(ctx, &Authorizer{[]influxdb.Permission{tt.args.permission}})
|
||||
|
@ -271,7 +271,7 @@ func TestScraperTargetStoreService_UpdateTarget(t *testing.T) {
|
|||
OrgID: 10,
|
||||
}, nil
|
||||
},
|
||||
UpdateTargetF: func(ctx context.Context, upd *influxdb.ScraperTarget) (*influxdb.ScraperTarget, error) {
|
||||
UpdateTargetF: func(ctx context.Context, upd *influxdb.ScraperTarget, userID influxdb.ID) (*influxdb.ScraperTarget, error) {
|
||||
return &influxdb.ScraperTarget{
|
||||
ID: 1,
|
||||
OrgID: 10,
|
||||
|
@ -312,7 +312,7 @@ func TestScraperTargetStoreService_UpdateTarget(t *testing.T) {
|
|||
OrgID: 10,
|
||||
}, nil
|
||||
},
|
||||
UpdateTargetF: func(ctx context.Context, upd *influxdb.ScraperTarget) (*influxdb.ScraperTarget, error) {
|
||||
UpdateTargetF: func(ctx context.Context, upd *influxdb.ScraperTarget, userID influxdb.ID) (*influxdb.ScraperTarget, error) {
|
||||
return &influxdb.ScraperTarget{
|
||||
ID: 1,
|
||||
OrgID: 10,
|
||||
|
@ -343,12 +343,12 @@ func TestScraperTargetStoreService_UpdateTarget(t *testing.T) {
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := authorizer.NewScraperTargetStoreService(tt.fields.ScraperTargetStoreService)
|
||||
s := authorizer.NewScraperTargetStoreService(tt.fields.ScraperTargetStoreService, mock.NewUserResourceMappingService())
|
||||
|
||||
ctx := context.Background()
|
||||
ctx = influxdbcontext.SetAuthorizer(ctx, &Authorizer{tt.args.permissions})
|
||||
|
||||
_, err := s.UpdateTarget(ctx, &influxdb.ScraperTarget{ID: tt.args.id})
|
||||
_, err := s.UpdateTarget(ctx, &influxdb.ScraperTarget{ID: tt.args.id}, influxdb.ID(1))
|
||||
influxdbtesting.ErrorsEqual(t, err, tt.wants.err)
|
||||
})
|
||||
}
|
||||
|
@ -448,7 +448,7 @@ func TestScraperTargetStoreService_RemoveTarget(t *testing.T) {
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := authorizer.NewScraperTargetStoreService(tt.fields.ScraperTargetStoreService)
|
||||
s := authorizer.NewScraperTargetStoreService(tt.fields.ScraperTargetStoreService, mock.NewUserResourceMappingService())
|
||||
|
||||
ctx := context.Background()
|
||||
ctx = influxdbcontext.SetAuthorizer(ctx, &Authorizer{tt.args.permissions})
|
||||
|
@ -481,7 +481,7 @@ func TestScraperTargetStoreService_AddTarget(t *testing.T) {
|
|||
name: "authorized to create scraper",
|
||||
fields: fields{
|
||||
ScraperTargetStoreService: &mock.ScraperTargetStoreService{
|
||||
AddTargetF: func(ctx context.Context, st *influxdb.ScraperTarget) error {
|
||||
AddTargetF: func(ctx context.Context, st *influxdb.ScraperTarget, userID influxdb.ID) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
|
@ -504,7 +504,7 @@ func TestScraperTargetStoreService_AddTarget(t *testing.T) {
|
|||
name: "unauthorized to create scraper",
|
||||
fields: fields{
|
||||
ScraperTargetStoreService: &mock.ScraperTargetStoreService{
|
||||
AddTargetF: func(ctx context.Context, st *influxdb.ScraperTarget) error {
|
||||
AddTargetF: func(ctx context.Context, st *influxdb.ScraperTarget, userID influxdb.ID) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
|
@ -530,12 +530,12 @@ func TestScraperTargetStoreService_AddTarget(t *testing.T) {
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := authorizer.NewScraperTargetStoreService(tt.fields.ScraperTargetStoreService)
|
||||
s := authorizer.NewScraperTargetStoreService(tt.fields.ScraperTargetStoreService, mock.NewUserResourceMappingService())
|
||||
|
||||
ctx := context.Background()
|
||||
ctx = influxdbcontext.SetAuthorizer(ctx, &Authorizer{[]influxdb.Permission{tt.args.permission}})
|
||||
|
||||
err := s.AddTarget(ctx, &influxdb.ScraperTarget{OrgID: tt.args.orgID})
|
||||
err := s.AddTarget(ctx, &influxdb.ScraperTarget{OrgID: tt.args.orgID}, influxdb.ID(1))
|
||||
influxdbtesting.ErrorsEqual(t, err, tt.wants.err)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ func (c *Client) ListTargets(ctx context.Context) (list []platform.ScraperTarget
|
|||
}
|
||||
|
||||
// AddTarget add a new scraper target into storage.
|
||||
func (c *Client) AddTarget(ctx context.Context, target *platform.ScraperTarget) (err error) {
|
||||
func (c *Client) AddTarget(ctx context.Context, target *platform.ScraperTarget, userID platform.ID) (err error) {
|
||||
if !target.OrgID.Valid() {
|
||||
return &platform.Error{
|
||||
Code: platform.EInvalid,
|
||||
|
@ -62,7 +62,16 @@ func (c *Client) AddTarget(ctx context.Context, target *platform.ScraperTarget)
|
|||
}
|
||||
err = c.db.Update(func(tx *bolt.Tx) error {
|
||||
target.ID = c.IDGenerator.ID()
|
||||
return c.putTarget(ctx, tx, target)
|
||||
if err := c.putTarget(ctx, tx, target); err != nil {
|
||||
return err
|
||||
}
|
||||
urm := &platform.UserResourceMapping{
|
||||
ResourceID: target.ID,
|
||||
UserID: userID,
|
||||
UserType: platform.Owner,
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
}
|
||||
return c.createUserResourceMapping(ctx, tx, urm)
|
||||
})
|
||||
if err != nil {
|
||||
return &platform.Error{
|
||||
|
@ -87,7 +96,13 @@ func (c *Client) RemoveTarget(ctx context.Context, id platform.ID) error {
|
|||
Err: err,
|
||||
}
|
||||
}
|
||||
return tx.Bucket(scraperBucket).Delete(encID)
|
||||
if err = tx.Bucket(scraperBucket).Delete(encID); err != nil {
|
||||
return nil
|
||||
}
|
||||
return c.deleteUserResourceMappings(ctx, tx, platform.UserResourceMappingFilter{
|
||||
ResourceID: id,
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return &platform.Error{
|
||||
|
@ -99,7 +114,7 @@ func (c *Client) RemoveTarget(ctx context.Context, id platform.ID) error {
|
|||
}
|
||||
|
||||
// UpdateTarget updates a scraper target.
|
||||
func (c *Client) UpdateTarget(ctx context.Context, update *platform.ScraperTarget) (target *platform.ScraperTarget, err error) {
|
||||
func (c *Client) UpdateTarget(ctx context.Context, update *platform.ScraperTarget, userID platform.ID) (target *platform.ScraperTarget, err error) {
|
||||
op := getOp(platform.OpUpdateTarget)
|
||||
var pe *platform.Error
|
||||
if !update.ID.Valid() {
|
||||
|
|
|
@ -21,6 +21,11 @@ func initScraperTargetStoreService(f platformtesting.TargetFields, t *testing.T)
|
|||
t.Fatalf("failed to populate targets: %v", err)
|
||||
}
|
||||
}
|
||||
for _, m := range f.UserResourceMappings {
|
||||
if err := c.CreateUserResourceMapping(ctx, m); err != nil {
|
||||
t.Fatalf("failed to populate user resource mapping")
|
||||
}
|
||||
}
|
||||
return c, bolt.OpPrefix, func() {
|
||||
defer closeFn()
|
||||
for _, target := range f.Targets {
|
||||
|
@ -31,22 +36,6 @@ func initScraperTargetStoreService(f platformtesting.TargetFields, t *testing.T)
|
|||
}
|
||||
}
|
||||
|
||||
func TestScraperTargetStoreService_AddTarget(t *testing.T) {
|
||||
platformtesting.AddTarget(initScraperTargetStoreService, t)
|
||||
}
|
||||
|
||||
func TestScraperTargetStoreService_ListTargets(t *testing.T) {
|
||||
platformtesting.ListTargets(initScraperTargetStoreService, t)
|
||||
}
|
||||
|
||||
func TestScraperTargetStoreService_RemoveTarget(t *testing.T) {
|
||||
platformtesting.RemoveTarget(initScraperTargetStoreService, t)
|
||||
}
|
||||
|
||||
func TestScraperTargetStoreService_UpdateTarget(t *testing.T) {
|
||||
platformtesting.UpdateTarget(initScraperTargetStoreService, t)
|
||||
}
|
||||
|
||||
func TestScraperTargetStoreService_GetTargetByID(t *testing.T) {
|
||||
platformtesting.GetTargetByID(initScraperTargetStoreService, t)
|
||||
func TestScraperTargetStoreService(t *testing.T) {
|
||||
platformtesting.ScraperService(initScraperTargetStoreService, t)
|
||||
}
|
||||
|
|
|
@ -192,6 +192,7 @@ go_memstats_gc_cpu_fraction 1.972734963012756e-05
|
|||
// and influxdb.ScraperTargetStoreService interface.
|
||||
type mockStorage struct {
|
||||
sync.RWMutex
|
||||
influxdb.UserResourceMappingService
|
||||
TotalGatherJobs chan struct{}
|
||||
Metrics map[time.Time]Metrics
|
||||
Targets []influxdb.ScraperTarget
|
||||
|
@ -218,7 +219,7 @@ func (s *mockStorage) ListTargets(ctx context.Context) (targets []influxdb.Scrap
|
|||
return s.Targets, nil
|
||||
}
|
||||
|
||||
func (s *mockStorage) AddTarget(ctx context.Context, t *influxdb.ScraperTarget) error {
|
||||
func (s *mockStorage) AddTarget(ctx context.Context, t *influxdb.ScraperTarget, userID influxdb.ID) error {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
if s.Targets == nil {
|
||||
|
@ -259,7 +260,7 @@ func (s *mockStorage) GetTargetByID(ctx context.Context, id influxdb.ID) (target
|
|||
|
||||
}
|
||||
|
||||
func (s *mockStorage) UpdateTarget(ctx context.Context, update *influxdb.ScraperTarget) (target *influxdb.ScraperTarget, err error) {
|
||||
func (s *mockStorage) UpdateTarget(ctx context.Context, update *influxdb.ScraperTarget, userID influxdb.ID) (target *influxdb.ScraperTarget, err error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ func NewAPIHandler(b *APIBackend) *APIHandler {
|
|||
h.AuthorizationHandler.Logger = b.Logger.With(zap.String("handler", "auth"))
|
||||
|
||||
h.ScraperHandler = NewScraperHandler()
|
||||
h.ScraperHandler.ScraperStorageService = authorizer.NewScraperTargetStoreService(b.ScraperTargetStoreService)
|
||||
h.ScraperHandler.ScraperStorageService = authorizer.NewScraperTargetStoreService(b.ScraperTargetStoreService, b.UserResourceMappingService)
|
||||
h.ScraperHandler.BucketService = b.BucketService
|
||||
h.ScraperHandler.OrganizationService = b.OrganizationService
|
||||
h.ScraperHandler.Logger = b.Logger.With(zap.String("handler", "scraper"))
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"path"
|
||||
|
||||
"github.com/influxdata/influxdb"
|
||||
pctx "github.com/influxdata/influxdb/context"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -41,14 +42,19 @@ func NewScraperHandler() *ScraperHandler {
|
|||
// handlePostScraperTarget is HTTP handler for the POST /api/v2/scrapers route.
|
||||
func (h *ScraperHandler) handlePostScraperTarget(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
req, err := decodeScraperTargetAddRequest(ctx, r)
|
||||
if err != nil {
|
||||
EncodeError(ctx, err, w)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.ScraperStorageService.AddTarget(ctx, req); err != nil {
|
||||
auth, err := pctx.GetAuthorizer(ctx)
|
||||
if err != nil {
|
||||
EncodeError(ctx, err, w)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.ScraperStorageService.AddTarget(ctx, req, auth.GetUserID()); err != nil {
|
||||
EncodeError(ctx, err, w)
|
||||
return
|
||||
}
|
||||
|
@ -91,7 +97,13 @@ func (h *ScraperHandler) handlePatchScraperTarget(w http.ResponseWriter, r *http
|
|||
return
|
||||
}
|
||||
|
||||
target, err := h.ScraperStorageService.UpdateTarget(ctx, update)
|
||||
auth, err := pctx.GetAuthorizer(ctx)
|
||||
if err != nil {
|
||||
EncodeError(ctx, err, w)
|
||||
return
|
||||
}
|
||||
|
||||
target, err := h.ScraperStorageService.UpdateTarget(ctx, update, auth.GetUserID())
|
||||
if err != nil {
|
||||
EncodeError(ctx, err, w)
|
||||
return
|
||||
|
@ -247,7 +259,7 @@ func (s *ScraperService) ListTargets(ctx context.Context) ([]influxdb.ScraperTar
|
|||
|
||||
// UpdateTarget updates a single scraper target with changeset.
|
||||
// Returns the new target state after update.
|
||||
func (s *ScraperService) UpdateTarget(ctx context.Context, update *influxdb.ScraperTarget) (*influxdb.ScraperTarget, error) {
|
||||
func (s *ScraperService) UpdateTarget(ctx context.Context, update *influxdb.ScraperTarget, userID influxdb.ID) (*influxdb.ScraperTarget, error) {
|
||||
if !update.ID.Valid() {
|
||||
return nil, &influxdb.Error{
|
||||
Code: influxdb.EInvalid,
|
||||
|
@ -291,7 +303,7 @@ func (s *ScraperService) UpdateTarget(ctx context.Context, update *influxdb.Scra
|
|||
}
|
||||
|
||||
// AddTarget creates a new scraper target and sets target.ID with the new identifier.
|
||||
func (s *ScraperService) AddTarget(ctx context.Context, target *influxdb.ScraperTarget) error {
|
||||
func (s *ScraperService) AddTarget(ctx context.Context, target *influxdb.ScraperTarget, userID influxdb.ID) error {
|
||||
url, err := newURL(s.Addr, targetPath)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"testing"
|
||||
|
||||
platform "github.com/influxdata/influxdb"
|
||||
platcontext "github.com/influxdata/influxdb/context"
|
||||
"github.com/influxdata/influxdb/inmem"
|
||||
"github.com/influxdata/influxdb/mock"
|
||||
platformtesting "github.com/influxdata/influxdb/testing"
|
||||
|
@ -494,7 +495,7 @@ func TestService_handlePostScraperTarget(t *testing.T) {
|
|||
},
|
||||
},
|
||||
ScraperTargetStoreService: &mock.ScraperTargetStoreService{
|
||||
AddTargetF: func(ctx context.Context, st *platform.ScraperTarget) error {
|
||||
AddTargetF: func(ctx context.Context, st *platform.ScraperTarget, userID platform.ID) error {
|
||||
st.ID = targetOneID
|
||||
return nil
|
||||
},
|
||||
|
@ -549,6 +550,7 @@ func TestService_handlePostScraperTarget(t *testing.T) {
|
|||
}
|
||||
|
||||
r := httptest.NewRequest("GET", "http://any.tld", bytes.NewReader(st))
|
||||
r = r.WithContext(platcontext.SetAuthorizer(r.Context(), &platform.Authorization{}))
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
h.handlePostScraperTarget(w, r)
|
||||
|
@ -614,7 +616,7 @@ func TestService_handlePatchScraperTarget(t *testing.T) {
|
|||
},
|
||||
},
|
||||
ScraperTargetStoreService: &mock.ScraperTargetStoreService{
|
||||
UpdateTargetF: func(ctx context.Context, t *platform.ScraperTarget) (*platform.ScraperTarget, error) {
|
||||
UpdateTargetF: func(ctx context.Context, t *platform.ScraperTarget, userID platform.ID) (*platform.ScraperTarget, error) {
|
||||
if t.ID == targetOneID {
|
||||
return t, nil
|
||||
}
|
||||
|
@ -680,7 +682,7 @@ func TestService_handlePatchScraperTarget(t *testing.T) {
|
|||
},
|
||||
},
|
||||
ScraperTargetStoreService: &mock.ScraperTargetStoreService{
|
||||
UpdateTargetF: func(ctx context.Context, upd *platform.ScraperTarget) (*platform.ScraperTarget, error) {
|
||||
UpdateTargetF: func(ctx context.Context, upd *platform.ScraperTarget, userID platform.ID) (*platform.ScraperTarget, error) {
|
||||
return nil, &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Msg: platform.ErrScraperTargetNotFound,
|
||||
|
@ -732,7 +734,7 @@ func TestService_handlePatchScraperTarget(t *testing.T) {
|
|||
Value: tt.args.id,
|
||||
},
|
||||
}))
|
||||
|
||||
r = r.WithContext(platcontext.SetAuthorizer(r.Context(), &platform.Authorization{}))
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
h.handlePatchScraperTarget(w, r)
|
||||
|
@ -765,6 +767,11 @@ func initScraperService(f platformtesting.TargetFields, t *testing.T) (platform.
|
|||
t.Fatalf("failed to populate scraper targets")
|
||||
}
|
||||
}
|
||||
for _, m := range f.UserResourceMappings {
|
||||
if err := svc.PutUserResourceMapping(ctx, m); err != nil {
|
||||
t.Fatalf("failed to populate user resource mapping")
|
||||
}
|
||||
}
|
||||
|
||||
handler := NewScraperHandler()
|
||||
handler.ScraperStorageService = svc
|
||||
|
@ -784,10 +791,23 @@ func initScraperService(f platformtesting.TargetFields, t *testing.T) (platform.
|
|||
}, nil
|
||||
},
|
||||
}
|
||||
server := httptest.NewServer(handler)
|
||||
client := ScraperService{
|
||||
Addr: server.URL,
|
||||
OpPrefix: inmem.OpPrefix,
|
||||
userID, _ := platform.IDFromString("020f755c3c082002")
|
||||
server := httptest.NewServer(mock.NewMiddlewareHandler(
|
||||
handler, &platform.Authorization{
|
||||
UserID: *userID,
|
||||
Token: "tok",
|
||||
},
|
||||
))
|
||||
client := struct {
|
||||
platform.UserResourceMappingService
|
||||
ScraperService
|
||||
}{
|
||||
UserResourceMappingService: svc,
|
||||
ScraperService: ScraperService{
|
||||
Token: "tok",
|
||||
Addr: server.URL,
|
||||
OpPrefix: inmem.OpPrefix,
|
||||
},
|
||||
}
|
||||
done := server.Close
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ func (s *Service) ListTargets(ctx context.Context) (list []platform.ScraperTarge
|
|||
}
|
||||
|
||||
// AddTarget add a new scraper target into storage.
|
||||
func (s *Service) AddTarget(ctx context.Context, target *platform.ScraperTarget) (err error) {
|
||||
func (s *Service) AddTarget(ctx context.Context, target *platform.ScraperTarget, userID platform.ID) (err error) {
|
||||
target.ID = s.IDGenerator.ID()
|
||||
if !target.OrgID.Valid() {
|
||||
return &platform.Error{
|
||||
|
@ -73,6 +73,15 @@ func (s *Service) AddTarget(ctx context.Context, target *platform.ScraperTarget)
|
|||
Err: err,
|
||||
}
|
||||
}
|
||||
urm := &platform.UserResourceMapping{
|
||||
ResourceID: target.ID,
|
||||
UserID: userID,
|
||||
UserType: platform.Owner,
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
}
|
||||
if err := s.CreateUserResourceMapping(ctx, urm); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -85,11 +94,23 @@ func (s *Service) RemoveTarget(ctx context.Context, id platform.ID) error {
|
|||
}
|
||||
}
|
||||
s.scraperTargetKV.Delete(id.String())
|
||||
err := s.deleteUserResourceMapping(ctx, platform.UserResourceMappingFilter{
|
||||
ResourceID: id,
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
})
|
||||
if err != nil {
|
||||
return &platform.Error{
|
||||
Code: platform.ErrorCode(err),
|
||||
Op: OpPrefix + platform.OpRemoveTarget,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateTarget updates a scraper target.
|
||||
func (s *Service) UpdateTarget(ctx context.Context, update *platform.ScraperTarget) (target *platform.ScraperTarget, err error) {
|
||||
func (s *Service) UpdateTarget(ctx context.Context, update *platform.ScraperTarget, userID platform.ID) (target *platform.ScraperTarget, err error) {
|
||||
op := OpPrefix + platform.OpUpdateTarget
|
||||
if !update.ID.Valid() {
|
||||
return nil, &platform.Error{
|
||||
|
|
|
@ -17,25 +17,14 @@ func initScraperTargetStoreService(f platformtesting.TargetFields, t *testing.T)
|
|||
t.Fatalf("failed to populate scraper targets")
|
||||
}
|
||||
}
|
||||
for _, m := range f.UserResourceMappings {
|
||||
if err := s.PutUserResourceMapping(ctx, m); err != nil {
|
||||
t.Fatalf("failed to populate user resource mapping")
|
||||
}
|
||||
}
|
||||
return s, OpPrefix, func() {}
|
||||
}
|
||||
|
||||
func TestScraperTargetStoreService_AddTarget(t *testing.T) {
|
||||
platformtesting.AddTarget(initScraperTargetStoreService, t)
|
||||
}
|
||||
|
||||
func TestScraperTargetStoreService_ListTargets(t *testing.T) {
|
||||
platformtesting.ListTargets(initScraperTargetStoreService, t)
|
||||
}
|
||||
|
||||
func TestScraperTargetStoreService_RemoveTarget(t *testing.T) {
|
||||
platformtesting.RemoveTarget(initScraperTargetStoreService, t)
|
||||
}
|
||||
|
||||
func TestScraperTargetStoreService_UpdateTarget(t *testing.T) {
|
||||
platformtesting.UpdateTarget(initScraperTargetStoreService, t)
|
||||
}
|
||||
|
||||
func TestScraperTargetStoreService_GetTargetByID(t *testing.T) {
|
||||
platformtesting.GetTargetByID(initScraperTargetStoreService, t)
|
||||
func TestScraperTargetStoreService(t *testing.T) {
|
||||
platformtesting.ScraperService(initScraperTargetStoreService, t)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package mock
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/influxdata/influxdb"
|
||||
platcontext "github.com/influxdata/influxdb/context"
|
||||
)
|
||||
|
||||
// NewMiddlewareHandler create a mocked middleware handler.
|
||||
func NewMiddlewareHandler(handler http.Handler, auth influxdb.Authorizer) http.Handler {
|
||||
return &middlewareHandler{
|
||||
handler: handler,
|
||||
auth: auth,
|
||||
}
|
||||
}
|
||||
|
||||
type middlewareHandler struct {
|
||||
handler http.Handler
|
||||
auth influxdb.Authorizer
|
||||
}
|
||||
|
||||
func (m *middlewareHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
r = r.WithContext(platcontext.SetAuthorizer(ctx, m.auth))
|
||||
m.handler.ServeHTTP(w, r)
|
||||
}
|
|
@ -10,11 +10,12 @@ var _ platform.ScraperTargetStoreService = &ScraperTargetStoreService{}
|
|||
|
||||
// ScraperTargetStoreService is a mock implementation of a platform.ScraperTargetStoreService.
|
||||
type ScraperTargetStoreService struct {
|
||||
UserResourceMappingService
|
||||
ListTargetsF func(ctx context.Context) ([]platform.ScraperTarget, error)
|
||||
AddTargetF func(ctx context.Context, t *platform.ScraperTarget) error
|
||||
AddTargetF func(ctx context.Context, t *platform.ScraperTarget, userID platform.ID) error
|
||||
GetTargetByIDF func(ctx context.Context, id platform.ID) (*platform.ScraperTarget, error)
|
||||
RemoveTargetF func(ctx context.Context, id platform.ID) error
|
||||
UpdateTargetF func(ctx context.Context, t *platform.ScraperTarget) (*platform.ScraperTarget, error)
|
||||
UpdateTargetF func(ctx context.Context, t *platform.ScraperTarget, userID platform.ID) (*platform.ScraperTarget, error)
|
||||
}
|
||||
|
||||
// ListTargets lists all the scraper targets.
|
||||
|
@ -23,8 +24,8 @@ func (s *ScraperTargetStoreService) ListTargets(ctx context.Context) ([]platform
|
|||
}
|
||||
|
||||
// AddTarget adds a scraper target.
|
||||
func (s *ScraperTargetStoreService) AddTarget(ctx context.Context, t *platform.ScraperTarget) error {
|
||||
return s.AddTargetF(ctx, t)
|
||||
func (s *ScraperTargetStoreService) AddTarget(ctx context.Context, t *platform.ScraperTarget, userID platform.ID) error {
|
||||
return s.AddTargetF(ctx, t, userID)
|
||||
}
|
||||
|
||||
// GetTargetByID retrieves a scraper target by id.
|
||||
|
@ -38,6 +39,6 @@ func (s *ScraperTargetStoreService) RemoveTarget(ctx context.Context, id platfor
|
|||
}
|
||||
|
||||
// UpdateTarget updates a scraper target.
|
||||
func (s *ScraperTargetStoreService) UpdateTarget(ctx context.Context, t *platform.ScraperTarget) (*platform.ScraperTarget, error) {
|
||||
return s.UpdateTargetF(ctx, t)
|
||||
func (s *ScraperTargetStoreService) UpdateTarget(ctx context.Context, t *platform.ScraperTarget, userID platform.ID) (*platform.ScraperTarget, error) {
|
||||
return s.UpdateTargetF(ctx, t, userID)
|
||||
}
|
||||
|
|
|
@ -28,11 +28,12 @@ type ScraperTarget struct {
|
|||
|
||||
// ScraperTargetStoreService defines the crud service for ScraperTarget.
|
||||
type ScraperTargetStoreService interface {
|
||||
UserResourceMappingService
|
||||
ListTargets(ctx context.Context) ([]ScraperTarget, error)
|
||||
AddTarget(ctx context.Context, t *ScraperTarget) error
|
||||
AddTarget(ctx context.Context, t *ScraperTarget, userID ID) error
|
||||
GetTargetByID(ctx context.Context, id ID) (*ScraperTarget, error)
|
||||
RemoveTarget(ctx context.Context, id ID) error
|
||||
UpdateTarget(ctx context.Context, t *ScraperTarget) (*ScraperTarget, error)
|
||||
UpdateTarget(ctx context.Context, t *ScraperTarget, userID ID) (*ScraperTarget, error)
|
||||
}
|
||||
|
||||
// ScraperTargetFilter represents a set of filter that restrict the returned results.
|
||||
|
|
|
@ -19,8 +19,9 @@ const (
|
|||
|
||||
// TargetFields will include the IDGenerator, and targets
|
||||
type TargetFields struct {
|
||||
IDGenerator platform.IDGenerator
|
||||
Targets []*platform.ScraperTarget
|
||||
IDGenerator platform.IDGenerator
|
||||
Targets []*platform.ScraperTarget
|
||||
UserResourceMappings []*platform.UserResourceMapping
|
||||
}
|
||||
|
||||
var targetCmpOptions = cmp.Options{
|
||||
|
@ -79,11 +80,13 @@ func AddTarget(
|
|||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
userID platform.ID
|
||||
target *platform.ScraperTarget
|
||||
}
|
||||
type wants struct {
|
||||
err error
|
||||
targets []platform.ScraperTarget
|
||||
err error
|
||||
targets []platform.ScraperTarget
|
||||
userResourceMappings []*platform.UserResourceMapping
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -94,10 +97,12 @@ func AddTarget(
|
|||
{
|
||||
name: "create targets with empty set",
|
||||
fields: TargetFields{
|
||||
IDGenerator: mock.NewIDGenerator(targetOneID, t),
|
||||
Targets: []*platform.ScraperTarget{},
|
||||
IDGenerator: mock.NewIDGenerator(targetOneID, t),
|
||||
Targets: []*platform.ScraperTarget{},
|
||||
UserResourceMappings: []*platform.UserResourceMapping{},
|
||||
},
|
||||
args: args{
|
||||
userID: MustIDBase16(threeID),
|
||||
target: &platform.ScraperTarget{
|
||||
Name: "name1",
|
||||
Type: platform.PrometheusScraperType,
|
||||
|
@ -107,6 +112,14 @@ func AddTarget(
|
|||
},
|
||||
},
|
||||
wants: wants{
|
||||
userResourceMappings: []*platform.UserResourceMapping{
|
||||
{
|
||||
ResourceID: MustIDBase16(oneID),
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
UserID: MustIDBase16(threeID),
|
||||
UserType: platform.Owner,
|
||||
},
|
||||
},
|
||||
targets: []platform.ScraperTarget{
|
||||
{
|
||||
Name: "name1",
|
||||
|
@ -122,7 +135,8 @@ func AddTarget(
|
|||
{
|
||||
name: "create target with invalid org id",
|
||||
fields: TargetFields{
|
||||
IDGenerator: mock.NewIDGenerator(targetTwoID, t),
|
||||
IDGenerator: mock.NewIDGenerator(targetTwoID, t),
|
||||
UserResourceMappings: []*platform.UserResourceMapping{},
|
||||
Targets: []*platform.ScraperTarget{
|
||||
{
|
||||
Name: "name1",
|
||||
|
@ -149,6 +163,7 @@ func AddTarget(
|
|||
Msg: "org id is invalid",
|
||||
Op: platform.OpAddTarget,
|
||||
},
|
||||
userResourceMappings: []*platform.UserResourceMapping{},
|
||||
targets: []platform.ScraperTarget{
|
||||
{
|
||||
Name: "name1",
|
||||
|
@ -164,7 +179,8 @@ func AddTarget(
|
|||
{
|
||||
name: "create target with invalid bucket id",
|
||||
fields: TargetFields{
|
||||
IDGenerator: mock.NewIDGenerator(targetTwoID, t),
|
||||
IDGenerator: mock.NewIDGenerator(targetTwoID, t),
|
||||
UserResourceMappings: []*platform.UserResourceMapping{},
|
||||
Targets: []*platform.ScraperTarget{
|
||||
{
|
||||
Name: "name1",
|
||||
|
@ -191,6 +207,7 @@ func AddTarget(
|
|||
Msg: "bucket id is invalid",
|
||||
Op: platform.OpAddTarget,
|
||||
},
|
||||
userResourceMappings: []*platform.UserResourceMapping{},
|
||||
targets: []platform.ScraperTarget{
|
||||
{
|
||||
Name: "name1",
|
||||
|
@ -217,8 +234,17 @@ func AddTarget(
|
|||
ID: MustIDBase16(targetOneID),
|
||||
},
|
||||
},
|
||||
UserResourceMappings: []*platform.UserResourceMapping{
|
||||
{
|
||||
ResourceID: MustIDBase16(targetOneID),
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
UserID: MustIDBase16(threeID),
|
||||
UserType: platform.Member,
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
userID: MustIDBase16(threeID),
|
||||
target: &platform.ScraperTarget{
|
||||
ID: MustIDBase16(targetTwoID),
|
||||
Name: "name2",
|
||||
|
@ -229,6 +255,20 @@ func AddTarget(
|
|||
},
|
||||
},
|
||||
wants: wants{
|
||||
userResourceMappings: []*platform.UserResourceMapping{
|
||||
{
|
||||
ResourceID: MustIDBase16(oneID),
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
UserID: MustIDBase16(threeID),
|
||||
UserType: platform.Member,
|
||||
},
|
||||
{
|
||||
ResourceID: MustIDBase16(twoID),
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
UserID: MustIDBase16(threeID),
|
||||
UserType: platform.Owner,
|
||||
},
|
||||
},
|
||||
targets: []platform.ScraperTarget{
|
||||
{
|
||||
Name: "name1",
|
||||
|
@ -255,7 +295,7 @@ func AddTarget(
|
|||
s, opPrefix, done := init(tt.fields, t)
|
||||
defer done()
|
||||
ctx := context.Background()
|
||||
err := s.AddTarget(ctx, tt.args.target)
|
||||
err := s.AddTarget(ctx, tt.args.target, tt.args.userID)
|
||||
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
|
||||
defer s.RemoveTarget(ctx, tt.args.target.ID)
|
||||
|
||||
|
@ -266,6 +306,16 @@ func AddTarget(
|
|||
if diff := cmp.Diff(targets, tt.wants.targets, targetCmpOptions...); diff != "" {
|
||||
t.Errorf("scraper targets are different -got/+want\ndiff %s", diff)
|
||||
}
|
||||
urms, _, err := s.FindUserResourceMappings(ctx, platform.UserResourceMappingFilter{
|
||||
UserID: tt.args.userID,
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to retrieve user resource mappings: %v", err)
|
||||
}
|
||||
if diff := cmp.Diff(urms, tt.wants.userResourceMappings, userResourceMappingCmpOptions...); diff != "" {
|
||||
t.Errorf("user resource mappings are different -got/+want\ndiff %s", diff)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
@ -446,11 +496,13 @@ func GetTargetByID(
|
|||
func RemoveTarget(init func(TargetFields, *testing.T) (platform.ScraperTargetStoreService, string, func()),
|
||||
t *testing.T) {
|
||||
type args struct {
|
||||
ID platform.ID
|
||||
ID platform.ID
|
||||
userID platform.ID
|
||||
}
|
||||
type wants struct {
|
||||
err error
|
||||
targets []platform.ScraperTarget
|
||||
err error
|
||||
userResourceMappings []*platform.UserResourceMapping
|
||||
targets []platform.ScraperTarget
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -461,6 +513,20 @@ func RemoveTarget(init func(TargetFields, *testing.T) (platform.ScraperTargetSto
|
|||
{
|
||||
name: "delete targets using exist id",
|
||||
fields: TargetFields{
|
||||
UserResourceMappings: []*platform.UserResourceMapping{
|
||||
{
|
||||
ResourceID: MustIDBase16(oneID),
|
||||
UserID: MustIDBase16(threeID),
|
||||
UserType: platform.Owner,
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
},
|
||||
{
|
||||
ResourceID: MustIDBase16(twoID),
|
||||
UserID: MustIDBase16(threeID),
|
||||
UserType: platform.Member,
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
},
|
||||
},
|
||||
Targets: []*platform.ScraperTarget{
|
||||
{
|
||||
ID: MustIDBase16(targetOneID),
|
||||
|
@ -475,9 +541,18 @@ func RemoveTarget(init func(TargetFields, *testing.T) (platform.ScraperTargetSto
|
|||
},
|
||||
},
|
||||
args: args{
|
||||
ID: MustIDBase16(targetOneID),
|
||||
ID: MustIDBase16(targetOneID),
|
||||
userID: MustIDBase16(threeID),
|
||||
},
|
||||
wants: wants{
|
||||
userResourceMappings: []*platform.UserResourceMapping{
|
||||
{
|
||||
ResourceID: MustIDBase16(twoID),
|
||||
UserID: MustIDBase16(threeID),
|
||||
UserType: platform.Member,
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
},
|
||||
},
|
||||
targets: []platform.ScraperTarget{
|
||||
{
|
||||
ID: MustIDBase16(targetTwoID),
|
||||
|
@ -490,6 +565,20 @@ func RemoveTarget(init func(TargetFields, *testing.T) (platform.ScraperTargetSto
|
|||
{
|
||||
name: "delete targets using id that does not exist",
|
||||
fields: TargetFields{
|
||||
UserResourceMappings: []*platform.UserResourceMapping{
|
||||
{
|
||||
ResourceID: MustIDBase16(oneID),
|
||||
UserID: MustIDBase16(threeID),
|
||||
UserType: platform.Owner,
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
},
|
||||
{
|
||||
ResourceID: MustIDBase16(twoID),
|
||||
UserID: MustIDBase16(threeID),
|
||||
UserType: platform.Member,
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
},
|
||||
},
|
||||
Targets: []*platform.ScraperTarget{
|
||||
{
|
||||
ID: MustIDBase16(targetOneID),
|
||||
|
@ -504,7 +593,8 @@ func RemoveTarget(init func(TargetFields, *testing.T) (platform.ScraperTargetSto
|
|||
},
|
||||
},
|
||||
args: args{
|
||||
ID: MustIDBase16(targetThreeID),
|
||||
ID: MustIDBase16(targetThreeID),
|
||||
userID: MustIDBase16(threeID),
|
||||
},
|
||||
wants: wants{
|
||||
err: &platform.Error{
|
||||
|
@ -524,6 +614,20 @@ func RemoveTarget(init func(TargetFields, *testing.T) (platform.ScraperTargetSto
|
|||
BucketID: MustIDBase16(bucketOneID),
|
||||
},
|
||||
},
|
||||
userResourceMappings: []*platform.UserResourceMapping{
|
||||
{
|
||||
ResourceID: MustIDBase16(oneID),
|
||||
UserID: MustIDBase16(threeID),
|
||||
UserType: platform.Owner,
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
},
|
||||
{
|
||||
ResourceID: MustIDBase16(twoID),
|
||||
UserID: MustIDBase16(threeID),
|
||||
UserType: platform.Member,
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -542,6 +646,16 @@ func RemoveTarget(init func(TargetFields, *testing.T) (platform.ScraperTargetSto
|
|||
if diff := cmp.Diff(targets, tt.wants.targets, targetCmpOptions...); diff != "" {
|
||||
t.Errorf("targets are different -got/+want\ndiff %s", diff)
|
||||
}
|
||||
urms, _, err := s.FindUserResourceMappings(ctx, platform.UserResourceMappingFilter{
|
||||
UserID: tt.args.userID,
|
||||
ResourceType: platform.ScraperResourceType,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to retrieve user resource mappings: %v", err)
|
||||
}
|
||||
if diff := cmp.Diff(urms, tt.wants.userResourceMappings, userResourceMappingCmpOptions...); diff != "" {
|
||||
t.Errorf("user resource mappings are different -got/+want\ndiff %s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -552,8 +666,9 @@ func UpdateTarget(
|
|||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
url string
|
||||
id platform.ID
|
||||
url string
|
||||
userID platform.ID
|
||||
id platform.ID
|
||||
}
|
||||
type wants struct {
|
||||
err error
|
||||
|
@ -669,7 +784,7 @@ func UpdateTarget(
|
|||
URL: tt.args.url,
|
||||
}
|
||||
|
||||
target, err := s.UpdateTarget(ctx, upd)
|
||||
target, err := s.UpdateTarget(ctx, upd, tt.args.userID)
|
||||
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
|
||||
|
||||
if diff := cmp.Diff(target, tt.wants.target, targetCmpOptions...); diff != "" {
|
||||
|
|
Loading…
Reference in New Issue