From edf0d1bf3287e62847ca9df8fcde359e46a216c0 Mon Sep 17 00:00:00 2001 From: George MacRorie Date: Thu, 22 Oct 2020 12:15:56 +0100 Subject: [PATCH] refactor(notifications): isolate endpoint service Following the ongoing effort to isolate behaviours into their own packages and off of kv.Service, this change move the notification endpoints service implementation into its own package. It removes the endpoint behaviors from the kv service completely. --- cmd/influxd/launcher/launcher.go | 34 +- kv/check_test.go | 38 +- kv/initial_migration.go | 4 +- kv/notification_endpoint.go | 334 ------ kv/notification_endpoint_test.go | 77 -- kv/service.go | 2 - notification/endpoint/endpoint_test.go | 132 +-- .../endpoint/service}/service.go | 18 +- .../endpoint/service}/service_test.go | 75 +- notification/endpoint/service/store.go | 305 +++++ notification/endpoint/service/store_test.go | 127 ++ .../endpoint/service/testing/service.go | 1054 +++++------------ notification_endpoint.go | 6 - testing/checks.go | 3 +- testing/util.go | 38 +- 15 files changed, 911 insertions(+), 1336 deletions(-) delete mode 100644 kv/notification_endpoint.go delete mode 100644 kv/notification_endpoint_test.go rename {endpoints => notification/endpoint/service}/service.go (84%) rename {endpoints => notification/endpoint/service}/service_test.go (76%) create mode 100644 notification/endpoint/service/store.go create mode 100644 notification/endpoint/service/store_test.go rename testing/notification_endpoint.go => notification/endpoint/service/testing/service.go (55%) diff --git a/cmd/influxd/launcher/launcher.go b/cmd/influxd/launcher/launcher.go index b7aa2f2746a..4ffb5cee852 100644 --- a/cmd/influxd/launcher/launcher.go +++ b/cmd/influxd/launcher/launcher.go @@ -24,7 +24,6 @@ import ( "github.com/influxdata/influxdb/v2/chronograf/server" "github.com/influxdata/influxdb/v2/cmd/influxd/inspect" "github.com/influxdata/influxdb/v2/dbrp" - "github.com/influxdata/influxdb/v2/endpoints" "github.com/influxdata/influxdb/v2/gather" "github.com/influxdata/influxdb/v2/http" iqlcontrol "github.com/influxdata/influxdb/v2/influxql/control" @@ -46,6 +45,7 @@ import ( "github.com/influxdata/influxdb/v2/label" influxlogger "github.com/influxdata/influxdb/v2/logger" "github.com/influxdata/influxdb/v2/nats" + endpointservice "github.com/influxdata/influxdb/v2/notification/endpoint/service" ruleservice "github.com/influxdata/influxdb/v2/notification/rule/service" "github.com/influxdata/influxdb/v2/pkger" infprom "github.com/influxdata/influxdb/v2/prometheus" @@ -759,17 +759,16 @@ func (m *Launcher) run(ctx context.Context) (err error) { m.reg.MustRegister(m.boltClient) var ( - variableSvc platform.VariableService = m.kvService - sourceSvc platform.SourceService = m.kvService - dashboardSvc platform.DashboardService = m.kvService - dashboardLogSvc platform.DashboardOperationLogService = m.kvService - userLogSvc platform.UserOperationLogService = m.kvService - bucketLogSvc platform.BucketOperationLogService = m.kvService - orgLogSvc platform.OrganizationOperationLogService = m.kvService - scraperTargetSvc platform.ScraperTargetStoreService = m.kvService - telegrafSvc platform.TelegrafConfigStore = m.kvService - lookupSvc platform.LookupService = m.kvService - notificationEndpointStore platform.NotificationEndpointService = m.kvService + variableSvc platform.VariableService = m.kvService + sourceSvc platform.SourceService = m.kvService + dashboardSvc platform.DashboardService = m.kvService + dashboardLogSvc platform.DashboardOperationLogService = m.kvService + userLogSvc platform.UserOperationLogService = m.kvService + bucketLogSvc platform.BucketOperationLogService = m.kvService + orgLogSvc platform.OrganizationOperationLogService = m.kvService + scraperTargetSvc platform.ScraperTargetStoreService = m.kvService + telegrafSvc platform.TelegrafConfigStore = m.kvService + lookupSvc platform.LookupService = m.kvService ) tenantStore := tenant.NewStore(m.kvStore) @@ -988,10 +987,15 @@ func (m *Launcher) run(ctx context.Context) (err error) { checkSvc = middleware.NewCheckService(checkSvc, m.kvService, coordinator) } + var notificationEndpointSvc platform.NotificationEndpointService + { + notificationEndpointSvc = endpointservice.New(endpointservice.NewStore(m.kvStore), secretSvc) + } + var notificationRuleSvc platform.NotificationRuleStore { coordinator := coordinator.NewCoordinator(m.log, m.scheduler, m.executor) - notificationRuleSvc, err = ruleservice.NewRuleService(m.log, m.kvStore, m.kvService, ts.OrganizationService, m.kvService) + notificationRuleSvc, err = ruleservice.NewRuleService(m.log, m.kvStore, m.kvService, ts.OrganizationService, notificationEndpointSvc) if err != nil { return err } @@ -1145,7 +1149,7 @@ func (m *Launcher) run(ctx context.Context) (err error) { VariableFinder: variableSvc, TargetFinder: scraperTargetSvc, CheckFinder: checkSvc, - NotificationEndpointFinder: notificationEndpointStore, + NotificationEndpointFinder: notificationEndpointSvc, NotificationRuleFinder: notificationRuleSvc, } @@ -1190,7 +1194,7 @@ func (m *Launcher) run(ctx context.Context) (err error) { TaskService: taskSvc, TelegrafService: telegrafSvc, NotificationRuleStore: notificationRuleSvc, - NotificationEndpointService: endpoints.NewService(notificationEndpointStore, secretSvc, ts.UserResourceMappingService, ts.OrganizationService), + NotificationEndpointService: notificationEndpointSvc, CheckService: checkSvc, ScraperTargetStoreService: scraperTargetSvc, ChronografService: chronografSvc, diff --git a/kv/check_test.go b/kv/check_test.go index daac631da32..5c3e50fd6de 100644 --- a/kv/check_test.go +++ b/kv/check_test.go @@ -6,7 +6,9 @@ import ( "github.com/influxdata/influxdb/v2" "github.com/influxdata/influxdb/v2/kv" + "github.com/influxdata/influxdb/v2/mock" "github.com/influxdata/influxdb/v2/query/fluxlang" + "github.com/influxdata/influxdb/v2/tenant" influxdbtesting "github.com/influxdata/influxdb/v2/testing" "go.uber.org/zap/zaptest" ) @@ -15,20 +17,20 @@ func TestBoltCheckService(t *testing.T) { influxdbtesting.CheckService(initBoltCheckService, t) } -func initBoltCheckService(f influxdbtesting.CheckFields, t *testing.T) (influxdb.CheckService, *kv.Service, string, func()) { +func initBoltCheckService(f influxdbtesting.CheckFields, t *testing.T) (influxdb.CheckService, influxdb.UserResourceMappingService, string, func()) { s, closeBolt, err := NewTestBoltStore(t) if err != nil { t.Fatalf("failed to create new kv store: %v", err) } - svc, op, closeSvc := initCheckService(s, f, t) - return svc, svc, op, func() { + svc, urmSvc, op, closeSvc := initCheckService(s, f, t) + return svc, urmSvc, op, func() { closeSvc() closeBolt() } } -func initCheckService(s kv.SchemaStore, f influxdbtesting.CheckFields, t *testing.T) (*kv.Service, string, func()) { +func initCheckService(s kv.SchemaStore, f influxdbtesting.CheckFields, t *testing.T) (influxdb.CheckService, influxdb.UserResourceMappingService, string, func()) { ctx := context.Background() svc := kv.NewService(zaptest.NewLogger(t), s, kv.ServiceConfig{ FluxLanguageService: fluxlang.DefaultService, @@ -39,15 +41,20 @@ func initCheckService(s kv.SchemaStore, f influxdbtesting.CheckFields, t *testin svc.TimeGenerator = influxdb.RealTimeGenerator{} } + tenantStore := tenant.NewStore(s) + tenantSvc := tenant.NewService(tenantStore) + for _, m := range f.UserResourceMappings { - if err := svc.CreateUserResourceMapping(ctx, m); err != nil { + if err := tenantSvc.CreateUserResourceMapping(ctx, m); err != nil { t.Fatalf("failed to populate user resource mapping: %v", err) } } for _, o := range f.Organizations { - if err := svc.PutOrganization(ctx, o); err != nil { - t.Fatalf("failed to populate organizations") - } + withOrgID(tenantStore, o.ID, func() { + if err := tenantSvc.CreateOrganization(ctx, o); err != nil { + t.Fatalf("failed to populate org: %v", err) + } + }) } for _, c := range f.Checks { if err := svc.PutCheck(ctx, c); err != nil { @@ -59,14 +66,14 @@ func initCheckService(s kv.SchemaStore, f influxdbtesting.CheckFields, t *testin t.Fatalf("failed to populate tasks: %v", err) } } - return svc, kv.OpPrefix, func() { + return svc, tenantSvc, kv.OpPrefix, func() { for _, o := range f.Organizations { - if err := svc.DeleteOrganization(ctx, o.ID); err != nil { + if err := tenantSvc.DeleteOrganization(ctx, o.ID); err != nil { t.Logf("failed to remove organization: %v", err) } } for _, urm := range f.UserResourceMappings { - if err := svc.DeleteUserResourceMapping(ctx, urm.ResourceID, urm.UserID); err != nil && influxdb.ErrorCode(err) != influxdb.ENotFound { + if err := tenantSvc.DeleteUserResourceMapping(ctx, urm.ResourceID, urm.UserID); err != nil && influxdb.ErrorCode(err) != influxdb.ENotFound { t.Logf("failed to remove urm rule: %v", err) } } @@ -77,3 +84,12 @@ func initCheckService(s kv.SchemaStore, f influxdbtesting.CheckFields, t *testin } } } + +func withOrgID(store *tenant.Store, orgID influxdb.ID, fn func()) { + backup := store.OrgIDGen + defer func() { store.OrgIDGen = backup }() + + store.OrgIDGen = mock.NewStaticIDGenerator(orgID) + + fn() +} diff --git a/kv/initial_migration.go b/kv/initial_migration.go index 17661be0908..c4c092208c8 100644 --- a/kv/initial_migration.go +++ b/kv/initial_migration.go @@ -56,8 +56,8 @@ func (m InitialMigration) Up(ctx context.Context, store SchemaStore) error { // store base backed services checkBucket, checkIndexBucket, - notificationEndpointBucket, - notificationEndpointIndexBucket, + []byte("notificationEndpointv1"), + []byte("notificationEndpointIndexv1"), variableBucket, variableIndexBucket, variableOrgsIndex, diff --git a/kv/notification_endpoint.go b/kv/notification_endpoint.go deleted file mode 100644 index 2bcb5288b2b..00000000000 --- a/kv/notification_endpoint.go +++ /dev/null @@ -1,334 +0,0 @@ -package kv - -import ( - "context" - - "github.com/influxdata/influxdb/v2" - "github.com/influxdata/influxdb/v2/kit/tracing" - "github.com/influxdata/influxdb/v2/notification/endpoint" -) - -var ( - // ErrNotificationEndpointNotFound is used when the notification endpoint is not found. - ErrNotificationEndpointNotFound = &influxdb.Error{ - Msg: "notification endpoint not found", - Code: influxdb.ENotFound, - } - - notificationEndpointBucket = []byte("notificationEndpointv1") - notificationEndpointIndexBucket = []byte("notificationEndpointIndexv1") -) - -var _ influxdb.NotificationEndpointService = (*Service)(nil) - -func newEndpointStore() *IndexStore { - const resource = "notification endpoint" - - var decEndpointEntFn DecodeBucketValFn = func(key, val []byte) ([]byte, interface{}, error) { - edp, err := endpoint.UnmarshalJSON(val) - return key, edp, err - } - - var decValToEntFn ConvertValToEntFn = func(_ []byte, v interface{}) (Entity, error) { - edp, ok := v.(influxdb.NotificationEndpoint) - if err := IsErrUnexpectedDecodeVal(ok); err != nil { - return Entity{}, err - } - return Entity{ - PK: EncID(edp.GetID()), - UniqueKey: Encode(EncID(edp.GetOrgID()), EncString(edp.GetName())), - Body: edp, - }, nil - } - - return &IndexStore{ - Resource: resource, - EntStore: NewStoreBase(resource, notificationEndpointBucket, EncIDKey, EncBodyJSON, decEndpointEntFn, decValToEntFn), - IndexStore: NewOrgNameKeyStore(resource, notificationEndpointIndexBucket, true), - } -} - -// CreateNotificationEndpoint creates a new notification endpoint and sets b.ID with the new identifier. -func (s *Service) CreateNotificationEndpoint(ctx context.Context, edp influxdb.NotificationEndpoint, userID influxdb.ID) error { - return s.kv.Update(ctx, func(tx Tx) error { - return s.createNotificationEndpoint(ctx, tx, edp, userID) - }) -} - -func (s *Service) createNotificationEndpoint(ctx context.Context, tx Tx, edp influxdb.NotificationEndpoint, userID influxdb.ID) error { - // TODO(jsteenb2): why is org id check not necesssary if orgID isn't valid... feels odd - if edp.GetOrgID().Valid() { - span, ctx := tracing.StartSpanFromContext(ctx) - // TODO(jsteenb2): this defer doesn't get called until the end of entire function, - // need to rip this out as is - defer span.Finish() - - if _, err := s.findOrganizationByID(ctx, tx, edp.GetOrgID()); err != nil { - return err - } - } - - id := s.IDGenerator.ID() - edp.SetID(id) - now := s.TimeGenerator.Now() - edp.SetCreatedAt(now) - edp.SetUpdatedAt(now) - edp.BackfillSecretKeys() - - if err := edp.Valid(); err != nil { - return err - } - - ent := Entity{ - PK: EncID(edp.GetID()), - UniqueKey: Encode(EncID(edp.GetOrgID()), EncString(edp.GetName())), - Body: edp, - } - if err := s.endpointStore.Put(ctx, tx, ent, PutNew()); err != nil { - return err - } - - urm := &influxdb.UserResourceMapping{ - ResourceID: edp.GetID(), - UserID: userID, - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - } - return s.createUserResourceMapping(ctx, tx, urm) -} - -// UpdateNotificationEndpoint updates a single notification endpoint. -// Returns the new notification endpoint after update. -func (s *Service) UpdateNotificationEndpoint(ctx context.Context, id influxdb.ID, edp influxdb.NotificationEndpoint, userID influxdb.ID) (influxdb.NotificationEndpoint, error) { - var err error - err = s.kv.Update(ctx, func(tx Tx) error { - edp, err = s.updateNotificationEndpoint(ctx, tx, id, edp, userID) - return err - }) - return edp, err -} - -func (s *Service) updateNotificationEndpoint(ctx context.Context, tx Tx, id influxdb.ID, edp influxdb.NotificationEndpoint, userID influxdb.ID) (influxdb.NotificationEndpoint, error) { - current, err := s.findNotificationEndpointByID(ctx, tx, id) - if err != nil { - return nil, err - } - - // ID and OrganizationID can not be updated - edp.SetCreatedAt(current.GetCRUDLog().CreatedAt) - edp.SetUpdatedAt(s.TimeGenerator.Now()) - - if err := edp.Valid(); err != nil { - return nil, err - } - - ent := Entity{ - PK: EncID(edp.GetID()), - UniqueKey: Encode(EncID(edp.GetOrgID()), EncString(edp.GetName())), - Body: edp, - } - if err := s.endpointStore.Put(ctx, tx, ent, PutUpdate()); err != nil { - return nil, err - } - - return edp, nil -} - -// PatchNotificationEndpoint updates a single notification endpoint with changeset. -// Returns the new notification endpoint state after update. -func (s *Service) PatchNotificationEndpoint(ctx context.Context, id influxdb.ID, upd influxdb.NotificationEndpointUpdate) (influxdb.NotificationEndpoint, error) { - var edp influxdb.NotificationEndpoint - if err := s.kv.Update(ctx, func(tx Tx) (err error) { - edp, err = s.patchNotificationEndpoint(ctx, tx, id, upd) - if err != nil { - return err - } - return nil - }); err != nil { - return nil, err - } - - return edp, nil -} - -func (s *Service) patchNotificationEndpoint(ctx context.Context, tx Tx, id influxdb.ID, upd influxdb.NotificationEndpointUpdate) (influxdb.NotificationEndpoint, error) { - edp, err := s.findNotificationEndpointByID(ctx, tx, id) - if err != nil { - return nil, err - } - - if upd.Name != nil { - edp.SetName(*upd.Name) - } - if upd.Description != nil { - edp.SetDescription(*upd.Description) - } - if upd.Status != nil { - edp.SetStatus(*upd.Status) - } - edp.SetUpdatedAt(s.TimeGenerator.Now()) - - if err := edp.Valid(); err != nil { - return nil, err - } - - // TODO(jsteenb2): every above here moves into service layer - - ent := Entity{ - PK: EncID(edp.GetID()), - UniqueKey: Encode(EncID(edp.GetOrgID()), EncString(edp.GetName())), - Body: edp, - } - if err := s.endpointStore.Put(ctx, tx, ent, PutUpdate()); err != nil { - return nil, err - } - - return edp, nil -} - -// PutNotificationEndpoint put a notification endpoint to storage. -func (s *Service) PutNotificationEndpoint(ctx context.Context, edp influxdb.NotificationEndpoint) error { - // TODO(jsteenb2): all the stuffs before the update should be moved up into the - // service layer as well as all the id/time setting items - if err := edp.Valid(); err != nil { - return err - } - - return s.kv.Update(ctx, func(tx Tx) (err error) { - ent := Entity{ - PK: EncID(edp.GetID()), - UniqueKey: Encode(EncID(edp.GetOrgID()), EncString(edp.GetName())), - Body: edp, - } - return s.endpointStore.Put(ctx, tx, ent) - }) -} - -// FindNotificationEndpointByID returns a single notification endpoint by ID. -func (s *Service) FindNotificationEndpointByID(ctx context.Context, id influxdb.ID) (influxdb.NotificationEndpoint, error) { - var ( - edp influxdb.NotificationEndpoint - err error - ) - - err = s.kv.View(ctx, func(tx Tx) error { - edp, err = s.findNotificationEndpointByID(ctx, tx, id) - return err - }) - - return edp, err -} - -func (s *Service) findNotificationEndpointByID(ctx context.Context, tx Tx, id influxdb.ID) (influxdb.NotificationEndpoint, error) { - decodedEnt, err := s.endpointStore.FindEnt(ctx, tx, Entity{PK: EncID(id)}) - if err != nil { - return nil, err - } - edp, ok := decodedEnt.(influxdb.NotificationEndpoint) - return edp, IsErrUnexpectedDecodeVal(ok) -} - -// FindNotificationEndpoints returns a list of notification endpoints that match isNext and the total count of matching notification endpoints. -// Additional options provide pagination & sorting. -func (s *Service) FindNotificationEndpoints(ctx context.Context, filter influxdb.NotificationEndpointFilter, opt ...influxdb.FindOptions) (edps []influxdb.NotificationEndpoint, n int, err error) { - err = s.kv.View(ctx, func(tx Tx) error { - edps, n, err = s.findNotificationEndpoints(ctx, tx, filter, opt...) - return err - }) - return edps, n, err -} - -func (s *Service) findNotificationEndpoints(ctx context.Context, tx Tx, filter influxdb.NotificationEndpointFilter, opt ...influxdb.FindOptions) ([]influxdb.NotificationEndpoint, int, error) { - m, err := s.findUserResourceMappings(ctx, tx, filter.UserResourceMappingFilter) - if err != nil { - return nil, 0, err - } - - if len(m) == 0 { - return []influxdb.NotificationEndpoint{}, 0, nil - } - - idMap := make(map[influxdb.ID]bool) - for _, item := range m { - idMap[item.ResourceID] = true - } - - if filter.Org != nil { - o, err := s.findOrganizationByName(ctx, tx, *filter.Org) - if err != nil { - return nil, 0, &influxdb.Error{ - Err: err, - } - } - filter.OrgID = &o.ID - } - - var o influxdb.FindOptions - if len(opt) > 0 { - o = opt[0] - } - - edps := make([]influxdb.NotificationEndpoint, 0) - err = s.endpointStore.Find(ctx, tx, FindOpts{ - Descending: o.Descending, - Offset: o.Offset, - Limit: o.Limit, - FilterEntFn: filterEndpointsFn(idMap, filter), - CaptureFn: func(k []byte, v interface{}) error { - edp, ok := v.(influxdb.NotificationEndpoint) - if err := IsErrUnexpectedDecodeVal(ok); err != nil { - return err - } - edps = append(edps, edp) - return nil - }, - }) - if err != nil { - return nil, 0, err - } - - return edps, len(edps), err -} - -func filterEndpointsFn(idMap map[influxdb.ID]bool, filter influxdb.NotificationEndpointFilter) func([]byte, interface{}) bool { - return func(key []byte, val interface{}) bool { - edp := val.(influxdb.NotificationEndpoint) - if filter.ID != nil && edp.GetID() != *filter.ID { - return false - } - - if filter.OrgID != nil && edp.GetOrgID() != *filter.OrgID { - return false - } - - if idMap == nil { - return true - } - return idMap[edp.GetID()] - } -} - -// DeleteNotificationEndpoint removes a notification endpoint by ID. -func (s *Service) DeleteNotificationEndpoint(ctx context.Context, id influxdb.ID) (flds []influxdb.SecretField, orgID influxdb.ID, err error) { - err = s.kv.Update(ctx, func(tx Tx) error { - flds, orgID, err = s.deleteNotificationEndpoint(ctx, tx, id) - return err - }) - return flds, orgID, err -} - -func (s *Service) deleteNotificationEndpoint(ctx context.Context, tx Tx, id influxdb.ID) (flds []influxdb.SecretField, orgID influxdb.ID, err error) { - edp, err := s.findNotificationEndpointByID(ctx, tx, id) - if err != nil { - return nil, 0, err - } - - if err := s.endpointStore.DeleteEnt(ctx, tx, Entity{PK: EncID(id)}); err != nil { - return nil, 0, err - } - - return edp.SecretFields(), edp.GetOrgID(), s.deleteUserResourceMappings(ctx, tx, influxdb.UserResourceMappingFilter{ - ResourceID: id, - ResourceType: influxdb.NotificationEndpointResourceType, - }) -} diff --git a/kv/notification_endpoint_test.go b/kv/notification_endpoint_test.go deleted file mode 100644 index 96c3f8842c8..00000000000 --- a/kv/notification_endpoint_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package kv_test - -import ( - "context" - "testing" - - "github.com/influxdata/influxdb/v2" - "github.com/influxdata/influxdb/v2/endpoints" - "github.com/influxdata/influxdb/v2/kv" - influxdbtesting "github.com/influxdata/influxdb/v2/testing" - "go.uber.org/zap/zaptest" -) - -func TestNotificationEndpointService(t *testing.T) { - influxdbtesting.NotificationEndpointService(initBoltNotificationEndpointService, t) -} - -func initBoltNotificationEndpointService(f influxdbtesting.NotificationEndpointFields, t *testing.T) (influxdb.NotificationEndpointService, influxdb.SecretService, func()) { - store, closeBolt, err := NewTestBoltStore(t) - if err != nil { - t.Fatalf("failed to create new kv store: %v", err) - } - - svc, secretSVC, closeSvc := initNotificationEndpointService(store, f, t) - return svc, secretSVC, func() { - closeSvc() - closeBolt() - } -} - -func initNotificationEndpointService(s kv.SchemaStore, f influxdbtesting.NotificationEndpointFields, t *testing.T) (influxdb.NotificationEndpointService, influxdb.SecretService, func()) { - ctx := context.Background() - svc := kv.NewService(zaptest.NewLogger(t), s) - svc.IDGenerator = f.IDGenerator - svc.TimeGenerator = f.TimeGenerator - if f.TimeGenerator == nil { - svc.TimeGenerator = influxdb.RealTimeGenerator{} - } - - for _, edp := range f.NotificationEndpoints { - if err := svc.PutNotificationEndpoint(ctx, edp); err != nil { - t.Fatalf("failed to populate notification endpoint: %v", err) - } - } - - for _, o := range f.Orgs { - if err := svc.PutOrganization(ctx, o); err != nil { - t.Fatalf("failed to populate org: %v", err) - } - } - - for _, m := range f.UserResourceMappings { - if err := svc.CreateUserResourceMapping(ctx, m); err != nil { - t.Fatalf("failed to populate user resource mapping: %v", err) - } - } - - endpointSVC := endpoints.NewService(svc, svc, svc, svc) - return endpointSVC, svc, func() { - for _, edp := range f.NotificationEndpoints { - if _, _, err := svc.DeleteNotificationEndpoint(ctx, edp.GetID()); err != nil && err != kv.ErrNotificationEndpointNotFound { - t.Logf("failed to remove notification endpoint: %v", err) - } - } - for _, o := range f.Orgs { - if err := svc.DeleteOrganization(ctx, o.ID); err != nil { - t.Fatalf("failed to remove org: %v", err) - } - } - - for _, urm := range f.UserResourceMappings { - if err := svc.DeleteUserResourceMapping(ctx, urm.ResourceID, urm.UserID); err != nil && influxdb.ErrorCode(err) != influxdb.ENotFound { - t.Logf("failed to remove urm rule: %v", err) - } - } - } -} diff --git a/kv/service.go b/kv/service.go index 9a7cd63f793..5829df96465 100644 --- a/kv/service.go +++ b/kv/service.go @@ -45,7 +45,6 @@ type Service struct { Hash Crypt checkStore *IndexStore - endpointStore *IndexStore variableStore *IndexStore urmByUserIndex *Index @@ -65,7 +64,6 @@ func NewService(log *zap.Logger, kv Store, configs ...ServiceConfig) *Service { audit: noop.ResourceLogger{}, TimeGenerator: influxdb.RealTimeGenerator{}, checkStore: newCheckStore(), - endpointStore: newEndpointStore(), variableStore: newVariableStore(), urmByUserIndex: NewIndex(URMByUserIndexMapping, WithIndexReadPathEnabled), } diff --git a/notification/endpoint/endpoint_test.go b/notification/endpoint/endpoint_test.go index db16e9130fb..e592a7dd020 100644 --- a/notification/endpoint/endpoint_test.go +++ b/notification/endpoint/endpoint_test.go @@ -6,25 +6,18 @@ import ( "net/http" "net/url" "testing" - "time" "github.com/google/go-cmp/cmp" "github.com/influxdata/influxdb/v2" "github.com/influxdata/influxdb/v2/kit/errors" - "github.com/influxdata/influxdb/v2/mock" "github.com/influxdata/influxdb/v2/notification/endpoint" influxTesting "github.com/influxdata/influxdb/v2/testing" ) -const ( - id1 = "020f755c3c082000" - id3 = "020f755c3c082002" -) - var goodBase = endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, Description: "desc1", } @@ -48,9 +41,9 @@ func TestValidEndpoint(t *testing.T) { name: "invalid status", src: &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, }, }, err: &influxdb.Error{ @@ -62,12 +55,12 @@ func TestValidEndpoint(t *testing.T) { name: "empty name PagerDuty", src: &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), - OrgID: influxTesting.MustIDBase16Ptr(id3), + ID: id1, + OrgID: id3, Status: influxdb.Active, }, ClientURL: "https://events.pagerduty.com/v2/enqueue", - RoutingKey: influxdb.SecretField{Key: id1 + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: id1.String() + "-routing-key"}, }, err: &influxdb.Error{ Code: influxdb.EInvalid, @@ -78,11 +71,11 @@ func TestValidEndpoint(t *testing.T) { name: "empty name Telegram", src: &endpoint.Telegram{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), - OrgID: influxTesting.MustIDBase16Ptr(id3), + ID: id1, + OrgID: id3, Status: influxdb.Active, }, - Token: influxdb.SecretField{Key: id1 + "-token"}, + Token: influxdb.SecretField{Key: id1.String() + "-token"}, Channel: "-1001406363649", }, err: &influxdb.Error{ @@ -177,7 +170,7 @@ func TestValidEndpoint(t *testing.T) { name: "empty telegram channel", src: &endpoint.Telegram{ Base: goodBase, - Token: influxdb.SecretField{Key: id1 + "-token"}, + Token: influxdb.SecretField{Key: id1.String() + "-token"}, }, err: &influxdb.Error{ Code: influxdb.EInvalid, @@ -188,7 +181,7 @@ func TestValidEndpoint(t *testing.T) { name: "valid telegram token", src: &endpoint.Telegram{ Base: goodBase, - Token: influxdb.SecretField{Key: id1 + "-token"}, + Token: influxdb.SecretField{Key: id1.String() + "-token"}, Channel: "-1001406363649", }, err: nil, @@ -208,9 +201,6 @@ func TestValidEndpoint(t *testing.T) { } } -var timeGen1 = mock.TimeGenerator{FakeValue: time.Date(2006, time.July, 13, 4, 19, 10, 0, time.UTC)} -var timeGen2 = mock.TimeGenerator{FakeValue: time.Date(2006, time.July, 14, 5, 23, 53, 10, time.UTC)} - func TestJSON(t *testing.T) { cases := []struct { name string @@ -220,9 +210,9 @@ func TestJSON(t *testing.T) { name: "simple Slack", src: &endpoint.Slack{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -237,9 +227,9 @@ func TestJSON(t *testing.T) { name: "Slack without token", src: &endpoint.Slack{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -253,9 +243,9 @@ func TestJSON(t *testing.T) { name: "simple pagerduty", src: &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -270,9 +260,9 @@ func TestJSON(t *testing.T) { name: "simple http", src: &endpoint.HTTP{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -293,9 +283,9 @@ func TestJSON(t *testing.T) { name: "simple Telegram", src: &endpoint.Telegram{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "nameTelegram", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -331,9 +321,9 @@ func TestBackFill(t *testing.T) { name: "simple Slack", src: &endpoint.Slack{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -347,9 +337,9 @@ func TestBackFill(t *testing.T) { }, target: &endpoint.Slack{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -358,7 +348,7 @@ func TestBackFill(t *testing.T) { }, URL: "https://slack.com/api/chat.postMessage", Token: influxdb.SecretField{ - Key: id1 + "-token", + Key: id1.String() + "-token", Value: strPtr("token-value"), }, }, @@ -367,9 +357,9 @@ func TestBackFill(t *testing.T) { name: "simple pagerduty", src: &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -383,9 +373,9 @@ func TestBackFill(t *testing.T) { }, target: &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -394,7 +384,7 @@ func TestBackFill(t *testing.T) { }, ClientURL: "https://events.pagerduty.com/v2/enqueue", RoutingKey: influxdb.SecretField{ - Key: id1 + "-routing-key", + Key: id1.String() + "-routing-key", Value: strPtr("routing-key-value"), }, }, @@ -403,9 +393,9 @@ func TestBackFill(t *testing.T) { name: "http with token", src: &endpoint.HTTP{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -423,9 +413,9 @@ func TestBackFill(t *testing.T) { }, target: &endpoint.HTTP{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -435,11 +425,11 @@ func TestBackFill(t *testing.T) { AuthMethod: "basic", URL: "http://example.com", Username: influxdb.SecretField{ - Key: id1 + "-username", + Key: id1.String() + "-username", Value: strPtr("username1"), }, Password: influxdb.SecretField{ - Key: id1 + "-password", + Key: id1.String() + "-password", Value: strPtr("password1"), }, }, @@ -448,9 +438,9 @@ func TestBackFill(t *testing.T) { name: "simple Telegram", src: &endpoint.Telegram{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -463,9 +453,9 @@ func TestBackFill(t *testing.T) { }, target: &endpoint.Telegram{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -473,7 +463,7 @@ func TestBackFill(t *testing.T) { }, }, Token: influxdb.SecretField{ - Key: id1 + "-token", + Key: id1.String() + "-token", Value: strPtr("token-value"), }, }, @@ -497,9 +487,9 @@ func TestSecretFields(t *testing.T) { name: "simple Slack", src: &endpoint.Slack{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -508,13 +498,13 @@ func TestSecretFields(t *testing.T) { }, URL: "https://slack.com/api/chat.postMessage", Token: influxdb.SecretField{ - Key: id1 + "-token", + Key: id1.String() + "-token", Value: strPtr("token-value"), }, }, secrets: []influxdb.SecretField{ { - Key: id1 + "-token", + Key: id1.String() + "-token", Value: strPtr("token-value"), }, }, @@ -523,9 +513,9 @@ func TestSecretFields(t *testing.T) { name: "simple pagerduty", src: &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -534,13 +524,13 @@ func TestSecretFields(t *testing.T) { }, ClientURL: "https://events.pagerduty.com/v2/enqueue", RoutingKey: influxdb.SecretField{ - Key: id1 + "-routing-key", + Key: id1.String() + "-routing-key", Value: strPtr("routing-key-value"), }, }, secrets: []influxdb.SecretField{ { - Key: id1 + "-routing-key", + Key: id1.String() + "-routing-key", Value: strPtr("routing-key-value"), }, }, @@ -549,9 +539,9 @@ func TestSecretFields(t *testing.T) { name: "http with user and password", src: &endpoint.HTTP{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -561,21 +551,21 @@ func TestSecretFields(t *testing.T) { AuthMethod: "basic", URL: "http://example.com", Username: influxdb.SecretField{ - Key: id1 + "-username", + Key: id1.String() + "-username", Value: strPtr("user1"), }, Password: influxdb.SecretField{ - Key: id1 + "-password", + Key: id1.String() + "-password", Value: strPtr("password1"), }, }, secrets: []influxdb.SecretField{ { - Key: id1 + "-username", + Key: id1.String() + "-username", Value: strPtr("user1"), }, { - Key: id1 + "-password", + Key: id1.String() + "-password", Value: strPtr("password1"), }, }, @@ -584,9 +574,9 @@ func TestSecretFields(t *testing.T) { name: "simple Telegram", src: &endpoint.Telegram{ Base: endpoint.Base{ - ID: influxTesting.MustIDBase16Ptr(id1), + ID: id1, Name: "name1", - OrgID: influxTesting.MustIDBase16Ptr(id3), + OrgID: id3, Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -594,13 +584,13 @@ func TestSecretFields(t *testing.T) { }, }, Token: influxdb.SecretField{ - Key: id1 + "-token", + Key: id1.String() + "-token", Value: strPtr("token-value"), }, }, secrets: []influxdb.SecretField{ { - Key: id1 + "-token", + Key: id1.String() + "-token", Value: strPtr("token-value"), }, }, diff --git a/endpoints/service.go b/notification/endpoint/service/service.go similarity index 84% rename from endpoints/service.go rename to notification/endpoint/service/service.go index 76c402479aa..418805f6845 100644 --- a/endpoints/service.go +++ b/notification/endpoint/service/service.go @@ -1,28 +1,22 @@ -package endpoints +package service import ( "context" - "github.com/influxdata/influxdb/v2" + influxdb "github.com/influxdata/influxdb/v2" ) // Service provides all the notification endpoint service behavior. type Service struct { endpointStore influxdb.NotificationEndpointService secretSVC influxdb.SecretService - - // TODO(jsteenb2): NUKE THESE 2 embedded services after fixing up the domain! - influxdb.UserResourceMappingService - influxdb.OrganizationService } -// NewService constructs a new Service. -func NewService(store influxdb.NotificationEndpointService, secretSVC influxdb.SecretService, urmSVC influxdb.UserResourceMappingService, orgSVC influxdb.OrganizationService) *Service { +// New constructs a new Service. +func New(store influxdb.NotificationEndpointService, secretSVC influxdb.SecretService) *Service { return &Service{ - endpointStore: store, - secretSVC: secretSVC, - UserResourceMappingService: urmSVC, - OrganizationService: orgSVC, + endpointStore: store, + secretSVC: secretSVC, } } diff --git a/endpoints/service_test.go b/notification/endpoint/service/service_test.go similarity index 76% rename from endpoints/service_test.go rename to notification/endpoint/service/service_test.go index 2523b1f3abf..a3976082dce 100644 --- a/endpoints/service_test.go +++ b/notification/endpoint/service/service_test.go @@ -1,45 +1,44 @@ -package endpoints_test +package service_test import ( "context" "testing" "time" - "github.com/influxdata/influxdb/v2" - "github.com/influxdata/influxdb/v2/endpoints" + influxdb "github.com/influxdata/influxdb/v2" "github.com/influxdata/influxdb/v2/inmem" "github.com/influxdata/influxdb/v2/kv" "github.com/influxdata/influxdb/v2/kv/migration/all" "github.com/influxdata/influxdb/v2/mock" "github.com/influxdata/influxdb/v2/notification/endpoint" + "github.com/influxdata/influxdb/v2/notification/endpoint/service" + "github.com/influxdata/influxdb/v2/pkg/pointer" + "github.com/influxdata/influxdb/v2/tenant" influxTesting "github.com/influxdata/influxdb/v2/testing" + "go.uber.org/zap" "go.uber.org/zap/zaptest" ) -var id1 = influxTesting.MustIDBase16Ptr("020f755c3c082000") -var id2 = influxTesting.MustIDBase16Ptr("020f755c3c082001") -var orgID = influxTesting.MustIDBase16Ptr("a10f755c3c082001") -var userID = influxTesting.MustIDBase16Ptr("b10f755c3c082001") +var ( + id1 = influxTesting.MustIDBase16Ptr("020f755c3c082000") + id2 = influxTesting.MustIDBase16Ptr("020f755c3c082001") + id3 = influxTesting.MustIDBase16Ptr("020f755c3c082002") + orgID = influxTesting.MustIDBase16Ptr("a10f755c3c082001") + userID = influxTesting.MustIDBase16Ptr("b10f755c3c082001") -var timeGen1 = mock.TimeGenerator{FakeValue: time.Date(2006, time.July, 13, 4, 19, 10, 0, time.UTC)} -var timeGen2 = mock.TimeGenerator{FakeValue: time.Date(2006, time.July, 14, 5, 23, 53, 10, time.UTC)} -var testCrudLog = influxdb.CRUDLog{ - CreatedAt: timeGen1.Now(), - UpdatedAt: timeGen2.Now(), -} + timeGen1 = mock.TimeGenerator{FakeValue: time.Date(2006, time.July, 13, 4, 19, 10, 0, time.UTC)} + timeGen2 = mock.TimeGenerator{FakeValue: time.Date(2006, time.July, 14, 5, 23, 53, 10, time.UTC)} -// newInmemService creates a new in-memory secret service -func newInmemService(t *testing.T) *kv.Service { + testCrudLog = influxdb.CRUDLog{ + CreatedAt: timeGen1.Now(), + UpdatedAt: timeGen2.Now(), + } +) + +func newSecretService(t *testing.T, ctx context.Context, logger *zap.Logger, s kv.Store) influxdb.SecretService { t.Helper() - store := inmem.NewKVStore() - logger := zaptest.NewLogger(t) - ctx := context.Background() - // initialize the store - if err := all.Up(ctx, logger, store); err != nil { - t.Fatal(err) - } - svc := kv.NewService(logger, store) + tenantSvc := tenant.NewService(tenant.NewStore(s)) // initialize organization org := influxdb.Organization{ @@ -48,21 +47,26 @@ func newInmemService(t *testing.T) *kv.Service { CRUDLog: testCrudLog, } - if err := svc.CreateOrganization(ctx, &org); err != nil { + if err := tenantSvc.CreateOrganization(ctx, &org); err != nil { t.Fatal(err) } orgID = &org.ID // orgID is generated - return svc + return kv.NewService(logger, s) } // TestEndpointService_cummulativeSecrets tests that secrets are cummulatively added/updated and removed upon delete // see https://github.com/influxdata/influxdb/pull/19082 for details func TestEndpointService_cummulativeSecrets(t *testing.T) { - inMemService := newInmemService(t) - endpointService := endpoints.NewService(inMemService, inMemService, inMemService, inMemService) - secretService := inMemService ctx := context.Background() + store := inmem.NewKVStore() + logger := zaptest.NewLogger(t) + if err := all.Up(ctx, logger, store); err != nil { + t.Fatal(err) + } + + secretService := newSecretService(t, ctx, logger, store) + endpointService := service.New(service.NewStore(store), secretService) var endpoint1 = endpoint.HTTP{ Base: endpoint.Base{ @@ -79,8 +83,8 @@ func TestEndpointService_cummulativeSecrets(t *testing.T) { AuthMethod: "basic", Method: "POST", URL: "http://example.com", - Username: influxdb.SecretField{Key: id1.String() + "username-key", Value: strPtr("val1")}, - Password: influxdb.SecretField{Key: id1.String() + "password-key", Value: strPtr("val2")}, + Username: influxdb.SecretField{Key: id1.String() + "username-key", Value: pointer.String("val1")}, + Password: influxdb.SecretField{Key: id1.String() + "password-key", Value: pointer.String("val2")}, } var endpoint2 = endpoint.HTTP{ Base: endpoint.Base{ @@ -97,8 +101,8 @@ func TestEndpointService_cummulativeSecrets(t *testing.T) { AuthMethod: "basic", Method: "POST", URL: "http://example2.com", - Username: influxdb.SecretField{Key: id2.String() + "username-key", Value: strPtr("val3")}, - Password: influxdb.SecretField{Key: id2.String() + "password-key", Value: strPtr("val4")}, + Username: influxdb.SecretField{Key: id2.String() + "username-key", Value: pointer.String("val3")}, + Password: influxdb.SecretField{Key: id2.String() + "password-key", Value: pointer.String("val4")}, } var err error var secretKeys []string @@ -127,7 +131,7 @@ func TestEndpointService_cummulativeSecrets(t *testing.T) { // update 1st endpoint and validate secrets const updatedSecretValue = "updatedSecVal" - endpoint1.Username.Value = strPtr(updatedSecretValue) + endpoint1.Username.Value = pointer.String(updatedSecretValue) if _, err = endpointService.UpdateNotificationEndpoint(ctx, *endpoint1.ID, &endpoint1, *userID); err != nil { t.Fatal(err) } @@ -175,8 +179,3 @@ func TestEndpointService_cummulativeSecrets(t *testing.T) { t.Errorf("secrets after deleting the 2nd endpoint = %v, want %v", len(secretKeys), 2) } } - -// strPtr returns string pointer -func strPtr(s string) *string { - return &s -} diff --git a/notification/endpoint/service/store.go b/notification/endpoint/service/store.go new file mode 100644 index 00000000000..bc2da6c31be --- /dev/null +++ b/notification/endpoint/service/store.go @@ -0,0 +1,305 @@ +package service + +import ( + "context" + + influxdb "github.com/influxdata/influxdb/v2" + "github.com/influxdata/influxdb/v2/kv" + "github.com/influxdata/influxdb/v2/notification/endpoint" + "github.com/influxdata/influxdb/v2/snowflake" +) + +var ( + // ErrNotificationEndpointNotFound is used when the notification endpoint is not found. + ErrNotificationEndpointNotFound = &influxdb.Error{ + Msg: "notification endpoint not found", + Code: influxdb.ENotFound, + } + + notificationEndpointBucket = []byte("notificationEndpointv1") + notificationEndpointIndexBucket = []byte("notificationEndpointIndexv1") +) + +var _ influxdb.NotificationEndpointService = (*Store)(nil) + +func newEndpointStore() *kv.IndexStore { + const resource = "notification endpoint" + + var decEndpointEntFn kv.DecodeBucketValFn = func(key, val []byte) ([]byte, interface{}, error) { + edp, err := endpoint.UnmarshalJSON(val) + return key, edp, err + } + + var decValToEntFn kv.ConvertValToEntFn = func(_ []byte, v interface{}) (kv.Entity, error) { + edp, ok := v.(influxdb.NotificationEndpoint) + if err := kv.IsErrUnexpectedDecodeVal(ok); err != nil { + return kv.Entity{}, err + } + return kv.Entity{ + PK: kv.EncID(edp.GetID()), + UniqueKey: kv.Encode(kv.EncID(edp.GetOrgID()), kv.EncString(edp.GetName())), + Body: edp, + }, nil + } + + return &kv.IndexStore{ + Resource: resource, + EntStore: kv.NewStoreBase(resource, notificationEndpointBucket, kv.EncIDKey, kv.EncBodyJSON, decEndpointEntFn, decValToEntFn), + IndexStore: kv.NewOrgNameKeyStore(resource, notificationEndpointIndexBucket, true), + } +} + +type Store struct { + kv kv.Store + + endpointStore *kv.IndexStore + + IDGenerator influxdb.IDGenerator + TimeGenerator influxdb.TimeGenerator +} + +func NewStore(store kv.Store) *Store { + return &Store{ + kv: store, + endpointStore: newEndpointStore(), + IDGenerator: snowflake.NewDefaultIDGenerator(), + TimeGenerator: influxdb.RealTimeGenerator{}, + } +} + +// CreateNotificationEndpoint creates a new notification endpoint and sets b.ID with the new identifier. +func (s *Store) CreateNotificationEndpoint(ctx context.Context, edp influxdb.NotificationEndpoint, userID influxdb.ID) error { + return s.kv.Update(ctx, func(tx kv.Tx) error { + return s.createNotificationEndpoint(ctx, tx, edp, userID) + }) +} + +func (s *Store) createNotificationEndpoint(ctx context.Context, tx kv.Tx, edp influxdb.NotificationEndpoint, userID influxdb.ID) error { + id := s.IDGenerator.ID() + edp.SetID(id) + now := s.TimeGenerator.Now() + edp.SetCreatedAt(now) + edp.SetUpdatedAt(now) + edp.BackfillSecretKeys() + + if err := edp.Valid(); err != nil { + return err + } + + ent := kv.Entity{ + PK: kv.EncID(edp.GetID()), + UniqueKey: kv.Encode(kv.EncID(edp.GetOrgID()), kv.EncString(edp.GetName())), + Body: edp, + } + if err := s.endpointStore.Put(ctx, tx, ent, kv.PutNew()); err != nil { + return err + } + + return nil +} + +// UpdateNotificationEndpoint updates a single notification endpoint. +// Returns the new notification endpoint after update. +func (s *Store) UpdateNotificationEndpoint(ctx context.Context, id influxdb.ID, edp influxdb.NotificationEndpoint, userID influxdb.ID) (influxdb.NotificationEndpoint, error) { + var err error + err = s.kv.Update(ctx, func(tx kv.Tx) error { + edp, err = s.updateNotificationEndpoint(ctx, tx, id, edp, userID) + return err + }) + return edp, err +} + +func (s *Store) updateNotificationEndpoint(ctx context.Context, tx kv.Tx, id influxdb.ID, edp influxdb.NotificationEndpoint, userID influxdb.ID) (influxdb.NotificationEndpoint, error) { + current, err := s.findNotificationEndpointByID(ctx, tx, id) + if err != nil { + return nil, err + } + + // ID and OrganizationID can not be updated + edp.SetCreatedAt(current.GetCRUDLog().CreatedAt) + edp.SetUpdatedAt(s.TimeGenerator.Now()) + + if err := edp.Valid(); err != nil { + return nil, err + } + + ent := kv.Entity{ + PK: kv.EncID(edp.GetID()), + UniqueKey: kv.Encode(kv.EncID(edp.GetOrgID()), kv.EncString(edp.GetName())), + Body: edp, + } + if err := s.endpointStore.Put(ctx, tx, ent, kv.PutUpdate()); err != nil { + return nil, err + } + + return edp, nil +} + +// PatchNotificationEndpoint updates a single notification endpoint with changeset. +// Returns the new notification endpoint state after update. +func (s *Store) PatchNotificationEndpoint(ctx context.Context, id influxdb.ID, upd influxdb.NotificationEndpointUpdate) (influxdb.NotificationEndpoint, error) { + var edp influxdb.NotificationEndpoint + if err := s.kv.Update(ctx, func(tx kv.Tx) (err error) { + edp, err = s.patchNotificationEndpoint(ctx, tx, id, upd) + if err != nil { + return err + } + return nil + }); err != nil { + return nil, err + } + + return edp, nil +} + +func (s *Store) patchNotificationEndpoint(ctx context.Context, tx kv.Tx, id influxdb.ID, upd influxdb.NotificationEndpointUpdate) (influxdb.NotificationEndpoint, error) { + edp, err := s.findNotificationEndpointByID(ctx, tx, id) + if err != nil { + return nil, err + } + + if upd.Name != nil { + edp.SetName(*upd.Name) + } + if upd.Description != nil { + edp.SetDescription(*upd.Description) + } + if upd.Status != nil { + edp.SetStatus(*upd.Status) + } + edp.SetUpdatedAt(s.TimeGenerator.Now()) + + if err := edp.Valid(); err != nil { + return nil, err + } + + // TODO(jsteenb2): every above here moves into service layer + + ent := kv.Entity{ + PK: kv.EncID(edp.GetID()), + UniqueKey: kv.Encode(kv.EncID(edp.GetOrgID()), kv.EncString(edp.GetName())), + Body: edp, + } + if err := s.endpointStore.Put(ctx, tx, ent, kv.PutUpdate()); err != nil { + return nil, err + } + + return edp, nil +} + +// PutNotificationEndpoint put a notification endpoint to storage. +func (s *Store) PutNotificationEndpoint(ctx context.Context, edp influxdb.NotificationEndpoint) error { + // TODO(jsteenb2): all the stuffs before the update should be moved up into the + // service layer as well as all the id/time setting items + if err := edp.Valid(); err != nil { + return err + } + + return s.kv.Update(ctx, func(tx kv.Tx) (err error) { + ent := kv.Entity{ + PK: kv.EncID(edp.GetID()), + UniqueKey: kv.Encode(kv.EncID(edp.GetOrgID()), kv.EncString(edp.GetName())), + Body: edp, + } + return s.endpointStore.Put(ctx, tx, ent) + }) +} + +// FindNotificationEndpointByID returns a single notification endpoint by ID. +func (s *Store) FindNotificationEndpointByID(ctx context.Context, id influxdb.ID) (influxdb.NotificationEndpoint, error) { + var ( + edp influxdb.NotificationEndpoint + err error + ) + + err = s.kv.View(ctx, func(tx kv.Tx) error { + edp, err = s.findNotificationEndpointByID(ctx, tx, id) + return err + }) + + return edp, err +} + +func (s *Store) findNotificationEndpointByID(ctx context.Context, tx kv.Tx, id influxdb.ID) (influxdb.NotificationEndpoint, error) { + decodedEnt, err := s.endpointStore.FindEnt(ctx, tx, kv.Entity{PK: kv.EncID(id)}) + if err != nil { + return nil, err + } + edp, ok := decodedEnt.(influxdb.NotificationEndpoint) + return edp, kv.IsErrUnexpectedDecodeVal(ok) +} + +// FindNotificationEndpoints returns a list of notification endpoints that match isNext and the total count of matching notification endpoints. +// Additional options provide pagination & sorting. +func (s *Store) FindNotificationEndpoints(ctx context.Context, filter influxdb.NotificationEndpointFilter, opt ...influxdb.FindOptions) (edps []influxdb.NotificationEndpoint, n int, err error) { + err = s.kv.View(ctx, func(tx kv.Tx) error { + edps, n, err = s.findNotificationEndpoints(ctx, tx, filter, opt...) + return err + }) + return edps, n, err +} + +func (s *Store) findNotificationEndpoints(ctx context.Context, tx kv.Tx, filter influxdb.NotificationEndpointFilter, opt ...influxdb.FindOptions) ([]influxdb.NotificationEndpoint, int, error) { + var o influxdb.FindOptions + if len(opt) > 0 { + o = opt[0] + } + + edps := make([]influxdb.NotificationEndpoint, 0) + err := s.endpointStore.Find(ctx, tx, kv.FindOpts{ + Descending: o.Descending, + Offset: o.Offset, + Limit: o.Limit, + FilterEntFn: filterEndpointsFn(filter), + CaptureFn: func(k []byte, v interface{}) error { + edp, ok := v.(influxdb.NotificationEndpoint) + if err := kv.IsErrUnexpectedDecodeVal(ok); err != nil { + return err + } + edps = append(edps, edp) + return nil + }, + }) + if err != nil { + return nil, 0, err + } + + return edps, len(edps), err +} + +func filterEndpointsFn(filter influxdb.NotificationEndpointFilter) func([]byte, interface{}) bool { + return func(key []byte, val interface{}) bool { + edp := val.(influxdb.NotificationEndpoint) + if filter.ID != nil && edp.GetID() != *filter.ID { + return false + } + + if filter.OrgID != nil && edp.GetOrgID() != *filter.OrgID { + return false + } + + return true + } +} + +// DeleteNotificationEndpoint removes a notification endpoint by ID. +func (s *Store) DeleteNotificationEndpoint(ctx context.Context, id influxdb.ID) (flds []influxdb.SecretField, orgID influxdb.ID, err error) { + err = s.kv.Update(ctx, func(tx kv.Tx) error { + flds, orgID, err = s.deleteNotificationEndpoint(ctx, tx, id) + return err + }) + return flds, orgID, err +} + +func (s *Store) deleteNotificationEndpoint(ctx context.Context, tx kv.Tx, id influxdb.ID) (flds []influxdb.SecretField, orgID influxdb.ID, err error) { + edp, err := s.findNotificationEndpointByID(ctx, tx, id) + if err != nil { + return nil, 0, err + } + + if err := s.endpointStore.DeleteEnt(ctx, tx, kv.Entity{PK: kv.EncID(id)}); err != nil { + return nil, 0, err + } + + return edp.SecretFields(), edp.GetOrgID(), nil +} diff --git a/notification/endpoint/service/store_test.go b/notification/endpoint/service/store_test.go new file mode 100644 index 00000000000..e7fb7468e1f --- /dev/null +++ b/notification/endpoint/service/store_test.go @@ -0,0 +1,127 @@ +package service_test + +import ( + "context" + "io/ioutil" + "os" + "testing" + + influxdb "github.com/influxdata/influxdb/v2" + "github.com/influxdata/influxdb/v2/bolt" + "github.com/influxdata/influxdb/v2/inmem" + "github.com/influxdata/influxdb/v2/kit/errors" + "github.com/influxdata/influxdb/v2/kv" + "github.com/influxdata/influxdb/v2/kv/migration/all" + "github.com/influxdata/influxdb/v2/notification/endpoint/service" + endpointsTesting "github.com/influxdata/influxdb/v2/notification/endpoint/service/testing" + "github.com/influxdata/influxdb/v2/tenant" + "go.uber.org/zap/zaptest" +) + +func TestNotificationEndpointService_WithInmem(t *testing.T) { + endpointsTesting.NotificationEndpointService(initInmemNotificationEndpointService, t) +} + +func TestNotificationEndpointService_WithBolt(t *testing.T) { + endpointsTesting.NotificationEndpointService(initBoltNotificationEndpointService, t) +} + +func NewTestBoltStore(t *testing.T) (kv.SchemaStore, func(), error) { + f, err := ioutil.TempFile("", "influxdata-bolt-") + if err != nil { + return nil, nil, errors.New("unable to open temporary boltdb file") + } + f.Close() + + ctx := context.Background() + logger := zaptest.NewLogger(t) + path := f.Name() + + // skip fsync to improve test performance + s := bolt.NewKVStore(logger, path, bolt.WithNoSync) + if err := s.Open(context.Background()); err != nil { + return nil, nil, err + } + + if err := all.Up(ctx, logger, s); err != nil { + return nil, nil, err + } + + close := func() { + s.Close() + os.Remove(path) + } + + return s, close, nil +} + +func initBoltNotificationEndpointService(f endpointsTesting.NotificationEndpointFields, t *testing.T) (influxdb.NotificationEndpointService, influxdb.SecretService, func()) { + store, closeStore, err := NewTestBoltStore(t) + if err != nil { + t.Fatal(err) + } + + svc, secretSVC, closeSvc := initNotificationEndpointService(store, f, t) + return svc, secretSVC, func() { + closeSvc() + closeStore() + } +} + +func initInmemNotificationEndpointService(f endpointsTesting.NotificationEndpointFields, t *testing.T) (influxdb.NotificationEndpointService, influxdb.SecretService, func()) { + store := inmem.NewKVStore() + if err := all.Up(context.Background(), zaptest.NewLogger(t), store); err != nil { + t.Fatal(err) + } + + svc, secretSVC, closeSvc := initNotificationEndpointService(store, f, t) + return svc, secretSVC, closeSvc +} + +func initNotificationEndpointService(s kv.SchemaStore, f endpointsTesting.NotificationEndpointFields, t *testing.T) (influxdb.NotificationEndpointService, influxdb.SecretService, func()) { + ctx := context.Background() + logger := zaptest.NewLogger(t) + + tenantStore := tenant.NewStore(s) + if f.IDGenerator != nil { + tenantStore.OrgIDGen = f.IDGenerator + tenantStore.IDGen = f.IDGenerator + } + + tenantSvc := tenant.NewService(tenantStore) + + secretSvc := kv.NewService(logger, s) + + store := service.NewStore(s) + store.IDGenerator = f.IDGenerator + if f.TimeGenerator != nil { + store.TimeGenerator = f.TimeGenerator + } + + endpointSvc := service.New(store, secretSvc) + + for _, edp := range f.NotificationEndpoints { + if err := store.PutNotificationEndpoint(ctx, edp); err != nil { + t.Fatalf("failed to populate notification endpoint: %v", err) + } + } + + for _, o := range f.Orgs { + if err := tenantSvc.CreateOrganization(ctx, o); err != nil { + t.Fatalf("failed to populate org: %v", err) + } + } + + return endpointSvc, secretSvc, func() { + for _, edp := range f.NotificationEndpoints { + if _, _, err := endpointSvc.DeleteNotificationEndpoint(ctx, edp.GetID()); err != nil && err != service.ErrNotificationEndpointNotFound { + t.Logf("failed to remove notification endpoint: %v", err) + } + } + for _, o := range f.Orgs { + if err := tenantSvc.DeleteOrganization(ctx, o.ID); err != nil { + t.Fatalf("failed to remove org: %v", err) + } + } + } +} diff --git a/testing/notification_endpoint.go b/notification/endpoint/service/testing/service.go similarity index 55% rename from testing/notification_endpoint.go rename to notification/endpoint/service/testing/service.go index 1f71b3ab5f6..fdc6d9448c3 100644 --- a/testing/notification_endpoint.go +++ b/notification/endpoint/service/testing/service.go @@ -2,6 +2,7 @@ package testing import ( "context" + "fmt" "net/http" "sort" "strings" @@ -9,25 +10,37 @@ import ( "time" "github.com/google/go-cmp/cmp" - "github.com/influxdata/influxdb/v2" + influxdb "github.com/influxdata/influxdb/v2" "github.com/influxdata/influxdb/v2/mock" "github.com/influxdata/influxdb/v2/notification/endpoint" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +const ( + oneID = influxdb.ID(iota + 1) + twoID + threeID + fourID + fiveID + sixID +) + +var ( + fakeDate = time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC) + fakeGenerator = mock.TimeGenerator{FakeValue: fakeDate} + timeGen1 = mock.TimeGenerator{FakeValue: time.Date(2006, time.July, 13, 4, 19, 10, 0, time.UTC)} + timeGen2 = mock.TimeGenerator{FakeValue: time.Date(2006, time.July, 14, 5, 23, 53, 10, time.UTC)} +) + // NotificationEndpointFields includes prepopulated data for mapping tests. type NotificationEndpointFields struct { IDGenerator influxdb.IDGenerator TimeGenerator influxdb.TimeGenerator NotificationEndpoints []influxdb.NotificationEndpoint Orgs []*influxdb.Organization - UserResourceMappings []*influxdb.UserResourceMapping } -var timeGen1 = mock.TimeGenerator{FakeValue: time.Date(2006, time.July, 13, 4, 19, 10, 0, time.UTC)} -var timeGen2 = mock.TimeGenerator{FakeValue: time.Date(2006, time.July, 14, 5, 23, 53, 10, time.UTC)} - var notificationEndpointCmpOptions = cmp.Options{ cmp.Transformer("Sort", func(in []influxdb.NotificationEndpoint) []influxdb.NotificationEndpoint { out := append([]influxdb.NotificationEndpoint(nil), in...) @@ -93,7 +106,6 @@ func CreateNotificationEndpoint( type wants struct { err error notificationEndpoints []influxdb.NotificationEndpoint - userResourceMapping []*influxdb.UserResourceMapping } tests := []struct { @@ -105,27 +117,19 @@ func CreateNotificationEndpoint( { name: "basic create notification endpoint", fields: NotificationEndpointFields{ - IDGenerator: mock.NewIDGenerator(twoID, t), + IDGenerator: mock.NewStaticIDGenerator(twoID), TimeGenerator: fakeGenerator, Orgs: []*influxdb.Organization{ - {ID: MustIDBase16(fourID), Name: "org1"}, + {ID: fourID, Name: "org1"}, }, NotificationEndpoints: []influxdb.NotificationEndpoint{}, - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - ResourceType: influxdb.NotificationEndpointResourceType, - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - }, - }, }, args: args{ - userID: MustIDBase16(sixID), + userID: sixID, notificationEndpoint: &endpoint.PagerDuty{ Base: endpoint.Base{ Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, }, ClientURL: "example-pagerduty.com", @@ -138,31 +142,19 @@ func CreateNotificationEndpoint( notificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: fakeDate, UpdatedAt: fakeDate, }, }, - ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, - }, - }, - userResourceMapping: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - ResourceType: influxdb.NotificationEndpointResourceType, - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - }, - { - ResourceID: MustIDBase16(twoID), - ResourceType: influxdb.NotificationEndpointResourceType, - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, + ClientURL: "example-pagerduty.com", + RoutingKey: influxdb.SecretField{ + Key: fmt.Sprintf("%s-routing-key", twoID), + }, }, }, }, @@ -178,11 +170,6 @@ func CreateNotificationEndpoint( err := s.CreateNotificationEndpoint(ctx, tt.args.notificationEndpoint, tt.args.userID) ErrorsEqual(t, err, tt.wants.err) - urmFilter := influxdb.UserResourceMappingFilter{ - UserID: tt.args.userID, - ResourceType: influxdb.NotificationEndpointResourceType, - } - filter := influxdb.NotificationEndpointFilter{} edps, _, err := s.FindNotificationEndpoints(ctx, filter) if err != nil { @@ -192,14 +179,6 @@ func CreateNotificationEndpoint( t.Errorf("notificationEndpoints are different -got/+want\ndiff %s", diff) } - urms, _, err := s.FindUserResourceMappings(ctx, urmFilter) - if err != nil { - t.Fatalf("failed to retrieve user resource mappings: %v", err) - } - if diff := cmp.Diff(urms, tt.wants.userResourceMapping, userResourceMappingCmpOptions...); diff != "" { - t.Errorf("user resource mappings are different -got/+want\ndiff %s", diff) - } - for _, edp := range tt.wants.notificationEndpoints { secrets, err := secretSVC.GetSecretKeys(ctx, edp.GetOrgID()) if err != nil { @@ -235,48 +214,38 @@ func FindNotificationEndpointByID( { name: "bad id", fields: NotificationEndpointFields{ - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), UpdatedAt: timeGen2.Now(), }, }, - URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + URL: "example-slack.com", + Token: influxdb.SecretField{ + Key: fmt.Sprintf("%s-token", oneID), + }, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), UpdatedAt: timeGen2.Now(), }, }, - ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + ClientURL: "example-pagerduty.com", + RoutingKey: influxdb.SecretField{ + Key: fmt.Sprintf("%s-routing-key", twoID), + }, }, }, }, @@ -293,26 +262,12 @@ func FindNotificationEndpointByID( { name: "not found", fields: NotificationEndpointFields{ - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -320,13 +275,13 @@ func FindNotificationEndpointByID( }, }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -334,12 +289,12 @@ func FindNotificationEndpointByID( }, }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, args: args{ - id: MustIDBase16(threeID), + id: threeID, }, wants: wants{ err: &influxdb.Error{ @@ -351,26 +306,12 @@ func FindNotificationEndpointByID( { name: "basic find telegraf config by id", fields: NotificationEndpointFields{ - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -378,13 +319,13 @@ func FindNotificationEndpointByID( }, }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -392,19 +333,19 @@ func FindNotificationEndpointByID( }, }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, args: args{ - id: MustIDBase16(twoID), + id: twoID, }, wants: wants{ notificationEndpoint: &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -412,7 +353,7 @@ func FindNotificationEndpointByID( }, }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, @@ -467,26 +408,12 @@ func FindNotificationEndpoints( { name: "find all notification endpoints", fields: NotificationEndpointFields{ - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -494,13 +421,13 @@ func FindNotificationEndpoints( }, }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -508,15 +435,7 @@ func FindNotificationEndpoints( }, }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, - }, - }, - }, - args: args{ - filter: influxdb.NotificationEndpointFilter{ - UserResourceMappingFilter: influxdb.UserResourceMappingFilter{ - UserID: MustIDBase16(sixID), - ResourceType: influxdb.NotificationEndpointResourceType, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, @@ -524,9 +443,9 @@ func FindNotificationEndpoints( notificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -534,13 +453,13 @@ func FindNotificationEndpoints( }, }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -548,7 +467,7 @@ func FindNotificationEndpoints( }, }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, @@ -558,183 +477,63 @@ func FindNotificationEndpoints( fields: NotificationEndpointFields{ Orgs: []*influxdb.Organization{ { - ID: MustIDBase16(oneID), + ID: oneID, Name: "org1", }, { - ID: MustIDBase16(fourID), + ID: fourID, Name: "org4", }, }, - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(fourID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(oneID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp1", }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(twoID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp2", }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(fourID), - OrgID: MustIDBase16Ptr(oneID), + ID: idPtr(fourID), + OrgID: idPtr(oneID), Status: influxdb.Active, Name: "edp3", }, ClientURL: "example-pagerduty2.com", - RoutingKey: influxdb.SecretField{Key: fourID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", fourID)}, }, }, }, args: args{ filter: influxdb.NotificationEndpointFilter{ - OrgID: idPtr(MustIDBase16(oneID)), - UserResourceMappingFilter: influxdb.UserResourceMappingFilter{ - ResourceType: influxdb.NotificationEndpointResourceType, - UserID: MustIDBase16(sixID), - }, + OrgID: idPtr(oneID), }, }, wants: wants{ notificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(fourID), - OrgID: MustIDBase16Ptr(oneID), + ID: idPtr(fourID), + OrgID: idPtr(oneID), Status: influxdb.Active, Name: "edp3", }, ClientURL: "example-pagerduty2.com", - RoutingKey: influxdb.SecretField{Key: fourID + "-routing-key"}, - }, - }, - }, - }, - { - name: "filter by organization name only", - fields: NotificationEndpointFields{ - Orgs: []*influxdb.Organization{ - { - ID: MustIDBase16(oneID), - Name: "org1", - }, - { - ID: MustIDBase16(fourID), - Name: "org4", - }, - }, - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, - NotificationEndpoints: []influxdb.NotificationEndpoint{ - &endpoint.Slack{ - Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), - OrgID: MustIDBase16Ptr(fourID), - Status: influxdb.Active, - Name: "edp1", - }, - URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, - }, - &endpoint.HTTP{ - Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), - OrgID: MustIDBase16Ptr(fourID), - Status: influxdb.Active, - Name: "edp2", - }, - URL: "example-webhook.com", - Method: http.MethodGet, - AuthMethod: "none", - }, - &endpoint.PagerDuty{ - Base: endpoint.Base{ - ID: MustIDBase16Ptr(fourID), - OrgID: MustIDBase16Ptr(oneID), - Status: influxdb.Active, - Name: "edp3", - }, - ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: fourID + "-routing-key"}, - }, - }, - }, - args: args{ - filter: influxdb.NotificationEndpointFilter{ - Org: strPtr("org4"), - UserResourceMappingFilter: influxdb.UserResourceMappingFilter{ - UserID: MustIDBase16(sixID), - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, - }, - wants: wants{ - notificationEndpoints: []influxdb.NotificationEndpoint{ - &endpoint.Slack{ - Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), - OrgID: MustIDBase16Ptr(fourID), - Status: influxdb.Active, - Name: "edp1", - }, - URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, - }, - &endpoint.HTTP{ - Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), - OrgID: MustIDBase16Ptr(fourID), - Status: influxdb.Active, - Name: "edp2", - }, - URL: "example-webhook.com", - Method: http.MethodGet, - AuthMethod: "none", + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", fourID)}, }, }, }, @@ -744,43 +543,29 @@ func FindNotificationEndpoints( fields: NotificationEndpointFields{ Orgs: []*influxdb.Organization{ { - ID: MustIDBase16(oneID), + ID: oneID, Name: "org1", }, { - ID: MustIDBase16(fourID), + ID: fourID, Name: "org4", }, }, - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(oneID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp1", }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.HTTP{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(twoID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp2", }, @@ -790,33 +575,29 @@ func FindNotificationEndpoints( }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(fourID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp3", }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: fourID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", fourID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(fiveID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(fiveID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp4", }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: fourID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", fourID)}, }, }, }, args: args{ filter: influxdb.NotificationEndpointFilter{ Org: strPtr("org4"), - UserResourceMappingFilter: influxdb.UserResourceMappingFilter{ - UserID: MustIDBase16(sixID), - ResourceType: influxdb.NotificationEndpointResourceType, - }, }, opts: influxdb.FindOptions{ Limit: 2, @@ -826,18 +607,18 @@ func FindNotificationEndpoints( notificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(oneID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp1", }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.HTTP{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(twoID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp2", }, @@ -853,50 +634,29 @@ func FindNotificationEndpoints( fields: NotificationEndpointFields{ Orgs: []*influxdb.Organization{ { - ID: MustIDBase16(oneID), + ID: oneID, Name: "org1", }, { - ID: MustIDBase16(fourID), + ID: fourID, Name: "org4", }, }, - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - - { - ResourceID: MustIDBase16(fourID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(oneID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp1", }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.HTTP{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(twoID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp2", }, @@ -906,23 +666,19 @@ func FindNotificationEndpoints( }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(fourID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp3", }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: fourID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", fourID)}, }, }, }, args: args{ filter: influxdb.NotificationEndpointFilter{ Org: strPtr("org4"), - UserResourceMappingFilter: influxdb.UserResourceMappingFilter{ - UserID: MustIDBase16(sixID), - ResourceType: influxdb.NotificationEndpointResourceType, - }, }, opts: influxdb.FindOptions{ Offset: 1, @@ -932,8 +688,8 @@ func FindNotificationEndpoints( notificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.HTTP{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(twoID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp2", }, @@ -943,13 +699,13 @@ func FindNotificationEndpoints( }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(fourID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp3", }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: fourID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", fourID)}, }, }, }, @@ -959,50 +715,29 @@ func FindNotificationEndpoints( fields: NotificationEndpointFields{ Orgs: []*influxdb.Organization{ { - ID: MustIDBase16(oneID), + ID: oneID, Name: "org1", }, { - ID: MustIDBase16(fourID), + ID: fourID, Name: "org4", }, }, - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - - { - ResourceID: MustIDBase16(fourID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(oneID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp1", }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.HTTP{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(twoID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp2", }, @@ -1012,23 +747,19 @@ func FindNotificationEndpoints( }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(fourID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp3", }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: fourID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", fourID)}, }, }, }, args: args{ filter: influxdb.NotificationEndpointFilter{ Org: strPtr("org4"), - UserResourceMappingFilter: influxdb.UserResourceMappingFilter{ - UserID: MustIDBase16(sixID), - ResourceType: influxdb.NotificationEndpointResourceType, - }, }, opts: influxdb.FindOptions{ Limit: 1, @@ -1039,8 +770,8 @@ func FindNotificationEndpoints( notificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.HTTP{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(twoID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp2", }, @@ -1056,49 +787,29 @@ func FindNotificationEndpoints( fields: NotificationEndpointFields{ Orgs: []*influxdb.Organization{ { - ID: MustIDBase16(oneID), + ID: oneID, Name: "org1", }, { - ID: MustIDBase16(fourID), + ID: fourID, Name: "org4", }, }, - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(fourID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(oneID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp1", }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.HTTP{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(twoID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp2", }, @@ -1108,36 +819,32 @@ func FindNotificationEndpoints( }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(fourID), - OrgID: MustIDBase16Ptr(oneID), + ID: idPtr(fourID), + OrgID: idPtr(oneID), Status: influxdb.Active, Name: "edp3", }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: fourID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", fourID)}, }, }, }, args: args{ filter: influxdb.NotificationEndpointFilter{ - ID: idPtr(MustIDBase16(fourID)), - UserResourceMappingFilter: influxdb.UserResourceMappingFilter{ - UserID: MustIDBase16(sixID), - ResourceType: influxdb.NotificationEndpointResourceType, - }, + ID: idPtr(fourID), }, }, wants: wants{ notificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(fourID), - OrgID: MustIDBase16Ptr(oneID), + ID: idPtr(fourID), + OrgID: idPtr(oneID), Status: influxdb.Active, Name: "edp3", }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: fourID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", fourID)}, }, }, }, @@ -1147,49 +854,29 @@ func FindNotificationEndpoints( fields: NotificationEndpointFields{ Orgs: []*influxdb.Organization{ { - ID: MustIDBase16(oneID), + ID: oneID, Name: "org1", }, { - ID: MustIDBase16(fourID), + ID: fourID, Name: "org4", }, }, - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(threeID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(oneID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp1", }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.HTTP{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(twoID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp2", }, @@ -1199,22 +886,19 @@ func FindNotificationEndpoints( }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(threeID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(threeID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp3", }, - ClientURL: "example-pagerduty.com", RoutingKey: influxdb.SecretField{Key: threeID + "-routing-key"}, + ClientURL: "example-pagerduty.com", + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", threeID)}, }, }, }, args: args{ filter: influxdb.NotificationEndpointFilter{ - OrgID: idPtr(MustIDBase16(oneID)), - UserResourceMappingFilter: influxdb.UserResourceMappingFilter{ - UserID: MustIDBase16(sixID), - ResourceType: influxdb.NotificationEndpointResourceType, - }, + OrgID: idPtr(oneID), }, }, wants: wants{ @@ -1226,43 +910,29 @@ func FindNotificationEndpoints( fields: NotificationEndpointFields{ Orgs: []*influxdb.Organization{ { - ID: MustIDBase16(oneID), + ID: oneID, Name: "org1", }, { - ID: MustIDBase16(fourID), + ID: fourID, Name: "org4", }, }, - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(oneID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp1", }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.HTTP{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(twoID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp2", }, @@ -1272,22 +942,18 @@ func FindNotificationEndpoints( }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(threeID), - OrgID: MustIDBase16Ptr(fourID), + ID: idPtr(threeID), + OrgID: idPtr(fourID), Status: influxdb.Active, Name: "edp3", }, - ClientURL: "example-pagerduty.com", RoutingKey: influxdb.SecretField{Key: threeID + "-routing-key"}, + ClientURL: "example-pagerduty.com", RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", threeID)}, }, }, }, args: args{ filter: influxdb.NotificationEndpointFilter{ - ID: idPtr(MustIDBase16(fiveID)), - UserResourceMappingFilter: influxdb.UserResourceMappingFilter{ - UserID: MustIDBase16(sixID), - ResourceType: influxdb.NotificationEndpointResourceType, - }, + ID: idPtr(fiveID), }, }, wants: wants{}, @@ -1339,26 +1005,12 @@ func UpdateNotificationEndpoint( name: "can't find the id", fields: NotificationEndpointFields{ TimeGenerator: fakeGenerator, - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -1366,32 +1018,32 @@ func UpdateNotificationEndpoint( }, }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), UpdatedAt: timeGen2.Now(), }, }, - ClientURL: "example-pagerduty.com", RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + ClientURL: "example-pagerduty.com", RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, args: args{ - userID: MustIDBase16(sixID), - id: MustIDBase16(fourID), - orgID: MustIDBase16(fourID), + userID: sixID, + id: fourID, + orgID: fourID, notificationEndpoint: &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Inactive, }, ClientURL: "example-pagerduty.com", @@ -1401,7 +1053,7 @@ func UpdateNotificationEndpoint( wants: wants{ err: &influxdb.Error{ Code: influxdb.ENotFound, - Msg: "notification endpoint not found", + Msg: `notification endpoint not found for key "0000000000000004"`, }, }, }, @@ -1409,26 +1061,12 @@ func UpdateNotificationEndpoint( name: "regular update", fields: NotificationEndpointFields{ TimeGenerator: fakeGenerator, - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -1436,32 +1074,32 @@ func UpdateNotificationEndpoint( }, }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), UpdatedAt: timeGen2.Now(), }, }, - ClientURL: "example-pagerduty.com", RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + ClientURL: "example-pagerduty.com", RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, args: args{ - userID: MustIDBase16(sixID), - id: MustIDBase16(twoID), - orgID: MustIDBase16(fourID), + userID: sixID, + id: twoID, + orgID: fourID, notificationEndpoint: &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name3", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Inactive, }, ClientURL: "example-pagerduty2.com", @@ -1471,9 +1109,9 @@ func UpdateNotificationEndpoint( wants: wants{ notificationEndpoint: &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name3", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Inactive, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -1481,7 +1119,7 @@ func UpdateNotificationEndpoint( }, }, ClientURL: "example-pagerduty2.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, @@ -1489,26 +1127,12 @@ func UpdateNotificationEndpoint( name: "update secret", fields: NotificationEndpointFields{ TimeGenerator: fakeGenerator, - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -1516,19 +1140,19 @@ func UpdateNotificationEndpoint( }, }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, args: args{ - userID: MustIDBase16(sixID), - id: MustIDBase16(twoID), - orgID: MustIDBase16(fourID), + userID: sixID, + id: twoID, + orgID: fourID, notificationEndpoint: &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name3", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Inactive, }, ClientURL: "example-pagerduty2.com", @@ -1540,9 +1164,9 @@ func UpdateNotificationEndpoint( wants: wants{ notificationEndpoint: &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name3", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Inactive, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -1562,9 +1186,7 @@ func UpdateNotificationEndpoint( edp, err := s.UpdateNotificationEndpoint(ctx, tt.args.id, tt.args.notificationEndpoint, tt.args.userID) if err != nil { - iErr, ok := err.(*influxdb.Error) - require.True(t, ok) - assert.Equal(t, tt.wants.err.Code, iErr.Code) + require.Equal(t, tt.wants.err, err) return } @@ -1621,26 +1243,12 @@ func PatchNotificationEndpoint( name: "can't find the id", fields: NotificationEndpointFields{ TimeGenerator: fakeGenerator, - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -1648,13 +1256,13 @@ func PatchNotificationEndpoint( }, }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -1662,12 +1270,12 @@ func PatchNotificationEndpoint( }, }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, args: args{ - id: MustIDBase16(fourID), + id: fourID, upd: influxdb.NotificationEndpointUpdate{ Name: &name3, Status: &status3, @@ -1684,53 +1292,39 @@ func PatchNotificationEndpoint( name: "regular update", fields: NotificationEndpointFields{ TimeGenerator: fakeGenerator, - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", Status: influxdb.Active, - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), UpdatedAt: timeGen2.Now(), }, }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", Status: influxdb.Active, - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), UpdatedAt: timeGen2.Now(), }, }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, args: args{ - id: MustIDBase16(twoID), + id: twoID, upd: influxdb.NotificationEndpointUpdate{ Name: &name3, Status: &status3, @@ -1739,17 +1333,17 @@ func PatchNotificationEndpoint( wants: wants{ notificationEndpoint: &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: name3, Status: status3, - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), UpdatedAt: fakeDate, }, }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, @@ -1790,7 +1384,6 @@ func DeleteNotificationEndpoint( type wants struct { notificationEndpoints []influxdb.NotificationEndpoint - userResourceMappings []*influxdb.UserResourceMapping secretFlds []influxdb.SecretField orgID influxdb.ID err *influxdb.Error @@ -1804,26 +1397,12 @@ func DeleteNotificationEndpoint( { name: "bad id", fields: NotificationEndpointFields{ - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -1831,13 +1410,13 @@ func DeleteNotificationEndpoint( }, }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -1845,40 +1424,26 @@ func DeleteNotificationEndpoint( }, }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, args: args{ id: influxdb.ID(0), - orgID: MustIDBase16(fourID), - userID: MustIDBase16(sixID), + orgID: fourID, + userID: sixID, }, wants: wants{ err: &influxdb.Error{ Code: influxdb.EInvalid, Msg: "no key was provided for notification endpoint", }, - userResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, notificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -1886,20 +1451,20 @@ func DeleteNotificationEndpoint( }, }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), UpdatedAt: timeGen2.Now(), }, }, - ClientURL: "example-pagerduty.com", RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + ClientURL: "example-pagerduty.com", RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, @@ -1907,26 +1472,12 @@ func DeleteNotificationEndpoint( { name: "none existing endpoint", fields: NotificationEndpointFields{ - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -1934,53 +1485,39 @@ func DeleteNotificationEndpoint( }, }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), UpdatedAt: timeGen2.Now(), }, }, - ClientURL: "example-pagerduty.com", RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + ClientURL: "example-pagerduty.com", RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, args: args{ - id: MustIDBase16(fourID), - orgID: MustIDBase16(fourID), - userID: MustIDBase16(sixID), + id: fourID, + orgID: fourID, + userID: sixID, }, wants: wants{ err: &influxdb.Error{ Code: influxdb.ENotFound, Msg: "notification endpoint not found", }, - userResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, notificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -1988,13 +1525,13 @@ func DeleteNotificationEndpoint( }, }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -2002,7 +1539,7 @@ func DeleteNotificationEndpoint( }, }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, @@ -2010,26 +1547,12 @@ func DeleteNotificationEndpoint( { name: "regular delete", fields: NotificationEndpointFields{ - UserResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - { - ResourceID: MustIDBase16(twoID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Member, - ResourceType: influxdb.NotificationEndpointResourceType, - }, - }, NotificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -2037,13 +1560,13 @@ func DeleteNotificationEndpoint( }, }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, &endpoint.PagerDuty{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(twoID), + ID: idPtr(twoID), Name: "name2", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -2051,34 +1574,26 @@ func DeleteNotificationEndpoint( }, }, ClientURL: "example-pagerduty.com", - RoutingKey: influxdb.SecretField{Key: twoID + "-routing-key"}, + RoutingKey: influxdb.SecretField{Key: fmt.Sprintf("%s-routing-key", twoID)}, }, }, }, args: args{ - id: MustIDBase16(twoID), - orgID: MustIDBase16(fourID), - userID: MustIDBase16(sixID), + id: twoID, + orgID: fourID, + userID: sixID, }, wants: wants{ secretFlds: []influxdb.SecretField{ - {Key: twoID + "-routing-key"}, - }, - orgID: MustIDBase16(fourID), - userResourceMappings: []*influxdb.UserResourceMapping{ - { - ResourceID: MustIDBase16(oneID), - UserID: MustIDBase16(sixID), - UserType: influxdb.Owner, - ResourceType: influxdb.NotificationEndpointResourceType, - }, + {Key: fmt.Sprintf("%s-routing-key", twoID)}, }, + orgID: fourID, notificationEndpoints: []influxdb.NotificationEndpoint{ &endpoint.Slack{ Base: endpoint.Base{ - ID: MustIDBase16Ptr(oneID), + ID: idPtr(oneID), Name: "name1", - OrgID: MustIDBase16Ptr(fourID), + OrgID: idPtr(fourID), Status: influxdb.Active, CRUDLog: influxdb.CRUDLog{ CreatedAt: timeGen1.Now(), @@ -2086,7 +1601,7 @@ func DeleteNotificationEndpoint( }, }, URL: "example-slack.com", - Token: influxdb.SecretField{Key: oneID + "-token"}, + Token: influxdb.SecretField{Key: fmt.Sprintf("%s-token", oneID)}, }, }, }, @@ -2120,17 +1635,6 @@ func DeleteNotificationEndpoint( t.Errorf("notification endpoints are different -got/+want\ndiff %s", diff) } - urms, _, err := s.FindUserResourceMappings(ctx, influxdb.UserResourceMappingFilter{ - UserID: tt.args.userID, - ResourceType: influxdb.NotificationEndpointResourceType, - }) - 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) - } - var deletedEndpoint influxdb.NotificationEndpoint for _, ne := range tt.fields.NotificationEndpoints { if ne.GetID() == tt.args.id { @@ -2171,3 +1675,35 @@ func influxErrsEqual(t *testing.T, expected *influxdb.Error, actual error) { assert.Equal(t, expected.Code, iErr.Code) assert.Truef(t, strings.HasPrefix(iErr.Error(), expected.Error()), "expected: %s got err: %s", expected.Error(), actual.Error()) } + +func idPtr(id influxdb.ID) *influxdb.ID { + return &id +} + +func strPtr(s string) *string { return &s } + +// ErrorsEqual checks to see if the provided errors are equivalent. +func ErrorsEqual(t *testing.T, actual, expected error) { + t.Helper() + if expected == nil && actual == nil { + return + } + + if expected == nil && actual != nil { + t.Errorf("unexpected error %s", actual.Error()) + } + + if expected != nil && actual == nil { + t.Errorf("expected error %s but received nil", expected.Error()) + } + + if influxdb.ErrorCode(expected) != influxdb.ErrorCode(actual) { + t.Logf("\nexpected: %v\nactual: %v\n\n", expected, actual) + t.Errorf("expected error code %q but received %q", influxdb.ErrorCode(expected), influxdb.ErrorCode(actual)) + } + + if influxdb.ErrorMessage(expected) != influxdb.ErrorMessage(actual) { + t.Logf("\nexpected: %v\nactual: %v\n\n", expected, actual) + t.Errorf("expected error message %q but received %q", influxdb.ErrorMessage(expected), influxdb.ErrorMessage(actual)) + } +} diff --git a/notification_endpoint.go b/notification_endpoint.go index 7f264f91c96..bcbcd3141ca 100644 --- a/notification_endpoint.go +++ b/notification_endpoint.go @@ -104,12 +104,6 @@ func (n *NotificationEndpointUpdate) Valid() error { // NotificationEndpointService represents a service for managing notification endpoints. type NotificationEndpointService interface { - // UserResourceMappingService must be part of all NotificationEndpointStore service, - // for create, delete. - UserResourceMappingService - // OrganizationService is needed for search filter - OrganizationService - // FindNotificationEndpointByID returns a single notification endpoint by ID. FindNotificationEndpointByID(ctx context.Context, id ID) (NotificationEndpoint, error) diff --git a/testing/checks.go b/testing/checks.go index 1cca38abdbc..d1a9a5f2dde 100644 --- a/testing/checks.go +++ b/testing/checks.go @@ -12,7 +12,6 @@ import ( "github.com/influxdata/flux/ast" "github.com/influxdata/flux/parser" "github.com/influxdata/influxdb/v2" - "github.com/influxdata/influxdb/v2/kv" "github.com/influxdata/influxdb/v2/mock" "github.com/influxdata/influxdb/v2/notification" "github.com/influxdata/influxdb/v2/notification/check" @@ -160,7 +159,7 @@ type CheckFields struct { Tasks []influxdb.TaskCreate } -type checkServiceFactory func(CheckFields, *testing.T) (influxdb.CheckService, *kv.Service, string, func()) +type checkServiceFactory func(CheckFields, *testing.T) (influxdb.CheckService, influxdb.UserResourceMappingService, string, func()) type checkServiceF func( init checkServiceFactory, diff --git a/testing/util.go b/testing/util.go index 1caea3b44fc..e4aa6fcb464 100644 --- a/testing/util.go +++ b/testing/util.go @@ -2,10 +2,13 @@ package testing import ( "context" + "strings" "testing" + "github.com/influxdata/influxdb/v2" platform "github.com/influxdata/influxdb/v2" - "github.com/influxdata/influxdb/v2/kv" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // TODO(goller): remove opPrefix argument @@ -66,7 +69,7 @@ func MustIDBase16Ptr(s string) *platform.ID { return &id } -func MustCreateOrgs(ctx context.Context, svc *kv.Service, os ...*platform.Organization) { +func MustCreateOrgs(ctx context.Context, svc influxdb.OrganizationService, os ...*platform.Organization) { for _, o := range os { if err := svc.CreateOrganization(ctx, o); err != nil { panic(err) @@ -74,7 +77,7 @@ func MustCreateOrgs(ctx context.Context, svc *kv.Service, os ...*platform.Organi } } -func MustCreateLabels(ctx context.Context, svc *kv.Service, labels ...*platform.Label) { +func MustCreateLabels(ctx context.Context, svc influxdb.LabelService, labels ...*platform.Label) { for _, l := range labels { if err := svc.CreateLabel(ctx, l); err != nil { panic(err) @@ -82,7 +85,7 @@ func MustCreateLabels(ctx context.Context, svc *kv.Service, labels ...*platform. } } -func MustCreateUsers(ctx context.Context, svc *kv.Service, us ...*platform.User) { +func MustCreateUsers(ctx context.Context, svc influxdb.UserService, us ...*platform.User) { for _, u := range us { if err := svc.CreateUser(ctx, u); err != nil { panic(err) @@ -90,7 +93,7 @@ func MustCreateUsers(ctx context.Context, svc *kv.Service, us ...*platform.User) } } -func MustCreateMappings(ctx context.Context, svc *kv.Service, ms ...*platform.UserResourceMapping) { +func MustCreateMappings(ctx context.Context, svc influxdb.UserResourceMappingService, ms ...*platform.UserResourceMapping) { for _, m := range ms { if err := svc.CreateUserResourceMapping(ctx, m); err != nil { panic(err) @@ -98,7 +101,7 @@ func MustCreateMappings(ctx context.Context, svc *kv.Service, ms ...*platform.Us } } -func MustMakeUsersOrgOwner(ctx context.Context, svc *kv.Service, oid platform.ID, uids ...platform.ID) { +func MustMakeUsersOrgOwner(ctx context.Context, svc influxdb.UserResourceMappingService, oid platform.ID, uids ...platform.ID) { ms := make([]*platform.UserResourceMapping, len(uids)) for i, uid := range uids { ms[i] = &platform.UserResourceMapping{ @@ -111,7 +114,7 @@ func MustMakeUsersOrgOwner(ctx context.Context, svc *kv.Service, oid platform.ID MustCreateMappings(ctx, svc, ms...) } -func MustMakeUsersOrgMember(ctx context.Context, svc *kv.Service, oid platform.ID, uids ...platform.ID) { +func MustMakeUsersOrgMember(ctx context.Context, svc influxdb.UserResourceMappingService, oid platform.ID, uids ...platform.ID) { ms := make([]*platform.UserResourceMapping, len(uids)) for i, uid := range uids { ms[i] = &platform.UserResourceMapping{ @@ -131,3 +134,24 @@ func MustNewPermissionAtID(id platform.ID, a platform.Action, rt platform.Resour } return perm } + +func influxErrsEqual(t *testing.T, expected *influxdb.Error, actual error) { + t.Helper() + + if expected != nil { + require.Error(t, actual) + } + + if actual == nil { + return + } + + if expected == nil { + require.NoError(t, actual) + return + } + iErr, ok := actual.(*influxdb.Error) + require.True(t, ok) + assert.Equal(t, expected.Code, iErr.Code) + assert.Truef(t, strings.HasPrefix(iErr.Error(), expected.Error()), "expected: %s got err: %s", expected.Error(), actual.Error()) +}