2020-03-11 18:31:33 +00:00
|
|
|
package tenant
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2020-07-24 10:35:41 +00:00
|
|
|
"time"
|
2020-03-11 18:31:33 +00:00
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/kit/platform"
|
|
|
|
"github.com/influxdata/influxdb/v2/kit/platform/errors"
|
|
|
|
|
2020-04-03 17:39:20 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/kit/tracing"
|
|
|
|
"github.com/influxdata/influxdb/v2/kv"
|
2020-07-24 10:35:41 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/rand"
|
2020-04-03 17:39:20 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/snowflake"
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/tenant/index"
|
2020-03-11 18:31:33 +00:00
|
|
|
)
|
|
|
|
|
2020-03-17 19:23:00 +00:00
|
|
|
const MaxIDGenerationN = 100
|
|
|
|
|
2020-03-11 18:31:33 +00:00
|
|
|
type Store struct {
|
2020-08-11 14:56:42 +00:00
|
|
|
kvStore kv.Store
|
2021-03-30 18:10:02 +00:00
|
|
|
IDGen platform.IDGenerator
|
|
|
|
OrgIDGen platform.IDGenerator
|
|
|
|
BucketIDGen platform.IDGenerator
|
2020-08-11 14:56:42 +00:00
|
|
|
|
|
|
|
now func() time.Time
|
|
|
|
|
2020-03-27 18:36:25 +00:00
|
|
|
urmByUserIndex *kv.Index
|
2020-03-11 18:31:33 +00:00
|
|
|
}
|
|
|
|
|
2020-08-11 14:56:42 +00:00
|
|
|
type StoreOption func(*Store)
|
|
|
|
|
|
|
|
func NewStore(kvStore kv.Store, opts ...StoreOption) *Store {
|
|
|
|
store := &Store{
|
|
|
|
kvStore: kvStore,
|
|
|
|
IDGen: snowflake.NewDefaultIDGenerator(),
|
|
|
|
OrgIDGen: rand.NewOrgBucketID(time.Now().UnixNano()),
|
|
|
|
BucketIDGen: rand.NewOrgBucketID(time.Now().UnixNano()),
|
|
|
|
now: func() time.Time {
|
|
|
|
return time.Now().UTC()
|
|
|
|
},
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
urmByUserIndex: kv.NewIndex(index.URMByUserIndexMapping, kv.WithIndexReadPathEnabled),
|
2020-03-11 18:31:33 +00:00
|
|
|
}
|
2020-08-11 14:56:42 +00:00
|
|
|
|
|
|
|
for _, opt := range opts {
|
|
|
|
opt(store)
|
|
|
|
}
|
|
|
|
|
|
|
|
return store
|
2020-03-11 18:31:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// View opens up a transaction that will not write to any data. Implementing interfaces
|
|
|
|
// should take care to ensure that all view transactions do not mutate any data.
|
|
|
|
func (s *Store) View(ctx context.Context, fn func(kv.Tx) error) error {
|
|
|
|
return s.kvStore.View(ctx, fn)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update opens up a transaction that will mutate data.
|
|
|
|
func (s *Store) Update(ctx context.Context, fn func(kv.Tx) error) error {
|
|
|
|
return s.kvStore.Update(ctx, fn)
|
|
|
|
}
|
|
|
|
|
2020-03-17 19:23:00 +00:00
|
|
|
// generateSafeID attempts to create ids for buckets
|
|
|
|
// and orgs that are without backslash, commas, and spaces, BUT ALSO do not already exist.
|
2021-03-30 18:10:02 +00:00
|
|
|
func (s *Store) generateSafeID(ctx context.Context, tx kv.Tx, bucket []byte, gen platform.IDGenerator) (platform.ID, error) {
|
2020-03-17 19:23:00 +00:00
|
|
|
for i := 0; i < MaxIDGenerationN; i++ {
|
2020-08-11 14:56:42 +00:00
|
|
|
id := gen.ID()
|
2020-03-17 19:23:00 +00:00
|
|
|
|
|
|
|
err := s.uniqueID(ctx, tx, bucket, id)
|
|
|
|
if err == nil {
|
|
|
|
return id, nil
|
|
|
|
}
|
|
|
|
|
2020-08-11 14:56:42 +00:00
|
|
|
if err == ErrIDNotUnique {
|
2020-03-17 19:23:00 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
return platform.InvalidID(), err
|
2020-03-17 19:23:00 +00:00
|
|
|
}
|
2020-08-11 14:56:42 +00:00
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
return platform.InvalidID(), ErrFailureGeneratingID
|
2020-03-17 19:23:00 +00:00
|
|
|
}
|
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
func (s *Store) uniqueID(ctx context.Context, tx kv.Tx, bucket []byte, id platform.ID) error {
|
2020-03-17 19:23:00 +00:00
|
|
|
span, _ := tracing.StartSpanFromContext(ctx)
|
|
|
|
defer span.Finish()
|
|
|
|
|
|
|
|
encodedID, err := id.Encode()
|
|
|
|
if err != nil {
|
2021-03-30 18:10:02 +00:00
|
|
|
return &errors.Error{
|
|
|
|
Code: errors.EInvalid,
|
2020-03-17 19:23:00 +00:00
|
|
|
Err: err,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
b, err := tx.Bucket(bucket)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = b.Get(encodedID)
|
|
|
|
if kv.IsNotFound(err) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-08-11 14:56:42 +00:00
|
|
|
return ErrIDNotUnique
|
2020-03-17 19:23:00 +00:00
|
|
|
}
|