Merge branch 'master' into flux-staging
commit
896837b9e5
|
@ -23,9 +23,9 @@ func (c *Client) setPassword(ctx context.Context, tx *bolt.Tx, name string, pass
|
|||
return err
|
||||
}
|
||||
|
||||
u, err := c.findUserByName(ctx, tx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
u, pe := c.findUserByName(ctx, tx, name)
|
||||
if pe != nil {
|
||||
return pe
|
||||
}
|
||||
|
||||
encodedID, err := u.ID.Encode()
|
||||
|
|
|
@ -124,9 +124,9 @@ func (c *Client) CreateSession(ctx context.Context, user string) (*platform.Sess
|
|||
}
|
||||
|
||||
func (c *Client) createSession(ctx context.Context, tx *bolt.Tx, user string) (*platform.Session, error) {
|
||||
u, err := c.findUserByName(ctx, tx, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
u, pe := c.findUserByName(ctx, tx, user)
|
||||
if pe != nil {
|
||||
return nil, pe
|
||||
}
|
||||
|
||||
s := &platform.Session{}
|
||||
|
|
174
bolt/user.go
174
bolt/user.go
|
@ -6,7 +6,7 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/bbolt"
|
||||
bolt "github.com/coreos/bbolt"
|
||||
"github.com/influxdata/platform"
|
||||
platformcontext "github.com/influxdata/platform/context"
|
||||
)
|
||||
|
@ -39,25 +39,30 @@ func (c *Client) FindUserByID(ctx context.Context, id platform.ID) (*platform.Us
|
|||
var u *platform.User
|
||||
|
||||
err := c.db.View(func(tx *bolt.Tx) error {
|
||||
usr, err := c.findUserByID(ctx, tx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
usr, pe := c.findUserByID(ctx, tx, id)
|
||||
if pe != nil {
|
||||
return pe
|
||||
}
|
||||
u = usr
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, &platform.Error{
|
||||
Op: getOp(platform.OpFindUserByID),
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (c *Client) findUserByID(ctx context.Context, tx *bolt.Tx, id platform.ID) (*platform.User, error) {
|
||||
func (c *Client) findUserByID(ctx context.Context, tx *bolt.Tx, id platform.ID) (*platform.User, *platform.Error) {
|
||||
encodedID, err := id.Encode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, &platform.Error{
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
var u platform.User
|
||||
|
@ -71,7 +76,9 @@ func (c *Client) findUserByID(ctx context.Context, tx *bolt.Tx, id platform.ID)
|
|||
}
|
||||
|
||||
if err := json.Unmarshal(v, &u); err != nil {
|
||||
return nil, err
|
||||
return nil, &platform.Error{
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
return &u, nil
|
||||
|
@ -82,9 +89,9 @@ func (c *Client) FindUserByName(ctx context.Context, n string) (*platform.User,
|
|||
var u *platform.User
|
||||
|
||||
err := c.db.View(func(tx *bolt.Tx) error {
|
||||
usr, err := c.findUserByName(ctx, tx, n)
|
||||
if err != nil {
|
||||
return err
|
||||
usr, pe := c.findUserByName(ctx, tx, n)
|
||||
if pe != nil {
|
||||
return pe
|
||||
}
|
||||
u = usr
|
||||
return nil
|
||||
|
@ -93,10 +100,9 @@ func (c *Client) FindUserByName(ctx context.Context, n string) (*platform.User,
|
|||
return u, err
|
||||
}
|
||||
|
||||
func (c *Client) findUserByName(ctx context.Context, tx *bolt.Tx, n string) (*platform.User, error) {
|
||||
func (c *Client) findUserByName(ctx context.Context, tx *bolt.Tx, n string) (*platform.User, *platform.Error) {
|
||||
u := tx.Bucket(userIndex).Get(userIndexKey(n))
|
||||
if u == nil {
|
||||
// TODO: Make standard error
|
||||
return nil, &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Msg: "user not found",
|
||||
|
@ -105,7 +111,9 @@ func (c *Client) findUserByName(ctx context.Context, tx *bolt.Tx, n string) (*pl
|
|||
|
||||
var id platform.ID
|
||||
if err := id.Decode(u); err != nil {
|
||||
return nil, err
|
||||
return nil, &platform.Error{
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
return c.findUserByID(ctx, tx, id)
|
||||
}
|
||||
|
@ -114,18 +122,34 @@ func (c *Client) findUserByName(ctx context.Context, tx *bolt.Tx, n string) (*pl
|
|||
// Filters using ID, or Name should be efficient.
|
||||
// Other filters will do a linear scan across users until it finds a match.
|
||||
func (c *Client) FindUser(ctx context.Context, filter platform.UserFilter) (*platform.User, error) {
|
||||
var u *platform.User
|
||||
var err error
|
||||
op := getOp(platform.OpFindUser)
|
||||
if filter.ID != nil {
|
||||
return c.FindUserByID(ctx, *filter.ID)
|
||||
u, err = c.FindUserByID(ctx, *filter.ID)
|
||||
if err != nil {
|
||||
return nil, &platform.Error{
|
||||
Op: op,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
if filter.Name != nil {
|
||||
return c.FindUserByName(ctx, *filter.Name)
|
||||
u, err = c.FindUserByName(ctx, *filter.Name)
|
||||
if err != nil {
|
||||
return nil, &platform.Error{
|
||||
Op: op,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
filterFn := filterUsersFn(filter)
|
||||
|
||||
var u *platform.User
|
||||
err := c.db.View(func(tx *bolt.Tx) error {
|
||||
err = c.db.View(func(tx *bolt.Tx) error {
|
||||
return forEachUser(ctx, tx, func(usr *platform.User) bool {
|
||||
if filterFn(usr) {
|
||||
u = usr
|
||||
|
@ -136,11 +160,17 @@ func (c *Client) FindUser(ctx context.Context, filter platform.UserFilter) (*pla
|
|||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, &platform.Error{
|
||||
Op: op,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
if u == nil {
|
||||
return nil, fmt.Errorf("user not found")
|
||||
return nil, &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Msg: "user not found",
|
||||
}
|
||||
}
|
||||
|
||||
return u, nil
|
||||
|
@ -166,10 +196,14 @@ func filterUsersFn(filter platform.UserFilter) func(u *platform.User) bool {
|
|||
// Filters using ID, or Name should be efficient.
|
||||
// Other filters will do a linear scan across all users searching for a match.
|
||||
func (c *Client) FindUsers(ctx context.Context, filter platform.UserFilter, opt ...platform.FindOptions) ([]*platform.User, int, error) {
|
||||
op := getOp(platform.OpFindUsers)
|
||||
if filter.ID != nil {
|
||||
u, err := c.FindUserByID(ctx, *filter.ID)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
return nil, 0, &platform.Error{
|
||||
Err: err,
|
||||
Op: op,
|
||||
}
|
||||
}
|
||||
|
||||
return []*platform.User{u}, 1, nil
|
||||
|
@ -178,7 +212,10 @@ func (c *Client) FindUsers(ctx context.Context, filter platform.UserFilter, opt
|
|||
if filter.Name != nil {
|
||||
u, err := c.FindUserByName(ctx, *filter.Name)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
return nil, 0, &platform.Error{
|
||||
Err: err,
|
||||
Op: op,
|
||||
}
|
||||
}
|
||||
|
||||
return []*platform.User{u}, 1, nil
|
||||
|
@ -204,12 +241,14 @@ func (c *Client) FindUsers(ctx context.Context, filter platform.UserFilter, opt
|
|||
|
||||
// CreateUser creates a platform user and sets b.ID.
|
||||
func (c *Client) CreateUser(ctx context.Context, u *platform.User) error {
|
||||
return c.db.Update(func(tx *bolt.Tx) error {
|
||||
err := c.db.Update(func(tx *bolt.Tx) error {
|
||||
unique := c.uniqueUserName(ctx, tx, u)
|
||||
|
||||
if !unique {
|
||||
// TODO: make standard error
|
||||
return fmt.Errorf("user with name %s already exists", u.Name)
|
||||
return &platform.Error{
|
||||
Code: platform.EConflict,
|
||||
Msg: fmt.Sprintf("user with name %s already exists", u.Name),
|
||||
}
|
||||
}
|
||||
|
||||
u.ID = c.IDGenerator.ID()
|
||||
|
@ -220,6 +259,13 @@ func (c *Client) CreateUser(ctx context.Context, u *platform.User) error {
|
|||
|
||||
return c.putUser(ctx, tx, u)
|
||||
})
|
||||
if err != nil {
|
||||
return &platform.Error{
|
||||
Err: err,
|
||||
Op: getOp(platform.OpCreateUser),
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PutUser will put a user without setting an ID.
|
||||
|
@ -273,9 +319,12 @@ func (c *Client) uniqueUserName(ctx context.Context, tx *bolt.Tx, u *platform.Us
|
|||
func (c *Client) UpdateUser(ctx context.Context, id platform.ID, upd platform.UserUpdate) (*platform.User, error) {
|
||||
var u *platform.User
|
||||
err := c.db.Update(func(tx *bolt.Tx) error {
|
||||
usr, err := c.updateUser(ctx, tx, id, upd)
|
||||
if err != nil {
|
||||
return err
|
||||
usr, pe := c.updateUser(ctx, tx, id, upd)
|
||||
if pe != nil {
|
||||
return &platform.Error{
|
||||
Err: pe,
|
||||
Op: getOp(platform.OpUpdateUser),
|
||||
}
|
||||
}
|
||||
u = usr
|
||||
return nil
|
||||
|
@ -284,7 +333,7 @@ func (c *Client) UpdateUser(ctx context.Context, id platform.ID, upd platform.Us
|
|||
return u, err
|
||||
}
|
||||
|
||||
func (c *Client) updateUser(ctx context.Context, tx *bolt.Tx, id platform.ID, upd platform.UserUpdate) (*platform.User, error) {
|
||||
func (c *Client) updateUser(ctx context.Context, tx *bolt.Tx, id platform.ID, upd platform.UserUpdate) (*platform.User, *platform.Error) {
|
||||
u, err := c.findUserByID(ctx, tx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -294,17 +343,23 @@ func (c *Client) updateUser(ctx context.Context, tx *bolt.Tx, id platform.ID, up
|
|||
// Users are indexed by name and so the user index must be pruned
|
||||
// when name is modified.
|
||||
if err := tx.Bucket(userIndex).Delete(userIndexKey(u.Name)); err != nil {
|
||||
return nil, err
|
||||
return nil, &platform.Error{
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
u.Name = *upd.Name
|
||||
}
|
||||
|
||||
if err := c.appendUserEventToLog(ctx, tx, u.ID, userUpdatedEvent); err != nil {
|
||||
return nil, err
|
||||
return nil, &platform.Error{
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.putUser(ctx, tx, u); err != nil {
|
||||
return nil, err
|
||||
return nil, &platform.Error{
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
return u, nil
|
||||
|
@ -312,41 +367,64 @@ func (c *Client) updateUser(ctx context.Context, tx *bolt.Tx, id platform.ID, up
|
|||
|
||||
// DeleteUser deletes a user and prunes it from the index.
|
||||
func (c *Client) DeleteUser(ctx context.Context, id platform.ID) error {
|
||||
return c.db.Update(func(tx *bolt.Tx) error {
|
||||
if err := c.deleteUsersAuthorizations(ctx, tx, id); err != nil {
|
||||
return err
|
||||
err := c.db.Update(func(tx *bolt.Tx) error {
|
||||
if pe := c.deleteUsersAuthorizations(ctx, tx, id); pe != nil {
|
||||
return pe
|
||||
}
|
||||
return c.deleteUser(ctx, tx, id)
|
||||
if pe := c.deleteUser(ctx, tx, id); pe != nil {
|
||||
return pe
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return &platform.Error{
|
||||
Op: getOp(platform.OpDeleteUser),
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) deleteUser(ctx context.Context, tx *bolt.Tx, id platform.ID) error {
|
||||
u, err := c.findUserByID(ctx, tx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
func (c *Client) deleteUser(ctx context.Context, tx *bolt.Tx, id platform.ID) *platform.Error {
|
||||
u, pe := c.findUserByID(ctx, tx, id)
|
||||
if pe != nil {
|
||||
return pe
|
||||
}
|
||||
encodedID, err := id.Encode()
|
||||
if err != nil {
|
||||
return err
|
||||
return &platform.Error{
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
if err := tx.Bucket(userIndex).Delete(userIndexKey(u.Name)); err != nil {
|
||||
return err
|
||||
return &platform.Error{
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
if err := tx.Bucket(userUser).Delete(encodedID); err != nil {
|
||||
return err
|
||||
return &platform.Error{
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
return c.deleteUserResourceMappings(ctx, tx, platform.UserResourceMappingFilter{
|
||||
if err := c.deleteUserResourceMappings(ctx, tx, platform.UserResourceMappingFilter{
|
||||
UserID: id,
|
||||
})
|
||||
}); err != nil {
|
||||
return &platform.Error{
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) deleteUsersAuthorizations(ctx context.Context, tx *bolt.Tx, id platform.ID) error {
|
||||
func (c *Client) deleteUsersAuthorizations(ctx context.Context, tx *bolt.Tx, id platform.ID) *platform.Error {
|
||||
authFilter := platform.AuthorizationFilter{
|
||||
UserID: &id,
|
||||
}
|
||||
as, err := c.findAuthorizations(ctx, tx, authFilter)
|
||||
if err != nil {
|
||||
return err
|
||||
return &platform.Error{
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
for _, a := range as {
|
||||
if err := c.deleteAuthorization(ctx, tx, a.ID); err != nil {
|
||||
|
@ -356,7 +434,7 @@ func (c *Client) deleteUsersAuthorizations(ctx context.Context, tx *bolt.Tx, id
|
|||
return nil
|
||||
}
|
||||
|
||||
// GeUserOperationLog retrieves a user operation log.
|
||||
// GetUserOperationLog retrieves a user operation log.
|
||||
func (c *Client) GetUserOperationLog(ctx context.Context, id platform.ID, opts platform.FindOptions) ([]*platform.OperationLogEntry, int, error) {
|
||||
// TODO(desa): might be worthwhile to allocate a slice of size opts.Limit
|
||||
log := []*platform.OperationLogEntry{}
|
||||
|
|
|
@ -5,10 +5,11 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/influxdata/platform"
|
||||
bolt "github.com/influxdata/platform/bolt"
|
||||
platformtesting "github.com/influxdata/platform/testing"
|
||||
)
|
||||
|
||||
func initUserService(f platformtesting.UserFields, t *testing.T) (platform.UserService, func()) {
|
||||
func initUserService(f platformtesting.UserFields, t *testing.T) (platform.UserService, string, func()) {
|
||||
c, closeFn, err := NewTestClient()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create new bolt client: %v", err)
|
||||
|
@ -20,7 +21,7 @@ func initUserService(f platformtesting.UserFields, t *testing.T) (platform.UserS
|
|||
t.Fatalf("failed to populate users")
|
||||
}
|
||||
}
|
||||
return c, func() {
|
||||
return c, bolt.OpPrefix, func() {
|
||||
defer closeFn()
|
||||
for _, u := range f.Users {
|
||||
if err := c.DeleteUser(ctx, u.ID); err != nil {
|
||||
|
@ -30,26 +31,6 @@ func initUserService(f platformtesting.UserFields, t *testing.T) (platform.UserS
|
|||
}
|
||||
}
|
||||
|
||||
func TestUserService_CreateUser(t *testing.T) {
|
||||
platformtesting.CreateUser(initUserService, t)
|
||||
}
|
||||
|
||||
func TestUserService_FindUserByID(t *testing.T) {
|
||||
platformtesting.FindUserByID(initUserService, t)
|
||||
}
|
||||
|
||||
func TestUserService_FindUsers(t *testing.T) {
|
||||
platformtesting.FindUsers(initUserService, t)
|
||||
}
|
||||
|
||||
func TestUserService_DeleteUser(t *testing.T) {
|
||||
platformtesting.DeleteUser(initUserService, t)
|
||||
}
|
||||
|
||||
func TestUserService_FindUser(t *testing.T) {
|
||||
platformtesting.FindUser(initUserService, t)
|
||||
}
|
||||
|
||||
func TestUserService_UpdateUser(t *testing.T) {
|
||||
platformtesting.UpdateUser(initUserService, t)
|
||||
func TestUserService(t *testing.T) {
|
||||
platformtesting.UserService(initUserService, t)
|
||||
}
|
||||
|
|
|
@ -55,6 +55,8 @@ func main() {
|
|||
if err := m.Run(ctx, os.Args[1:]...); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
} else if !m.running {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
<-ctx.Done()
|
||||
|
@ -67,8 +69,9 @@ func main() {
|
|||
|
||||
// Main represents the main program execution.
|
||||
type Main struct {
|
||||
wg sync.WaitGroup
|
||||
cancel func()
|
||||
wg sync.WaitGroup
|
||||
cancel func()
|
||||
running bool
|
||||
|
||||
logLevel string
|
||||
httpBindAddress string
|
||||
|
@ -197,6 +200,7 @@ func (m *Main) Run(ctx context.Context, args ...string) error {
|
|||
}
|
||||
|
||||
func (m *Main) run(ctx context.Context) (err error) {
|
||||
m.running = true
|
||||
ctx, m.cancel = context.WithCancel(ctx)
|
||||
|
||||
var lvl zapcore.Level
|
||||
|
|
|
@ -90,7 +90,7 @@ func NewAPIHandler(b *APIBackend) *APIHandler {
|
|||
h.DashboardHandler.DashboardService = b.DashboardService
|
||||
h.DashboardHandler.DashboardOperationLogService = b.DashboardOperationLogService
|
||||
|
||||
h.ViewHandler = NewViewHandler(b.UserResourceMappingService)
|
||||
h.ViewHandler = NewViewHandler(b.UserResourceMappingService, b.LabelService)
|
||||
h.ViewHandler.ViewService = b.ViewService
|
||||
|
||||
h.MacroHandler = NewMacroHandler()
|
||||
|
|
|
@ -516,6 +516,7 @@ func (s *BucketService) FindBucket(ctx context.Context, filter platform.BucketFi
|
|||
return nil, &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: s.OpPrefix + platform.OpFindBucket,
|
||||
Msg: "bucket not found",
|
||||
Err: ErrNotFound,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -630,6 +630,7 @@ paths:
|
|||
$ref: "#/components/schemas/Error"
|
||||
/sources:
|
||||
post:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Sources
|
||||
summary: Creates a Source
|
||||
|
@ -661,6 +662,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
get:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Sources
|
||||
summary: Get all sources
|
||||
|
@ -685,7 +687,35 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
/sources/{sourceID}:
|
||||
delete:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Sources
|
||||
summary: Delete a source
|
||||
parameters:
|
||||
- in: path
|
||||
name: sourceID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the source
|
||||
responses:
|
||||
'204':
|
||||
description: delete has been accepted
|
||||
'404':
|
||||
description: view not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
patch:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Sources
|
||||
summary: Updates a Source
|
||||
|
@ -723,6 +753,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
get:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Sources
|
||||
summary: Get a source
|
||||
|
@ -754,6 +785,7 @@ paths:
|
|||
$ref: "#/components/schemas/Error"
|
||||
/sources/{sourceID}/health:
|
||||
get:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Sources
|
||||
summary: Get a sources health
|
||||
|
@ -823,6 +855,7 @@ paths:
|
|||
$ref: "#/components/schemas/Error"
|
||||
/views:
|
||||
post:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Views
|
||||
summary: A view contains information about the visual representation of data
|
||||
|
@ -854,6 +887,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
get:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Views
|
||||
summary: Get all views
|
||||
|
@ -878,37 +912,39 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'/views/{viewID}':
|
||||
get:
|
||||
tags:
|
||||
- Views
|
||||
summary: Get a single View
|
||||
parameters:
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of view to update
|
||||
responses:
|
||||
'200':
|
||||
description: get a single view
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/View"
|
||||
'404':
|
||||
description: view not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
patch:
|
||||
get:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Views
|
||||
summary: Get a single View
|
||||
parameters:
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of view to update
|
||||
responses:
|
||||
'200':
|
||||
description: get a single view
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/View"
|
||||
'404':
|
||||
description: view not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
patch:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Views
|
||||
summary: Update a single view
|
||||
|
@ -945,7 +981,8 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
delete:
|
||||
delete:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Views
|
||||
summary: Delete a view
|
||||
|
@ -973,6 +1010,7 @@ paths:
|
|||
$ref: "#/components/schemas/Error"
|
||||
/dashboards:
|
||||
post:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Dashboards
|
||||
summary: Create a dashboard
|
||||
|
@ -1004,6 +1042,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
get:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Dashboards
|
||||
summary: Get all dashboards
|
||||
|
@ -1043,47 +1082,49 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'/dashboards/{dashboardID}':
|
||||
get:
|
||||
tags:
|
||||
- Dashboards
|
||||
summary: Get a single Dashboard
|
||||
parameters:
|
||||
- in: path
|
||||
name: dashboardID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of dashboard to update
|
||||
responses:
|
||||
'200':
|
||||
description: get a single dashboard
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Dashboard"
|
||||
'404':
|
||||
description: dashboard not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
patch:
|
||||
get:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Dashboards
|
||||
summary: Get a single Dashboard
|
||||
parameters:
|
||||
- in: path
|
||||
name: dashboardID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of dashboard to update
|
||||
responses:
|
||||
'200':
|
||||
description: get a single dashboard
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Dashboard"
|
||||
'404':
|
||||
description: dashboard not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
patch:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Dashboards
|
||||
summary: Update a single dashboard
|
||||
requestBody:
|
||||
description: patching of a dashboard
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Dashboard"
|
||||
description: patching of a dashboard
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Dashboard"
|
||||
parameters:
|
||||
- in: path
|
||||
name: dashboardID
|
||||
|
@ -1110,7 +1151,8 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
delete:
|
||||
delete:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Dashboards
|
||||
summary: Delete a dashboard
|
||||
|
@ -1137,18 +1179,19 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'/dashboards/{dashboardID}/cells':
|
||||
put:
|
||||
put:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Cells
|
||||
- Dashboards
|
||||
summary: Replace a dashboards cells
|
||||
requestBody:
|
||||
description: batch replaces all of a dashboards cells (this is used primarily to update the positional information of all of the cells)
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Cells"
|
||||
description: batch replaces all of a dashboards cells (this is used primarily to update the positional information of all of the cells)
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Cells"
|
||||
parameters:
|
||||
- in: path
|
||||
name: dashboardID
|
||||
|
@ -1175,7 +1218,8 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
post:
|
||||
post:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Cells
|
||||
- Dashboards
|
||||
|
@ -1215,6 +1259,7 @@ paths:
|
|||
$ref: "#/components/schemas/Error"
|
||||
'/dashboards/{dashboardID}/cells/{cellID}':
|
||||
patch:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Cells
|
||||
- Dashboards
|
||||
|
@ -1259,6 +1304,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
delete:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Cells
|
||||
- Dashboards
|
||||
|
@ -2461,6 +2507,7 @@ paths:
|
|||
$ref: "#/components/schemas/Error"
|
||||
/tasks:
|
||||
get:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Tasks
|
||||
summary: List tasks.
|
||||
|
@ -2502,6 +2549,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
post:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Tasks
|
||||
summary: Create a new task
|
||||
|
@ -2527,6 +2575,7 @@ paths:
|
|||
$ref: "#/components/schemas/Error"
|
||||
'/tasks/{taskID}':
|
||||
get:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Tasks
|
||||
summary: Retrieve an task
|
||||
|
@ -2551,6 +2600,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
patch:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Tasks
|
||||
summary: Update a task
|
||||
|
@ -2583,6 +2633,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
delete:
|
||||
x-generated: true
|
||||
tags:
|
||||
- Tasks
|
||||
summary: Delete a task
|
||||
|
@ -4625,12 +4676,16 @@ components:
|
|||
properties:
|
||||
self:
|
||||
type: string
|
||||
query:
|
||||
type: string
|
||||
health:
|
||||
type: string
|
||||
buckets:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
organizationID:
|
||||
type: string
|
||||
default:
|
||||
type: boolean
|
||||
name:
|
||||
type: string
|
||||
type:
|
||||
|
|
|
@ -96,7 +96,14 @@ func requestMacroID(ctx context.Context) (platform.ID, error) {
|
|||
}
|
||||
|
||||
id, err := platform.IDFromString(urlID)
|
||||
return *id, err
|
||||
if err != nil {
|
||||
return platform.InvalidID(), &platform.Error{
|
||||
Code: platform.EInvalid,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
return *id, nil
|
||||
}
|
||||
|
||||
func (h *MacroHandler) handleGetMacro(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
@ -159,6 +159,24 @@ func TestMacroService_handleGetMacro(t *testing.T) {
|
|||
body: ``,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "request an invalid macro ID",
|
||||
args: args{
|
||||
id: "baz",
|
||||
},
|
||||
fields: fields{
|
||||
&mock.MacroService{
|
||||
FindMacroByIDF: func(ctx context.Context, id platform.ID) (*platform.Macro, error) {
|
||||
return nil, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
statusCode: 400,
|
||||
contentType: "application/json",
|
||||
body: `{"code":"invalid","msg":"An internal error has occurred.","err":"id must have a length of 16 bytes"}`,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
|
@ -1,12 +1,34 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/platform/toml"
|
||||
)
|
||||
|
||||
// ReadyHandler is a default readiness handler. The default behavior is always ready.
|
||||
var up = time.Now()
|
||||
|
||||
// ReadyHandler is a default readiness handler. The default behaviour is always ready.
|
||||
func ReadyHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprintln(w, `{"status": "ready"}`)
|
||||
|
||||
var status = struct {
|
||||
Status string `json:"status"`
|
||||
Start time.Time `json:"started"`
|
||||
Up toml.Duration `json:"up"`
|
||||
}{
|
||||
Status: "ready",
|
||||
Start: up,
|
||||
Up: toml.Duration(time.Since(up)),
|
||||
}
|
||||
|
||||
enc := json.NewEncoder(w)
|
||||
enc.SetIndent("", " ")
|
||||
err := enc.Encode(status)
|
||||
if err != nil {
|
||||
fmt.Fprintf(w, "Error encoding status data: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
|
482
http/swagger.yml
482
http/swagger.yml
|
@ -494,6 +494,12 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Macros"
|
||||
'400':
|
||||
description: invalid request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
default:
|
||||
description: internal server error
|
||||
content:
|
||||
|
@ -1091,6 +1097,284 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'/views/{viewID}/labels':
|
||||
get:
|
||||
tags:
|
||||
- Views
|
||||
summary: list all labels for a view
|
||||
parameters:
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
responses:
|
||||
'200':
|
||||
description: a list of all labels for a view
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
labels:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
links:
|
||||
$ref: "#/components/schemas/Links"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
post:
|
||||
tags:
|
||||
- Views
|
||||
summary: add a label to a view
|
||||
parameters:
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
requestBody:
|
||||
description: label to add
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
label:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: a list of all labels for a view
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
labels:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
links:
|
||||
$ref: "#/components/schemas/Links"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'/views/{viewID}/labels/{label}':
|
||||
delete:
|
||||
tags:
|
||||
- Views
|
||||
summary: delete a label from a view
|
||||
parameters:
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
- in: path
|
||||
name: label
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: the label name
|
||||
responses:
|
||||
'204':
|
||||
description: delete has been accepted
|
||||
'404':
|
||||
description: view not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'/views/{viewID}/members':
|
||||
get:
|
||||
tags:
|
||||
- Users
|
||||
- Views
|
||||
summary: List all view members
|
||||
parameters:
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
responses:
|
||||
'200':
|
||||
description: a list of users who have member privileges for a view
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Users"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
post:
|
||||
tags:
|
||||
- Users
|
||||
- Views
|
||||
summary: Add view member
|
||||
parameters:
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
requestBody:
|
||||
description: user to add as member
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
responses:
|
||||
'201':
|
||||
description: added to view members
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'/views/{viewID}/members/{userID}':
|
||||
delete:
|
||||
tags:
|
||||
- Users
|
||||
- Views
|
||||
summary: removes a member from an view
|
||||
parameters:
|
||||
- in: path
|
||||
name: userID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of member to remove
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
responses:
|
||||
'204':
|
||||
description: member removed
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'/views/{viewID}/owners':
|
||||
get:
|
||||
tags:
|
||||
- Users
|
||||
- Views
|
||||
summary: List all view owners
|
||||
parameters:
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
responses:
|
||||
'200':
|
||||
description: a list of users who have owner privileges for a view
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Users"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
post:
|
||||
tags:
|
||||
- Users
|
||||
- Views
|
||||
summary: Add view owner
|
||||
parameters:
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
requestBody:
|
||||
description: user to add as owner
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
responses:
|
||||
'201':
|
||||
description: added to view owners
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'/views/{viewID}/owners/{userID}':
|
||||
delete:
|
||||
tags:
|
||||
- Users
|
||||
- Views
|
||||
summary: removes an owner from a view
|
||||
parameters:
|
||||
- in: path
|
||||
name: userID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of owner to remove
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
responses:
|
||||
'204':
|
||||
description: owner removed
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
/dashboards:
|
||||
post:
|
||||
tags:
|
||||
|
@ -2512,6 +2796,32 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
delete:
|
||||
tags:
|
||||
- Organizations
|
||||
summary: Delete an organization
|
||||
parameters:
|
||||
- in: path
|
||||
name: orgID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of organization to delete
|
||||
responses:
|
||||
'204':
|
||||
description: delete has been accepted
|
||||
'404':
|
||||
description: organization not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'/orgs/{orgID}/labels':
|
||||
get:
|
||||
tags:
|
||||
|
@ -3557,178 +3867,6 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'/views/{viewID}/members':
|
||||
get:
|
||||
tags:
|
||||
- Users
|
||||
- Views
|
||||
summary: List all view members
|
||||
parameters:
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
responses:
|
||||
'200':
|
||||
description: a list of users who have member privileges for a view
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Users"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
post:
|
||||
tags:
|
||||
- Users
|
||||
- Views
|
||||
summary: Add view member
|
||||
parameters:
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
requestBody:
|
||||
description: user to add as member
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
responses:
|
||||
'201':
|
||||
description: added to view members
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'/views/{viewID}/members/{userID}':
|
||||
delete:
|
||||
tags:
|
||||
- Users
|
||||
- Views
|
||||
summary: removes a member from an view
|
||||
parameters:
|
||||
- in: path
|
||||
name: userID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of member to remove
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
responses:
|
||||
'204':
|
||||
description: member removed
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'/views/{viewID}/owners':
|
||||
get:
|
||||
tags:
|
||||
- Users
|
||||
- Views
|
||||
summary: List all view owners
|
||||
parameters:
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
responses:
|
||||
'200':
|
||||
description: a list of users who have owner privileges for a view
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Users"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
post:
|
||||
tags:
|
||||
- Users
|
||||
- Views
|
||||
summary: Add view owner
|
||||
parameters:
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
requestBody:
|
||||
description: user to add as owner
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
responses:
|
||||
'201':
|
||||
description: added to view owners
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'/views/{viewID}/owners/{userID}':
|
||||
delete:
|
||||
tags:
|
||||
- Users
|
||||
- Views
|
||||
summary: removes an owner from a view
|
||||
parameters:
|
||||
- in: path
|
||||
name: userID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of owner to remove
|
||||
- in: path
|
||||
name: viewID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: ID of the view
|
||||
responses:
|
||||
'204':
|
||||
description: owner removed
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
components:
|
||||
schemas:
|
||||
LanguageRequest:
|
||||
|
|
|
@ -413,6 +413,8 @@ type UserService struct {
|
|||
Addr string
|
||||
Token string
|
||||
InsecureSkipVerify bool
|
||||
// OpPrefix is the ops of not found error.
|
||||
OpPrefix string
|
||||
}
|
||||
|
||||
// FindMe returns user information about the owner of the token
|
||||
|
@ -436,7 +438,7 @@ func (s *UserService) FindMe(ctx context.Context, id platform.ID) (*platform.Use
|
|||
|
||||
defer resp.Body.Close()
|
||||
|
||||
if err := CheckError(resp); err != nil {
|
||||
if err := CheckError(resp, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -466,7 +468,7 @@ func (s *UserService) FindUserByID(ctx context.Context, id platform.ID) (*platfo
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err := CheckError(resp); err != nil {
|
||||
if err := CheckError(resp, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -483,11 +485,18 @@ func (s *UserService) FindUserByID(ctx context.Context, id platform.ID) (*platfo
|
|||
func (s *UserService) FindUser(ctx context.Context, filter platform.UserFilter) (*platform.User, error) {
|
||||
users, n, err := s.FindUsers(ctx, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, &platform.Error{
|
||||
Op: s.OpPrefix + platform.OpFindUser,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
if n == 0 {
|
||||
return nil, ErrNotFound
|
||||
return nil, &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: s.OpPrefix + platform.OpFindUser,
|
||||
Msg: "no results found",
|
||||
}
|
||||
}
|
||||
|
||||
return users[0], nil
|
||||
|
@ -564,7 +573,7 @@ func (s *UserService) CreateUser(ctx context.Context, u *platform.User) error {
|
|||
}
|
||||
|
||||
// TODO(jsternberg): Should this check for a 201 explicitly?
|
||||
if err := CheckError(resp); err != nil {
|
||||
if err := CheckError(resp, true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -603,7 +612,7 @@ func (s *UserService) UpdateUser(ctx context.Context, id platform.ID, upd platfo
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err := CheckError(resp); err != nil {
|
||||
if err := CheckError(resp, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
platformtesting "github.com/influxdata/platform/testing"
|
||||
)
|
||||
|
||||
func initUserService(f platformtesting.UserFields, t *testing.T) (platform.UserService, func()) {
|
||||
func initUserService(f platformtesting.UserFields, t *testing.T) (platform.UserService, string, func()) {
|
||||
t.Helper()
|
||||
svc := inmem.NewService()
|
||||
svc.IDGenerator = f.IDGenerator
|
||||
|
@ -26,12 +26,13 @@ func initUserService(f platformtesting.UserFields, t *testing.T) (platform.UserS
|
|||
handler.UserService = svc
|
||||
server := httptest.NewServer(handler)
|
||||
client := UserService{
|
||||
Addr: server.URL,
|
||||
Addr: server.URL,
|
||||
OpPrefix: inmem.OpPrefix,
|
||||
}
|
||||
|
||||
done := server.Close
|
||||
|
||||
return &client, done
|
||||
return &client, inmem.OpPrefix, done
|
||||
}
|
||||
|
||||
func TestUserService(t *testing.T) {
|
||||
|
|
|
@ -17,22 +17,26 @@ type ViewHandler struct {
|
|||
|
||||
ViewService platform.ViewService
|
||||
UserResourceMappingService platform.UserResourceMappingService
|
||||
LabelService platform.LabelService
|
||||
}
|
||||
|
||||
const (
|
||||
viewsPath = "/api/v2/views"
|
||||
viewsIDPath = "/api/v2/views/:id"
|
||||
viewsIDMembersPath = "/api/v2/views/:id/members"
|
||||
viewsIDMembersIDPath = "/api/v2/views/:id/members/:userID"
|
||||
viewsIDOwnersPath = "/api/v2/views/:id/owners"
|
||||
viewsIDOwnersIDPath = "/api/v2/views/:id/owners:userID"
|
||||
viewsPath = "/api/v2/views"
|
||||
viewsIDPath = "/api/v2/views/:id"
|
||||
viewsIDMembersPath = "/api/v2/views/:id/members"
|
||||
viewsIDMembersIDPath = "/api/v2/views/:id/members/:userID"
|
||||
viewsIDOwnersPath = "/api/v2/views/:id/owners"
|
||||
viewsIDOwnersIDPath = "/api/v2/views/:id/owners/:userID"
|
||||
viewsIDLabelsPath = "/api/v2/views/:id/labels"
|
||||
viewsIDLabelsNamePath = "/api/v2/views/:id/labels/:name"
|
||||
)
|
||||
|
||||
// NewViewHandler returns a new instance of ViewHandler.
|
||||
func NewViewHandler(mappingService platform.UserResourceMappingService) *ViewHandler {
|
||||
func NewViewHandler(mappingService platform.UserResourceMappingService, labelService platform.LabelService) *ViewHandler {
|
||||
h := &ViewHandler{
|
||||
Router: httprouter.New(),
|
||||
UserResourceMappingService: mappingService,
|
||||
LabelService: labelService,
|
||||
}
|
||||
|
||||
h.HandlerFunc("POST", viewsPath, h.handlePostViews)
|
||||
|
@ -50,6 +54,10 @@ func NewViewHandler(mappingService platform.UserResourceMappingService) *ViewHan
|
|||
h.HandlerFunc("GET", viewsIDOwnersPath, newGetMembersHandler(h.UserResourceMappingService, platform.Owner))
|
||||
h.HandlerFunc("DELETE", viewsIDOwnersIDPath, newDeleteMemberHandler(h.UserResourceMappingService, platform.Owner))
|
||||
|
||||
h.HandlerFunc("GET", viewsIDLabelsPath, newGetLabelsHandler(h.LabelService))
|
||||
h.HandlerFunc("POST", viewsIDLabelsPath, newPostLabelHandler(h.LabelService))
|
||||
h.HandlerFunc("DELETE", viewsIDLabelsNamePath, newDeleteLabelHandler(h.LabelService))
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
|
|
|
@ -129,8 +129,7 @@ func TestService_handleGetViews(t *testing.T) {
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mappingService := mock.NewUserResourceMappingService()
|
||||
h := NewViewHandler(mappingService)
|
||||
h := NewViewHandler(mock.NewUserResourceMappingService(), mock.NewLabelService())
|
||||
h.ViewService = tt.fields.ViewService
|
||||
|
||||
r := httptest.NewRequest("GET", "http://any.url", nil)
|
||||
|
@ -238,8 +237,7 @@ func TestService_handleGetView(t *testing.T) {
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mappingService := mock.NewUserResourceMappingService()
|
||||
h := NewViewHandler(mappingService)
|
||||
h := NewViewHandler(mock.NewUserResourceMappingService(), mock.NewLabelService())
|
||||
h.ViewService = tt.fields.ViewService
|
||||
|
||||
r := httptest.NewRequest("GET", "http://any.url", nil)
|
||||
|
@ -344,8 +342,7 @@ func TestService_handlePostViews(t *testing.T) {
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mappingService := mock.NewUserResourceMappingService()
|
||||
h := NewViewHandler(mappingService)
|
||||
h := NewViewHandler(mock.NewUserResourceMappingService(), mock.NewLabelService())
|
||||
h.ViewService = tt.fields.ViewService
|
||||
|
||||
b, err := json.Marshal(tt.args.view)
|
||||
|
@ -434,8 +431,7 @@ func TestService_handleDeleteView(t *testing.T) {
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mappingService := mock.NewUserResourceMappingService()
|
||||
h := NewViewHandler(mappingService)
|
||||
h := NewViewHandler(mock.NewUserResourceMappingService(), mock.NewLabelService())
|
||||
h.ViewService = tt.fields.ViewService
|
||||
|
||||
r := httptest.NewRequest("GET", "http://any.url", nil)
|
||||
|
@ -591,8 +587,7 @@ func TestService_handlePatchView(t *testing.T) {
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mappingService := mock.NewUserResourceMappingService()
|
||||
h := NewViewHandler(mappingService)
|
||||
h := NewViewHandler(mock.NewUserResourceMappingService(), mock.NewLabelService())
|
||||
h.ViewService = tt.fields.ViewService
|
||||
|
||||
upd := platform.ViewUpdate{}
|
||||
|
|
|
@ -149,7 +149,7 @@ func (s *Service) FindOrganizations(ctx context.Context, filter platform.Organiz
|
|||
return orgs, 0, &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: op,
|
||||
Msg: OpPrefix + platform.OpFindOrganizations,
|
||||
Msg: errOrganizationNotFound,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,17 +46,21 @@ func (s *Service) FindUserByID(ctx context.Context, id platform.ID) (u *platform
|
|||
var pe *platform.Error
|
||||
u, pe = s.loadUser(id)
|
||||
if pe != nil {
|
||||
err = pe
|
||||
err = &platform.Error{
|
||||
Op: OpPrefix + platform.OpFindUserByID,
|
||||
Err: pe,
|
||||
}
|
||||
}
|
||||
return u, err
|
||||
}
|
||||
|
||||
func (c *Service) findUserByName(ctx context.Context, n string) (*platform.User, error) {
|
||||
return c.FindUser(ctx, platform.UserFilter{Name: &n})
|
||||
func (s *Service) findUserByName(ctx context.Context, n string) (*platform.User, error) {
|
||||
return s.FindUser(ctx, platform.UserFilter{Name: &n})
|
||||
}
|
||||
|
||||
// FindUser returns the first user that matches a filter.
|
||||
func (s *Service) FindUser(ctx context.Context, filter platform.UserFilter) (*platform.User, error) {
|
||||
op := OpPrefix + platform.OpFindUser
|
||||
if filter.Name != nil {
|
||||
var o *platform.User
|
||||
|
||||
|
@ -75,6 +79,7 @@ func (s *Service) FindUser(ctx context.Context, filter platform.UserFilter) (*pl
|
|||
if o == nil {
|
||||
return nil, &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: op,
|
||||
Msg: "user not found",
|
||||
}
|
||||
}
|
||||
|
@ -82,14 +87,23 @@ func (s *Service) FindUser(ctx context.Context, filter platform.UserFilter) (*pl
|
|||
return o, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("expected filter to contain name")
|
||||
return nil, &platform.Error{
|
||||
Code: platform.EInvalid,
|
||||
Op: op,
|
||||
Msg: "expected filter to contain name",
|
||||
}
|
||||
}
|
||||
|
||||
// FindUsers will retrieve a list of users from storage.
|
||||
func (s *Service) FindUsers(ctx context.Context, filter platform.UserFilter, opt ...platform.FindOptions) ([]*platform.User, int, error) {
|
||||
op := OpPrefix + platform.OpFindUsers
|
||||
if filter.ID != nil {
|
||||
o, err := s.FindUserByID(ctx, *filter.ID)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
return nil, 0, &platform.Error{
|
||||
Err: err,
|
||||
Op: op,
|
||||
}
|
||||
}
|
||||
|
||||
return []*platform.User{o}, 1, nil
|
||||
|
@ -97,7 +111,10 @@ func (s *Service) FindUsers(ctx context.Context, filter platform.UserFilter, opt
|
|||
if filter.Name != nil {
|
||||
o, err := s.FindUser(ctx, filter)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
return nil, 0, &platform.Error{
|
||||
Err: err,
|
||||
Op: op,
|
||||
}
|
||||
}
|
||||
|
||||
return []*platform.User{o}, 1, nil
|
||||
|
@ -117,24 +134,34 @@ func (s *Service) FindUsers(ctx context.Context, filter platform.UserFilter, opt
|
|||
return orgs, len(orgs), nil
|
||||
}
|
||||
|
||||
// CreateUser will create an user into storage.
|
||||
func (s *Service) CreateUser(ctx context.Context, u *platform.User) error {
|
||||
if _, err := s.FindUser(ctx, platform.UserFilter{Name: &u.Name}); err == nil {
|
||||
return fmt.Errorf("user with name %s already exists", u.Name)
|
||||
return &platform.Error{
|
||||
Code: platform.EConflict,
|
||||
Op: OpPrefix + platform.OpCreateUser,
|
||||
Msg: fmt.Sprintf("user with name %s already exists", u.Name),
|
||||
}
|
||||
}
|
||||
u.ID = s.IDGenerator.ID()
|
||||
s.PutUser(ctx, u)
|
||||
return nil
|
||||
}
|
||||
|
||||
// PutUser put a user into storage.
|
||||
func (s *Service) PutUser(ctx context.Context, o *platform.User) error {
|
||||
s.userKV.Store(o.ID.String(), o)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateUser update a user in storage.
|
||||
func (s *Service) UpdateUser(ctx context.Context, id platform.ID, upd platform.UserUpdate) (*platform.User, error) {
|
||||
o, err := s.FindUserByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, &platform.Error{
|
||||
Err: err,
|
||||
Op: OpPrefix + platform.OpUpdateUser,
|
||||
}
|
||||
}
|
||||
|
||||
if upd.Name != nil {
|
||||
|
@ -146,9 +173,13 @@ func (s *Service) UpdateUser(ctx context.Context, id platform.ID, upd platform.U
|
|||
return o, nil
|
||||
}
|
||||
|
||||
// DeleteUser remove a user from storage.
|
||||
func (s *Service) DeleteUser(ctx context.Context, id platform.ID) error {
|
||||
if _, err := s.FindUserByID(ctx, id); err != nil {
|
||||
return err
|
||||
return &platform.Error{
|
||||
Err: err,
|
||||
Op: OpPrefix + platform.OpDeleteUser,
|
||||
}
|
||||
}
|
||||
s.userKV.Delete(id.String())
|
||||
return nil
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
platformtesting "github.com/influxdata/platform/testing"
|
||||
)
|
||||
|
||||
func initUserService(f platformtesting.UserFields, t *testing.T) (platform.UserService, func()) {
|
||||
func initUserService(f platformtesting.UserFields, t *testing.T) (platform.UserService, string, func()) {
|
||||
s := NewService()
|
||||
s.IDGenerator = f.IDGenerator
|
||||
ctx := context.Background()
|
||||
|
@ -17,35 +17,10 @@ func initUserService(f platformtesting.UserFields, t *testing.T) (platform.UserS
|
|||
t.Fatalf("failed to populate users")
|
||||
}
|
||||
}
|
||||
return s, func() {}
|
||||
return s, OpPrefix, func() {}
|
||||
}
|
||||
|
||||
func TestUserService_CreateUser(t *testing.T) {
|
||||
func TestUserService(t *testing.T) {
|
||||
t.Parallel()
|
||||
platformtesting.CreateUser(initUserService, t)
|
||||
}
|
||||
|
||||
func TestUserService_FindUserByID(t *testing.T) {
|
||||
t.Parallel()
|
||||
platformtesting.FindUserByID(initUserService, t)
|
||||
}
|
||||
|
||||
func TestUserService_FindUsers(t *testing.T) {
|
||||
t.Parallel()
|
||||
platformtesting.FindUsers(initUserService, t)
|
||||
}
|
||||
|
||||
func TestUserService_DeleteUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
platformtesting.DeleteUser(initUserService, t)
|
||||
}
|
||||
|
||||
func TestUserService_FindUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
platformtesting.FindUser(initUserService, t)
|
||||
}
|
||||
|
||||
func TestUserService_UpdateUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
platformtesting.UpdateUser(initUserService, t)
|
||||
platformtesting.UserService(initUserService, t)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
// Generated by tmpl
|
||||
// https://github.com/benbjohnson/tmpl
|
||||
//
|
||||
// DO NOT EDIT!
|
||||
// Source: arrays.gen.go.tmpl
|
||||
|
||||
package gen
|
||||
|
||||
import (
|
||||
"github.com/influxdata/platform/tsdb/cursors"
|
||||
"github.com/influxdata/platform/tsdb/tsm1"
|
||||
)
|
||||
|
||||
type FloatArray struct {
|
||||
cursors.FloatArray
|
||||
}
|
||||
|
||||
func NewFloatArrayLen(sz int) *FloatArray {
|
||||
return &FloatArray{
|
||||
FloatArray: cursors.FloatArray{
|
||||
Timestamps: make([]int64, sz),
|
||||
Values: make([]float64, sz),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (a *FloatArray) Encode(b []byte) ([]byte, error) {
|
||||
return tsm1.EncodeFloatArrayBlock(&a.FloatArray, b)
|
||||
}
|
||||
|
||||
type IntegerArray struct {
|
||||
cursors.IntegerArray
|
||||
}
|
||||
|
||||
func NewIntegerArrayLen(sz int) *IntegerArray {
|
||||
return &IntegerArray{
|
||||
IntegerArray: cursors.IntegerArray{
|
||||
Timestamps: make([]int64, sz),
|
||||
Values: make([]int64, sz),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (a *IntegerArray) Encode(b []byte) ([]byte, error) {
|
||||
return tsm1.EncodeIntegerArrayBlock(&a.IntegerArray, b)
|
||||
}
|
||||
|
||||
type UnsignedArray struct {
|
||||
cursors.UnsignedArray
|
||||
}
|
||||
|
||||
func NewUnsignedArrayLen(sz int) *UnsignedArray {
|
||||
return &UnsignedArray{
|
||||
UnsignedArray: cursors.UnsignedArray{
|
||||
Timestamps: make([]int64, sz),
|
||||
Values: make([]uint64, sz),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (a *UnsignedArray) Encode(b []byte) ([]byte, error) {
|
||||
return tsm1.EncodeUnsignedArrayBlock(&a.UnsignedArray, b)
|
||||
}
|
||||
|
||||
type StringArray struct {
|
||||
cursors.StringArray
|
||||
}
|
||||
|
||||
func NewStringArrayLen(sz int) *StringArray {
|
||||
return &StringArray{
|
||||
StringArray: cursors.StringArray{
|
||||
Timestamps: make([]int64, sz),
|
||||
Values: make([]string, sz),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (a *StringArray) Encode(b []byte) ([]byte, error) {
|
||||
return tsm1.EncodeStringArrayBlock(&a.StringArray, b)
|
||||
}
|
||||
|
||||
type BooleanArray struct {
|
||||
cursors.BooleanArray
|
||||
}
|
||||
|
||||
func NewBooleanArrayLen(sz int) *BooleanArray {
|
||||
return &BooleanArray{
|
||||
BooleanArray: cursors.BooleanArray{
|
||||
Timestamps: make([]int64, sz),
|
||||
Values: make([]bool, sz),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (a *BooleanArray) Encode(b []byte) ([]byte, error) {
|
||||
return tsm1.EncodeBooleanArrayBlock(&a.BooleanArray, b)
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package gen
|
||||
|
||||
import (
|
||||
"github.com/influxdata/platform/tsdb/tsm1"
|
||||
"github.com/influxdata/platform/tsdb/cursors"
|
||||
)
|
||||
|
||||
{{range .}}
|
||||
{{ $typename := print .Name "Array" }}
|
||||
type {{$typename}} struct {
|
||||
cursors.{{$typename}}
|
||||
}
|
||||
|
||||
func New{{$typename}}Len(sz int) *{{$typename}} {
|
||||
return &{{$typename}}{
|
||||
{{$typename}}: cursors.{{$typename}}{
|
||||
Timestamps: make([]int64, sz),
|
||||
Values: make([]{{.Type}}, sz),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (a *{{$typename}}) Encode(b []byte) ([]byte, error) {
|
||||
return tsm1.Encode{{$typename}}Block(&a.{{$typename}}, b)
|
||||
}
|
||||
{{end}}
|
|
@ -0,0 +1,3 @@
|
|||
package gen
|
||||
|
||||
//go:generate env GO111MODULE=on go run github.com/benbjohnson/tmpl -data=@types.tmpldata arrays.gen.go.tmpl values_constant.gen.go.tmpl
|
|
@ -8,6 +8,10 @@ import (
|
|||
type Sequence interface {
|
||||
Next() bool
|
||||
Value() string
|
||||
}
|
||||
|
||||
type CountableSequence interface {
|
||||
Sequence
|
||||
Count() int
|
||||
}
|
||||
|
||||
|
@ -49,11 +53,11 @@ func (s *CounterByteSequence) update() {
|
|||
s.val = fmt.Sprintf(s.format, fmt.Sprintf(s.nfmt, s.v))
|
||||
}
|
||||
|
||||
func (s *CounterByteSequence) Count() int { return s.end - s.s }
|
||||
func (s *CounterByteSequence) Value() string { return s.val }
|
||||
func (s *CounterByteSequence) Count() int { return s.end - s.s }
|
||||
|
||||
type ConstantStringSequence string
|
||||
|
||||
func (ConstantStringSequence) Next() bool { return true }
|
||||
func (s ConstantStringSequence) Next() bool { return true }
|
||||
func (s ConstantStringSequence) Value() string { return string(s) }
|
||||
func (ConstantStringSequence) Count() int { return 1 }
|
||||
func (s ConstantStringSequence) Count() int { return 1 }
|
|
@ -0,0 +1,37 @@
|
|||
package gen
|
||||
|
||||
import (
|
||||
"github.com/influxdata/platform/models"
|
||||
)
|
||||
|
||||
type SeriesGenerator interface {
|
||||
// Next advances the series generator to the next series key.
|
||||
Next() bool
|
||||
|
||||
// Name returns the name of the measurement.
|
||||
// The returned value may be modified by a subsequent call to Next.
|
||||
Name() []byte
|
||||
|
||||
// Tags returns the tag set.
|
||||
// The returned value may be modified by a subsequent call to Next.
|
||||
Tags() models.Tags
|
||||
|
||||
// Field returns the name of the field.
|
||||
// The returned value may be modified by a subsequent call to Next.
|
||||
Field() []byte
|
||||
|
||||
// ValuesGenerator returns a values sequence for the current series.
|
||||
ValuesGenerator() ValuesSequence
|
||||
}
|
||||
|
||||
type ValuesSequence interface {
|
||||
Reset()
|
||||
Next() bool
|
||||
Values() Values
|
||||
}
|
||||
|
||||
type Values interface {
|
||||
MinTime() int64
|
||||
MaxTime() int64
|
||||
Encode([]byte) ([]byte, error)
|
||||
}
|
|
@ -16,12 +16,12 @@ type TagsSequence interface {
|
|||
|
||||
type TagsValuesSequence struct {
|
||||
tags models.Tags
|
||||
vals []Sequence
|
||||
vals []CountableSequence
|
||||
n int
|
||||
max int
|
||||
}
|
||||
|
||||
func NewTagsValuesSequenceKeysValues(keys []string, vals []Sequence) *TagsValuesSequence {
|
||||
func NewTagsValuesSequenceKeysValues(keys []string, vals []CountableSequence) *TagsValuesSequence {
|
||||
tm := make(map[string]string, len(keys))
|
||||
for _, k := range keys {
|
||||
tm[k] = ""
|
||||
|
@ -42,7 +42,7 @@ func NewTagsValuesSequenceKeysValues(keys []string, vals []Sequence) *TagsValues
|
|||
}
|
||||
}
|
||||
|
||||
func NewTagsValuesSequenceValues(prefix string, vals []Sequence) *TagsValuesSequence {
|
||||
func NewTagsValuesSequenceValues(prefix string, vals []CountableSequence) *TagsValuesSequence {
|
||||
keys := make([]string, len(vals))
|
||||
// max tag width
|
||||
tw := int(math.Ceil(math.Log10(float64(len(vals)))))
|
||||
|
@ -82,7 +82,7 @@ func (s *TagsValuesSequence) Count() int { return s.max }
|
|||
|
||||
type keyValues struct {
|
||||
keys []string
|
||||
vals []Sequence
|
||||
vals []CountableSequence
|
||||
}
|
||||
|
||||
func (k keyValues) Len() int { return len(k.keys) }
|
|
@ -0,0 +1,27 @@
|
|||
[
|
||||
{
|
||||
"Name":"Float",
|
||||
"name":"float",
|
||||
"Type":"float64"
|
||||
},
|
||||
{
|
||||
"Name":"Integer",
|
||||
"name":"integer",
|
||||
"Type":"int64"
|
||||
},
|
||||
{
|
||||
"Name":"Unsigned",
|
||||
"name":"unsigned",
|
||||
"Type":"uint64"
|
||||
},
|
||||
{
|
||||
"Name":"String",
|
||||
"name":"string",
|
||||
"Type":"string"
|
||||
},
|
||||
{
|
||||
"Name":"Boolean",
|
||||
"name":"boolean",
|
||||
"Type":"bool"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
package gen
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
|
@ -0,0 +1,308 @@
|
|||
// Generated by tmpl
|
||||
// https://github.com/benbjohnson/tmpl
|
||||
//
|
||||
// DO NOT EDIT!
|
||||
// Source: values_constant.gen.go.tmpl
|
||||
|
||||
package gen
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/platform/tsdb/cursors"
|
||||
)
|
||||
|
||||
type FloatConstantValuesSequence struct {
|
||||
vals FloatArray
|
||||
n int
|
||||
t int64
|
||||
state struct {
|
||||
n int
|
||||
t int64
|
||||
d int64
|
||||
v float64
|
||||
}
|
||||
}
|
||||
|
||||
func NewFloatConstantValuesSequence(n int, start time.Time, delta time.Duration, v float64) *FloatConstantValuesSequence {
|
||||
g := &FloatConstantValuesSequence{
|
||||
vals: *NewFloatArrayLen(cursors.DefaultMaxPointsPerBlock),
|
||||
}
|
||||
g.state.n = n
|
||||
g.state.t = start.UnixNano()
|
||||
g.state.d = int64(delta)
|
||||
g.state.v = v
|
||||
g.Reset()
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *FloatConstantValuesSequence) Reset() {
|
||||
g.n = g.state.n
|
||||
g.t = g.state.t
|
||||
}
|
||||
|
||||
func (g *FloatConstantValuesSequence) Next() bool {
|
||||
if g.n == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
c := min(g.n, cursors.DefaultMaxPointsPerBlock)
|
||||
g.n -= c
|
||||
g.vals.Timestamps = g.vals.Timestamps[:c]
|
||||
g.vals.Values = g.vals.Values[:c]
|
||||
|
||||
var (
|
||||
t = g.t
|
||||
ts = g.vals.Timestamps
|
||||
vs = g.vals.Values
|
||||
d = g.state.d
|
||||
)
|
||||
for i := 0; i < len(ts) && i < len(vs); i++ {
|
||||
ts[i] = g.t
|
||||
vs[i] = g.state.v
|
||||
t += d
|
||||
}
|
||||
g.t = t
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *FloatConstantValuesSequence) Values() Values {
|
||||
return &g.vals
|
||||
}
|
||||
|
||||
type IntegerConstantValuesSequence struct {
|
||||
vals IntegerArray
|
||||
n int
|
||||
t int64
|
||||
state struct {
|
||||
n int
|
||||
t int64
|
||||
d int64
|
||||
v int64
|
||||
}
|
||||
}
|
||||
|
||||
func NewIntegerConstantValuesSequence(n int, start time.Time, delta time.Duration, v int64) *IntegerConstantValuesSequence {
|
||||
g := &IntegerConstantValuesSequence{
|
||||
vals: *NewIntegerArrayLen(cursors.DefaultMaxPointsPerBlock),
|
||||
}
|
||||
g.state.n = n
|
||||
g.state.t = start.UnixNano()
|
||||
g.state.d = int64(delta)
|
||||
g.state.v = v
|
||||
g.Reset()
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *IntegerConstantValuesSequence) Reset() {
|
||||
g.n = g.state.n
|
||||
g.t = g.state.t
|
||||
}
|
||||
|
||||
func (g *IntegerConstantValuesSequence) Next() bool {
|
||||
if g.n == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
c := min(g.n, cursors.DefaultMaxPointsPerBlock)
|
||||
g.n -= c
|
||||
g.vals.Timestamps = g.vals.Timestamps[:c]
|
||||
g.vals.Values = g.vals.Values[:c]
|
||||
|
||||
var (
|
||||
t = g.t
|
||||
ts = g.vals.Timestamps
|
||||
vs = g.vals.Values
|
||||
d = g.state.d
|
||||
)
|
||||
for i := 0; i < len(ts) && i < len(vs); i++ {
|
||||
ts[i] = g.t
|
||||
vs[i] = g.state.v
|
||||
t += d
|
||||
}
|
||||
g.t = t
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *IntegerConstantValuesSequence) Values() Values {
|
||||
return &g.vals
|
||||
}
|
||||
|
||||
type UnsignedConstantValuesSequence struct {
|
||||
vals UnsignedArray
|
||||
n int
|
||||
t int64
|
||||
state struct {
|
||||
n int
|
||||
t int64
|
||||
d int64
|
||||
v uint64
|
||||
}
|
||||
}
|
||||
|
||||
func NewUnsignedConstantValuesSequence(n int, start time.Time, delta time.Duration, v uint64) *UnsignedConstantValuesSequence {
|
||||
g := &UnsignedConstantValuesSequence{
|
||||
vals: *NewUnsignedArrayLen(cursors.DefaultMaxPointsPerBlock),
|
||||
}
|
||||
g.state.n = n
|
||||
g.state.t = start.UnixNano()
|
||||
g.state.d = int64(delta)
|
||||
g.state.v = v
|
||||
g.Reset()
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *UnsignedConstantValuesSequence) Reset() {
|
||||
g.n = g.state.n
|
||||
g.t = g.state.t
|
||||
}
|
||||
|
||||
func (g *UnsignedConstantValuesSequence) Next() bool {
|
||||
if g.n == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
c := min(g.n, cursors.DefaultMaxPointsPerBlock)
|
||||
g.n -= c
|
||||
g.vals.Timestamps = g.vals.Timestamps[:c]
|
||||
g.vals.Values = g.vals.Values[:c]
|
||||
|
||||
var (
|
||||
t = g.t
|
||||
ts = g.vals.Timestamps
|
||||
vs = g.vals.Values
|
||||
d = g.state.d
|
||||
)
|
||||
for i := 0; i < len(ts) && i < len(vs); i++ {
|
||||
ts[i] = g.t
|
||||
vs[i] = g.state.v
|
||||
t += d
|
||||
}
|
||||
g.t = t
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *UnsignedConstantValuesSequence) Values() Values {
|
||||
return &g.vals
|
||||
}
|
||||
|
||||
type StringConstantValuesSequence struct {
|
||||
vals StringArray
|
||||
n int
|
||||
t int64
|
||||
state struct {
|
||||
n int
|
||||
t int64
|
||||
d int64
|
||||
v string
|
||||
}
|
||||
}
|
||||
|
||||
func NewStringConstantValuesSequence(n int, start time.Time, delta time.Duration, v string) *StringConstantValuesSequence {
|
||||
g := &StringConstantValuesSequence{
|
||||
vals: *NewStringArrayLen(cursors.DefaultMaxPointsPerBlock),
|
||||
}
|
||||
g.state.n = n
|
||||
g.state.t = start.UnixNano()
|
||||
g.state.d = int64(delta)
|
||||
g.state.v = v
|
||||
g.Reset()
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *StringConstantValuesSequence) Reset() {
|
||||
g.n = g.state.n
|
||||
g.t = g.state.t
|
||||
}
|
||||
|
||||
func (g *StringConstantValuesSequence) Next() bool {
|
||||
if g.n == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
c := min(g.n, cursors.DefaultMaxPointsPerBlock)
|
||||
g.n -= c
|
||||
g.vals.Timestamps = g.vals.Timestamps[:c]
|
||||
g.vals.Values = g.vals.Values[:c]
|
||||
|
||||
var (
|
||||
t = g.t
|
||||
ts = g.vals.Timestamps
|
||||
vs = g.vals.Values
|
||||
d = g.state.d
|
||||
)
|
||||
for i := 0; i < len(ts) && i < len(vs); i++ {
|
||||
ts[i] = g.t
|
||||
vs[i] = g.state.v
|
||||
t += d
|
||||
}
|
||||
g.t = t
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *StringConstantValuesSequence) Values() Values {
|
||||
return &g.vals
|
||||
}
|
||||
|
||||
type BooleanConstantValuesSequence struct {
|
||||
vals BooleanArray
|
||||
n int
|
||||
t int64
|
||||
state struct {
|
||||
n int
|
||||
t int64
|
||||
d int64
|
||||
v bool
|
||||
}
|
||||
}
|
||||
|
||||
func NewBooleanConstantValuesSequence(n int, start time.Time, delta time.Duration, v bool) *BooleanConstantValuesSequence {
|
||||
g := &BooleanConstantValuesSequence{
|
||||
vals: *NewBooleanArrayLen(cursors.DefaultMaxPointsPerBlock),
|
||||
}
|
||||
g.state.n = n
|
||||
g.state.t = start.UnixNano()
|
||||
g.state.d = int64(delta)
|
||||
g.state.v = v
|
||||
g.Reset()
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *BooleanConstantValuesSequence) Reset() {
|
||||
g.n = g.state.n
|
||||
g.t = g.state.t
|
||||
}
|
||||
|
||||
func (g *BooleanConstantValuesSequence) Next() bool {
|
||||
if g.n == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
c := min(g.n, cursors.DefaultMaxPointsPerBlock)
|
||||
g.n -= c
|
||||
g.vals.Timestamps = g.vals.Timestamps[:c]
|
||||
g.vals.Values = g.vals.Values[:c]
|
||||
|
||||
var (
|
||||
t = g.t
|
||||
ts = g.vals.Timestamps
|
||||
vs = g.vals.Values
|
||||
d = g.state.d
|
||||
)
|
||||
for i := 0; i < len(ts) && i < len(vs); i++ {
|
||||
ts[i] = g.t
|
||||
vs[i] = g.state.v
|
||||
t += d
|
||||
}
|
||||
g.t = t
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *BooleanConstantValuesSequence) Values() Values {
|
||||
return &g.vals
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package gen
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/platform/tsdb/cursors"
|
||||
)
|
||||
|
||||
{{range .}}
|
||||
type {{.Name}}ConstantValuesSequence struct {
|
||||
vals {{.Name}}Array
|
||||
n int
|
||||
t int64
|
||||
state struct {
|
||||
n int
|
||||
t int64
|
||||
d int64
|
||||
v {{.Type}}
|
||||
}
|
||||
}
|
||||
|
||||
func New{{.Name}}ConstantValuesSequence(n int, start time.Time, delta time.Duration, v {{.Type}}) *{{.Name}}ConstantValuesSequence {
|
||||
g := &{{.Name}}ConstantValuesSequence{
|
||||
vals: *New{{.Name}}ArrayLen(cursors.DefaultMaxPointsPerBlock),
|
||||
}
|
||||
g.state.n = n
|
||||
g.state.t = start.UnixNano()
|
||||
g.state.d = int64(delta)
|
||||
g.state.v = v
|
||||
g.Reset()
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *{{.Name}}ConstantValuesSequence) Reset() {
|
||||
g.n = g.state.n
|
||||
g.t = g.state.t
|
||||
}
|
||||
|
||||
func (g *{{.Name}}ConstantValuesSequence) Next() bool {
|
||||
if g.n == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
c := min(g.n, cursors.DefaultMaxPointsPerBlock)
|
||||
g.n -= c
|
||||
g.vals.Timestamps = g.vals.Timestamps[:c]
|
||||
g.vals.Values = g.vals.Values[:c]
|
||||
|
||||
var (
|
||||
t = g.t
|
||||
ts = g.vals.Timestamps
|
||||
vs = g.vals.Values
|
||||
d = g.state.d
|
||||
)
|
||||
for i := 0; i < len(ts) && i < len(vs); i++ {
|
||||
ts[i] = g.t
|
||||
vs[i] = g.state.v
|
||||
t += d
|
||||
}
|
||||
g.t = t
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *{{.Name}}ConstantValuesSequence) Values() Values {
|
||||
return &g.vals
|
||||
}
|
||||
{{end}}
|
|
@ -0,0 +1,60 @@
|
|||
package gen
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/platform/tsdb/cursors"
|
||||
)
|
||||
|
||||
type FloatRandomValuesSequence struct {
|
||||
buf FloatArray
|
||||
vals FloatArray
|
||||
n int
|
||||
t int64
|
||||
state struct {
|
||||
n int
|
||||
t int64
|
||||
d int64
|
||||
scale float64
|
||||
}
|
||||
}
|
||||
|
||||
func NewFloatRandomValuesSequence(n int, start time.Time, delta time.Duration, scale float64) *FloatRandomValuesSequence {
|
||||
g := &FloatRandomValuesSequence{
|
||||
buf: *NewFloatArrayLen(cursors.DefaultMaxPointsPerBlock),
|
||||
}
|
||||
g.state.n = n
|
||||
g.state.t = start.UnixNano()
|
||||
g.state.d = int64(delta)
|
||||
g.state.scale = scale
|
||||
g.Reset()
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *FloatRandomValuesSequence) Reset() {
|
||||
g.n = g.state.n
|
||||
g.t = g.state.t
|
||||
}
|
||||
|
||||
func (g *FloatRandomValuesSequence) Next() bool {
|
||||
if g.n == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
c := min(g.n, cursors.DefaultMaxPointsPerBlock)
|
||||
g.n -= c
|
||||
g.vals.Timestamps = g.buf.Timestamps[:0]
|
||||
g.vals.Values = g.buf.Values[:0]
|
||||
|
||||
for i := 0; i < c; i++ {
|
||||
g.vals.Timestamps = append(g.vals.Timestamps, g.t)
|
||||
g.vals.Values = append(g.vals.Values, rand.Float64()*g.state.scale)
|
||||
g.t += g.state.d
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *FloatRandomValuesSequence) Values() Values {
|
||||
return &g.vals
|
||||
}
|
|
@ -7,7 +7,7 @@ import (
|
|||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/influxdata/platform/models"
|
||||
"github.com/influxdata/platform/pkg/testing/gen"
|
||||
"github.com/influxdata/platform/pkg/data/gen"
|
||||
"github.com/influxdata/platform/storage/reads"
|
||||
"github.com/influxdata/platform/storage/reads/datatypes"
|
||||
)
|
||||
|
@ -310,7 +310,7 @@ func (s *sliceSeriesCursor) Next() *reads.SeriesRow {
|
|||
|
||||
func BenchmarkNewGroupResultSet_GroupBy(b *testing.B) {
|
||||
card := []int{10, 10, 10}
|
||||
vals := make([]gen.Sequence, len(card))
|
||||
vals := make([]gen.CountableSequence, len(card))
|
||||
for i := range card {
|
||||
vals[i] = gen.NewCounterByteSequenceCount(card[i])
|
||||
}
|
||||
|
|
|
@ -945,7 +945,7 @@ func FindBucket(
|
|||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: platform.OpFindBucket,
|
||||
Msg: "no results found",
|
||||
Msg: "bucket not found",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -295,7 +295,7 @@ func FindOrganizationByID(
|
|||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: platform.OpFindOrganizationByID,
|
||||
Msg: "",
|
||||
Msg: "organization not found",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -3,7 +3,6 @@ package testing
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
|
@ -39,11 +38,11 @@ type UserFields struct {
|
|||
|
||||
// UserService tests all the service functions.
|
||||
func UserService(
|
||||
init func(UserFields, *testing.T) (platform.UserService, func()), t *testing.T,
|
||||
init func(UserFields, *testing.T) (platform.UserService, string, func()), t *testing.T,
|
||||
) {
|
||||
tests := []struct {
|
||||
name string
|
||||
fn func(init func(UserFields, *testing.T) (platform.UserService, func()),
|
||||
fn func(init func(UserFields, *testing.T) (platform.UserService, string, func()),
|
||||
t *testing.T)
|
||||
}{
|
||||
{
|
||||
|
@ -80,7 +79,7 @@ func UserService(
|
|||
|
||||
// CreateUser testing
|
||||
func CreateUser(
|
||||
init func(UserFields, *testing.T) (platform.UserService, func()),
|
||||
init func(UserFields, *testing.T) (platform.UserService, string, func()),
|
||||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
|
@ -173,26 +172,22 @@ func CreateUser(
|
|||
Name: "user1",
|
||||
},
|
||||
},
|
||||
err: fmt.Errorf("user with name user1 already exists"),
|
||||
err: &platform.Error{
|
||||
Code: platform.EConflict,
|
||||
Op: platform.OpCreateUser,
|
||||
Msg: "user with name user1 already exists",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s, done := init(tt.fields, t)
|
||||
s, opPrefix, done := init(tt.fields, t)
|
||||
defer done()
|
||||
ctx := context.TODO()
|
||||
err := s.CreateUser(ctx, tt.args.user)
|
||||
if (err != nil) != (tt.wants.err != nil) {
|
||||
t.Fatalf("expected error '%v' got '%v'", tt.wants.err, err)
|
||||
}
|
||||
|
||||
if err != nil && tt.wants.err != nil {
|
||||
if err.Error() != tt.wants.err.Error() {
|
||||
t.Fatalf("expected error messages to match '%v' got '%v'", tt.wants.err, err.Error())
|
||||
}
|
||||
}
|
||||
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
|
||||
|
||||
// Delete only created users - ie., having a not nil ID
|
||||
if tt.args.user.ID.Valid() {
|
||||
|
@ -212,7 +207,7 @@ func CreateUser(
|
|||
|
||||
// FindUserByID testing
|
||||
func FindUserByID(
|
||||
init func(UserFields, *testing.T) (platform.UserService, func()),
|
||||
init func(UserFields, *testing.T) (platform.UserService, string, func()),
|
||||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
|
@ -253,24 +248,41 @@ func FindUserByID(
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find user by id not exists",
|
||||
fields: UserFields{
|
||||
Users: []*platform.User{
|
||||
{
|
||||
ID: MustIDBase16(userOneID),
|
||||
Name: "user1",
|
||||
},
|
||||
{
|
||||
ID: MustIDBase16(userTwoID),
|
||||
Name: "user2",
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
id: MustIDBase16(threeID),
|
||||
},
|
||||
wants: wants{
|
||||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: platform.OpFindUserByID,
|
||||
Msg: "user not found",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s, done := init(tt.fields, t)
|
||||
s, opPrefix, done := init(tt.fields, t)
|
||||
defer done()
|
||||
ctx := context.TODO()
|
||||
|
||||
user, err := s.FindUserByID(ctx, tt.args.id)
|
||||
if (err != nil) != (tt.wants.err != nil) {
|
||||
t.Fatalf("expected errors to be equal '%v' got '%v'", tt.wants.err, err)
|
||||
}
|
||||
|
||||
if err != nil && tt.wants.err != nil {
|
||||
if err.Error() != tt.wants.err.Error() {
|
||||
t.Fatalf("expected error '%v' got '%v'", tt.wants.err, err)
|
||||
}
|
||||
}
|
||||
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
|
||||
|
||||
if diff := cmp.Diff(user, tt.wants.user, userCmpOptions...); diff != "" {
|
||||
t.Errorf("user is different -got/+want\ndiff %s", diff)
|
||||
|
@ -281,7 +293,7 @@ func FindUserByID(
|
|||
|
||||
// FindUsers testing
|
||||
func FindUsers(
|
||||
init func(UserFields, *testing.T) (platform.UserService, func()),
|
||||
init func(UserFields, *testing.T) (platform.UserService, string, func()),
|
||||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
|
@ -379,11 +391,61 @@ func FindUsers(
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find user by id not exists",
|
||||
fields: UserFields{
|
||||
Users: []*platform.User{
|
||||
{
|
||||
ID: MustIDBase16(userOneID),
|
||||
Name: "abc",
|
||||
},
|
||||
{
|
||||
ID: MustIDBase16(userTwoID),
|
||||
Name: "xyz",
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
ID: MustIDBase16(threeID),
|
||||
},
|
||||
wants: wants{
|
||||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: platform.OpFindUsers,
|
||||
Msg: "user not found",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find user by name not exists",
|
||||
fields: UserFields{
|
||||
Users: []*platform.User{
|
||||
{
|
||||
ID: MustIDBase16(userOneID),
|
||||
Name: "abc",
|
||||
},
|
||||
{
|
||||
ID: MustIDBase16(userTwoID),
|
||||
Name: "xyz",
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
name: "no_exist",
|
||||
},
|
||||
wants: wants{
|
||||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: platform.OpFindUsers,
|
||||
Msg: "user not found",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s, done := init(tt.fields, t)
|
||||
s, opPrefix, done := init(tt.fields, t)
|
||||
defer done()
|
||||
ctx := context.TODO()
|
||||
|
||||
|
@ -396,15 +458,7 @@ func FindUsers(
|
|||
}
|
||||
|
||||
users, _, err := s.FindUsers(ctx, filter)
|
||||
if (err != nil) != (tt.wants.err != nil) {
|
||||
t.Fatalf("expected errors to be equal '%v' got '%v'", tt.wants.err, err)
|
||||
}
|
||||
|
||||
if err != nil && tt.wants.err != nil {
|
||||
if err.Error() != tt.wants.err.Error() {
|
||||
t.Fatalf("expected error '%v' got '%v'", tt.wants.err, err)
|
||||
}
|
||||
}
|
||||
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
|
||||
|
||||
if diff := cmp.Diff(users, tt.wants.users, userCmpOptions...); diff != "" {
|
||||
t.Errorf("users are different -got/+want\ndiff %s", diff)
|
||||
|
@ -415,7 +469,7 @@ func FindUsers(
|
|||
|
||||
// DeleteUser testing
|
||||
func DeleteUser(
|
||||
init func(UserFields, *testing.T) (platform.UserService, func()),
|
||||
init func(UserFields, *testing.T) (platform.UserService, string, func()),
|
||||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
|
@ -476,7 +530,11 @@ func DeleteUser(
|
|||
ID: MustIDBase16(userThreeID),
|
||||
},
|
||||
wants: wants{
|
||||
err: fmt.Errorf("<not found> user not found"),
|
||||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: platform.OpDeleteUser,
|
||||
Msg: "user not found",
|
||||
},
|
||||
users: []*platform.User{
|
||||
{
|
||||
Name: "orgA",
|
||||
|
@ -493,19 +551,11 @@ func DeleteUser(
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s, done := init(tt.fields, t)
|
||||
s, opPrefix, done := init(tt.fields, t)
|
||||
defer done()
|
||||
ctx := context.TODO()
|
||||
err := s.DeleteUser(ctx, tt.args.ID)
|
||||
if (err != nil) != (tt.wants.err != nil) {
|
||||
t.Fatalf("expected error '%v' got '%v'", tt.wants.err, err)
|
||||
}
|
||||
|
||||
if err != nil && tt.wants.err != nil {
|
||||
if err.Error() != tt.wants.err.Error() {
|
||||
t.Fatalf("expected error messages to match '%v' got '%v'", tt.wants.err, err.Error())
|
||||
}
|
||||
}
|
||||
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
|
||||
|
||||
filter := platform.UserFilter{}
|
||||
users, _, err := s.FindUsers(ctx, filter)
|
||||
|
@ -521,7 +571,7 @@ func DeleteUser(
|
|||
|
||||
// FindUser testing
|
||||
func FindUser(
|
||||
init func(UserFields, *testing.T) (platform.UserService, func()),
|
||||
init func(UserFields, *testing.T) (platform.UserService, string, func()),
|
||||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
|
@ -572,14 +622,18 @@ func FindUser(
|
|||
name: "abc",
|
||||
},
|
||||
wants: wants{
|
||||
err: fmt.Errorf("<not found> user not found"),
|
||||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Msg: "user not found",
|
||||
Op: platform.OpFindUser,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s, done := init(tt.fields, t)
|
||||
s, opPrefix, done := init(tt.fields, t)
|
||||
defer done()
|
||||
ctx := context.TODO()
|
||||
filter := platform.UserFilter{}
|
||||
|
@ -588,15 +642,7 @@ func FindUser(
|
|||
}
|
||||
|
||||
user, err := s.FindUser(ctx, filter)
|
||||
if (err != nil) != (tt.wants.err != nil) {
|
||||
t.Fatalf("expected error '%v' got '%v'", tt.wants.err, err)
|
||||
}
|
||||
|
||||
if err != nil && tt.wants.err != nil {
|
||||
if err.Error() != tt.wants.err.Error() {
|
||||
t.Fatalf("expected error messages to match '%v' got '%v'", tt.wants.err, err.Error())
|
||||
}
|
||||
}
|
||||
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
|
||||
|
||||
if diff := cmp.Diff(user, tt.wants.user, userCmpOptions...); diff != "" {
|
||||
t.Errorf("users are different -got/+want\ndiff %s", diff)
|
||||
|
@ -607,7 +653,7 @@ func FindUser(
|
|||
|
||||
// UpdateUser testing
|
||||
func UpdateUser(
|
||||
init func(UserFields, *testing.T) (platform.UserService, func()),
|
||||
init func(UserFields, *testing.T) (platform.UserService, string, func()),
|
||||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
|
@ -650,11 +696,37 @@ func UpdateUser(
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "update name with id not exists",
|
||||
fields: UserFields{
|
||||
Users: []*platform.User{
|
||||
{
|
||||
ID: MustIDBase16(userOneID),
|
||||
Name: "user1",
|
||||
},
|
||||
{
|
||||
ID: MustIDBase16(userTwoID),
|
||||
Name: "user2",
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
id: MustIDBase16(threeID),
|
||||
name: "changed",
|
||||
},
|
||||
wants: wants{
|
||||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: platform.OpUpdateUser,
|
||||
Msg: "user not found",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s, done := init(tt.fields, t)
|
||||
s, opPrefix, done := init(tt.fields, t)
|
||||
defer done()
|
||||
ctx := context.TODO()
|
||||
|
||||
|
@ -664,15 +736,7 @@ func UpdateUser(
|
|||
}
|
||||
|
||||
user, err := s.UpdateUser(ctx, tt.args.id, upd)
|
||||
if (err != nil) != (tt.wants.err != nil) {
|
||||
t.Fatalf("expected error '%v' got '%v'", tt.wants.err, err)
|
||||
}
|
||||
|
||||
if err != nil && tt.wants.err != nil {
|
||||
if err.Error() != tt.wants.err.Error() {
|
||||
t.Fatalf("expected error messages to match '%v' got '%v'", tt.wants.err, err.Error())
|
||||
}
|
||||
}
|
||||
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
|
||||
|
||||
if diff := cmp.Diff(user, tt.wants.user, userCmpOptions...); diff != "" {
|
||||
t.Errorf("user is different -got/+want\ndiff %s", diff)
|
||||
|
|
|
@ -21,6 +21,10 @@ func diffErrors(actual, expected error, t *testing.T) {
|
|||
}
|
||||
|
||||
func diffPlatformErrors(name string, actual, expected error, opPrefix string, t *testing.T) {
|
||||
if expected == nil && actual == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if expected == nil && actual != nil {
|
||||
t.Fatalf("%s failed, unexpected error %s", name, actual.Error())
|
||||
}
|
||||
|
@ -29,13 +33,17 @@ func diffPlatformErrors(name string, actual, expected error, opPrefix string, t
|
|||
t.Fatalf("%s failed, expected error %s but received nil", name, expected.Error())
|
||||
}
|
||||
|
||||
if expected != nil && actual != nil && platform.ErrorCode(expected) != platform.ErrorCode(actual) {
|
||||
if platform.ErrorCode(expected) != platform.ErrorCode(actual) {
|
||||
t.Fatalf("%s failed, expected error %q but received error code %q", name, platform.ErrorCode(expected), platform.ErrorCode(actual))
|
||||
}
|
||||
|
||||
if expected != nil && actual != nil && opPrefix+platform.ErrorOp(expected) != platform.ErrorOp(actual) {
|
||||
if opPrefix+platform.ErrorOp(expected) != platform.ErrorOp(actual) {
|
||||
t.Fatalf("%s failed, expected error %q but received error op %q", name, opPrefix+platform.ErrorOp(expected), platform.ErrorOp(actual))
|
||||
}
|
||||
|
||||
if platform.ErrorMessage(expected) != platform.ErrorMessage(actual) {
|
||||
t.Fatalf("%s failed, expected error %q but received error message %q", name, platform.ErrorMessage(expected), platform.ErrorMessage(actual))
|
||||
}
|
||||
}
|
||||
|
||||
// MustIDBase16 is an helper to ensure a correct ID is built during testing.
|
||||
|
|
|
@ -3,6 +3,7 @@ package tsi1
|
|||
import (
|
||||
"math/rand"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -152,49 +153,70 @@ func TestTagValueSeriesIDCache_addToSet(t *testing.T) {
|
|||
if !newSeriesIDSet(20).Equals(ss) {
|
||||
t.Fatalf("series id set was %v", ss)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestTagValueSeriesIDCache_ConcurrentGetPut(t *testing.T) {
|
||||
func TestTagValueSeriesIDCache_ConcurrentGetPutDelete(t *testing.T) {
|
||||
// Exercise concurrent operations against a series ID cache.
|
||||
// This will catch any likely data races, when run with the race detector.
|
||||
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping long test")
|
||||
}
|
||||
|
||||
a := []string{"a", "b", "c", "d", "e"}
|
||||
rnd := func() []byte {
|
||||
return []byte(a[rand.Intn(len(a)-1)])
|
||||
t.Parallel()
|
||||
|
||||
const letters = "abcde"
|
||||
rnd := func(rng *rand.Rand) []byte {
|
||||
return []byte{letters[rng.Intn(len(letters)-1)]}
|
||||
}
|
||||
|
||||
cache := TestCache{NewTagValueSeriesIDCache(100)}
|
||||
done := make(chan struct{})
|
||||
var wg sync.WaitGroup
|
||||
|
||||
var seriesIDCounter int32 // Atomic counter to ensure unique series IDs.
|
||||
for i := 0; i < 5; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
// Local rng to avoid lock contention.
|
||||
rng := rand.New(rand.NewSource(rand.Int63()))
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
return
|
||||
default:
|
||||
}
|
||||
cache.Put(rnd(), rnd(), rnd(), newSeriesIDSet())
|
||||
nextID := int(atomic.AddInt32(&seriesIDCounter, 1))
|
||||
cache.Put(rnd(rng), rnd(rng), rnd(rng), newSeriesIDSet(nextID))
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
var gets, deletes int32
|
||||
for i := 0; i < 5; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
// Local rng to avoid lock contention.
|
||||
rng := rand.New(rand.NewSource(rand.Int63()))
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
return
|
||||
default:
|
||||
}
|
||||
_ = cache.Get(rnd(), rnd(), rnd())
|
||||
name, key, value := rnd(rng), rnd(rng), rnd(rng)
|
||||
if set := cache.Get(name, key, value); set != nil {
|
||||
ids := set.Slice()
|
||||
for _, id := range ids {
|
||||
cache.Delete(name, key, value, tsdb.NewSeriesID(id))
|
||||
atomic.AddInt32(&deletes, 1)
|
||||
}
|
||||
}
|
||||
atomic.AddInt32(&gets, 1)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
@ -202,6 +224,7 @@ func TestTagValueSeriesIDCache_ConcurrentGetPut(t *testing.T) {
|
|||
time.Sleep(10 * time.Second)
|
||||
close(done)
|
||||
wg.Wait()
|
||||
t.Logf("Concurrently executed against series ID cache: gets=%d puts=%d deletes=%d", gets, seriesIDCounter, deletes)
|
||||
}
|
||||
|
||||
type TestCache struct {
|
||||
|
|
|
@ -23,6 +23,8 @@ import (
|
|||
|
||||
// Ensure log file can append series.
|
||||
func TestLogFile_AddSeriesList(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sfile := MustOpenSeriesFile()
|
||||
defer sfile.Close()
|
||||
|
||||
|
@ -127,6 +129,8 @@ func TestLogFile_AddSeriesList(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestLogFile_SeriesStoredInOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sfile := MustOpenSeriesFile()
|
||||
defer sfile.Close()
|
||||
|
||||
|
@ -189,6 +193,8 @@ func TestLogFile_SeriesStoredInOrder(t *testing.T) {
|
|||
|
||||
// Ensure log file can delete an existing measurement.
|
||||
func TestLogFile_DeleteMeasurement(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sfile := MustOpenSeriesFile()
|
||||
defer sfile.Close()
|
||||
|
||||
|
@ -232,6 +238,8 @@ func TestLogFile_DeleteMeasurement(t *testing.T) {
|
|||
|
||||
// Ensure log file can recover correctly.
|
||||
func TestLogFile_Open(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("Truncate", func(t *testing.T) {
|
||||
sfile := MustOpenSeriesFile()
|
||||
defer sfile.Close()
|
||||
|
|
|
@ -12,6 +12,8 @@ import (
|
|||
)
|
||||
|
||||
func TestPartition_Open(t *testing.T) {
|
||||
t.Parallel() // There's a bit of IO in this test.
|
||||
|
||||
sfile := MustOpenSeriesFile()
|
||||
defer sfile.Close()
|
||||
|
||||
|
|
|
@ -1554,6 +1554,7 @@ func (e *Engine) fullCompactionStrategy(group CompactionGroup, optimize bool) *c
|
|||
fast: optimize,
|
||||
engine: e,
|
||||
level: 5,
|
||||
tracker: e.compactionTracker,
|
||||
}
|
||||
|
||||
if optimize {
|
||||
|
|
|
@ -12,7 +12,7 @@ import {Links} from 'src/types/v2/links'
|
|||
import {Task, TaskStatus} from 'src/types/v2/tasks'
|
||||
import {OnboardingStepProps} from 'src/onboarding/containers/OnboardingWizard'
|
||||
import {ConfigurationState} from 'src/types/v2/dataLoaders'
|
||||
import {TelegrafPluginInputCpu} from 'src/api'
|
||||
import {TelegrafPluginInputCpu, TelegrafPluginInputRedis} from 'src/api'
|
||||
|
||||
export const links: Links = {
|
||||
authorizations: '/api/v2/authorizations',
|
||||
|
@ -292,6 +292,15 @@ export const telegrafPlugin = {
|
|||
active: true,
|
||||
}
|
||||
|
||||
export const redisPlugin = {
|
||||
name: TelegrafPluginInputRedis.NameEnum.Redis,
|
||||
type: TelegrafPluginInputRedis.TypeEnum.Input,
|
||||
config: {
|
||||
servers: [],
|
||||
password: '',
|
||||
},
|
||||
}
|
||||
|
||||
export const influxDB2Plugin = {
|
||||
name: 'influxdb_v2',
|
||||
type: 'output',
|
||||
|
|
|
@ -1487,7 +1487,7 @@
|
|||
},
|
||||
"array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "http://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
|
||||
"dev": true
|
||||
},
|
||||
|
@ -5046,27 +5046,27 @@
|
|||
"dependencies": {
|
||||
"abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.4",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
|
||||
"integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5077,13 +5077,13 @@
|
|||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
@ -5093,39 +5093,39 @@
|
|||
},
|
||||
"chownr": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
|
||||
"integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
||||
"dev": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5135,28 +5135,28 @@
|
|||
},
|
||||
"deep-extend": {
|
||||
"version": "0.5.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz",
|
||||
"integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "1.2.5",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz",
|
||||
"integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5166,14 +5166,14 @@
|
|||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"gauge": {
|
||||
"version": "2.7.4",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
|
||||
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5190,7 +5190,7 @@
|
|||
},
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5205,14 +5205,14 @@
|
|||
},
|
||||
"has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.21",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz",
|
||||
"integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5222,7 +5222,7 @@
|
|||
},
|
||||
"ignore-walk": {
|
||||
"version": "3.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz",
|
||||
"integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5232,7 +5232,7 @@
|
|||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5243,20 +5243,20 @@
|
|||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"dev": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
@ -5265,14 +5265,14 @@
|
|||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
@ -5281,13 +5281,13 @@
|
|||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz",
|
||||
"integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
@ -5297,7 +5297,7 @@
|
|||
},
|
||||
"minizlib": {
|
||||
"version": "1.1.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz",
|
||||
"integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5307,7 +5307,7 @@
|
|||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
@ -5316,14 +5316,14 @@
|
|||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"needle": {
|
||||
"version": "2.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/needle/-/needle-2.2.0.tgz",
|
||||
"integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5335,7 +5335,7 @@
|
|||
},
|
||||
"node-pre-gyp": {
|
||||
"version": "0.10.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.0.tgz",
|
||||
"integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5354,7 +5354,7 @@
|
|||
},
|
||||
"nopt": {
|
||||
"version": "4.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
|
||||
"integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5365,14 +5365,14 @@
|
|||
},
|
||||
"npm-bundled": {
|
||||
"version": "1.0.3",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.3.tgz",
|
||||
"integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"npm-packlist": {
|
||||
"version": "1.1.10",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.10.tgz",
|
||||
"integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5383,7 +5383,7 @@
|
|||
},
|
||||
"npmlog": {
|
||||
"version": "4.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
|
||||
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5396,20 +5396,20 @@
|
|||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||
"dev": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
@ -5418,21 +5418,21 @@
|
|||
},
|
||||
"os-homedir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
|
||||
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
||||
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"osenv": {
|
||||
"version": "0.1.5",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
|
||||
"integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5443,21 +5443,21 @@
|
|||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"rc": {
|
||||
"version": "1.2.7",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz",
|
||||
"integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5470,7 +5470,7 @@
|
|||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
|
@ -5479,7 +5479,7 @@
|
|||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5495,7 +5495,7 @@
|
|||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
|
||||
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5505,48 +5505,48 @@
|
|||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
|
||||
"dev": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.5.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
||||
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
@ -5557,7 +5557,7 @@
|
|||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5567,7 +5567,7 @@
|
|||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
@ -5576,14 +5576,14 @@
|
|||
},
|
||||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"tar": {
|
||||
"version": "4.4.1",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz",
|
||||
"integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5599,14 +5599,14 @@
|
|||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
|
||||
"integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
|
@ -5616,13 +5616,13 @@
|
|||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.2",
|
||||
"resolved": false,
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz",
|
||||
"integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
|
||||
"dev": true
|
||||
}
|
||||
|
@ -9042,7 +9042,7 @@
|
|||
},
|
||||
"pako": {
|
||||
"version": "0.2.9",
|
||||
"resolved": "http://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
|
||||
"integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=",
|
||||
"dev": true
|
||||
},
|
||||
|
|
|
@ -2343,12 +2343,6 @@ export namespace Run {
|
|||
* @interface Source
|
||||
*/
|
||||
export interface Source {
|
||||
/**
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof Source
|
||||
*/
|
||||
_default?: boolean;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
|
@ -2472,6 +2466,24 @@ export namespace Source {
|
|||
* @interface SourceLinks
|
||||
*/
|
||||
export interface SourceLinks {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof SourceLinks
|
||||
*/
|
||||
buckets?: string;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof SourceLinks
|
||||
*/
|
||||
health?: string;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof SourceLinks
|
||||
*/
|
||||
query?: string;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
|
@ -4769,10 +4781,10 @@ export interface View {
|
|||
id?: string;
|
||||
/**
|
||||
*
|
||||
* @type {SourceLinks}
|
||||
* @type {ViewLinks}
|
||||
* @memberof View
|
||||
*/
|
||||
links?: SourceLinks;
|
||||
links?: ViewLinks;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
|
@ -4787,6 +4799,20 @@ export interface View {
|
|||
properties?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface ViewLinks
|
||||
*/
|
||||
export interface ViewLinks {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof ViewLinks
|
||||
*/
|
||||
self?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
|
@ -4795,10 +4821,10 @@ export interface View {
|
|||
export interface Views {
|
||||
/**
|
||||
*
|
||||
* @type {SourceLinks}
|
||||
* @type {ViewLinks}
|
||||
* @memberof Views
|
||||
*/
|
||||
links?: SourceLinks;
|
||||
links?: ViewLinks;
|
||||
/**
|
||||
*
|
||||
* @type {Array<View>}
|
||||
|
@ -10040,6 +10066,39 @@ export const SourcesApiAxiosParamCreator = function (configuration?: Configurati
|
|||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Delete a source
|
||||
* @param {string} sourceID ID of the source
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
sourcesSourceIDDelete(sourceID: string, options: any = {}): RequestArgs {
|
||||
// verify required parameter 'sourceID' is not null or undefined
|
||||
if (sourceID === null || sourceID === undefined) {
|
||||
throw new RequiredError('sourceID','Required parameter sourceID was null or undefined when calling sourcesSourceIDDelete.');
|
||||
}
|
||||
const localVarPath = `/sources/{sourceID}`
|
||||
.replace(`{${"sourceID"}}`, encodeURIComponent(String(sourceID)));
|
||||
const localVarUrlObj = url.parse(localVarPath, true);
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
const localVarRequestOptions = Object.assign({ method: 'DELETE' }, baseOptions, options);
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
localVarUrlObj.query = Object.assign({}, localVarUrlObj.query, localVarQueryParameter, options.query);
|
||||
// fix override query string Detail: https://stackoverflow.com/a/7517673/1077943
|
||||
delete localVarUrlObj.search;
|
||||
localVarRequestOptions.headers = Object.assign({}, localVarHeaderParameter, options.headers);
|
||||
|
||||
return {
|
||||
url: url.format(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Get a source
|
||||
|
@ -10201,6 +10260,20 @@ export const SourcesApiFp = function(configuration?: Configuration) {
|
|||
return axios.request(axiosRequestArgs);
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Delete a source
|
||||
* @param {string} sourceID ID of the source
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
sourcesSourceIDDelete(sourceID: string, options?: any): (axios?: AxiosInstance, basePath?: string) => AxiosPromise<Response> {
|
||||
const localVarAxiosArgs = SourcesApiAxiosParamCreator(configuration).sourcesSourceIDDelete(sourceID, options);
|
||||
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
const axiosRequestArgs = Object.assign(localVarAxiosArgs.options, {url: basePath + localVarAxiosArgs.url})
|
||||
return axios.request(axiosRequestArgs);
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Get a source
|
||||
|
@ -10285,6 +10358,16 @@ export const SourcesApiFactory = function (configuration?: Configuration, basePa
|
|||
sourcesSourceIDBucketsGet(sourceID: string, org: string, options?: any) {
|
||||
return SourcesApiFp(configuration).sourcesSourceIDBucketsGet(sourceID, org, options)(axios, basePath);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Delete a source
|
||||
* @param {string} sourceID ID of the source
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
sourcesSourceIDDelete(sourceID: string, options?: any) {
|
||||
return SourcesApiFp(configuration).sourcesSourceIDDelete(sourceID, options)(axios, basePath);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary Get a source
|
||||
|
@ -10364,6 +10447,18 @@ export class SourcesApi extends BaseAPI {
|
|||
return SourcesApiFp(this.configuration).sourcesSourceIDBucketsGet(sourceID, org, options)(this.axios, this.basePath);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @summary Delete a source
|
||||
* @param {string} sourceID ID of the source
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof SourcesApi
|
||||
*/
|
||||
public sourcesSourceIDDelete(sourceID: string, options?: any) {
|
||||
return SourcesApiFp(this.configuration).sourcesSourceIDDelete(sourceID, options)(this.axios, this.basePath);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @summary Get a source
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import React, {Component, ChangeEvent, KeyboardEvent} from 'react'
|
||||
|
||||
// Components
|
||||
import {Input, InputType, Radio, ButtonShape} from 'src/clockface'
|
||||
import {Input, Radio, ButtonShape} from 'src/clockface'
|
||||
|
||||
// Styles
|
||||
import './AutoInput.scss'
|
||||
|
@ -26,7 +26,7 @@ interface Props {
|
|||
|
||||
interface State {
|
||||
inputMode: Mode
|
||||
inputValue: number
|
||||
inputValue: string
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
|
@ -79,20 +79,17 @@ export default class AutoInput extends Component<Props, State> {
|
|||
|
||||
private get input(): JSX.Element {
|
||||
const {inputMode, inputValue} = this.state
|
||||
const {min, max, inputPlaceholder} = this.props
|
||||
const {inputPlaceholder} = this.props
|
||||
|
||||
if (inputMode === Mode.Custom) {
|
||||
return (
|
||||
<div className="auto-input--input">
|
||||
<Input
|
||||
type={InputType.Number}
|
||||
min={min}
|
||||
max={max}
|
||||
placeholder={inputPlaceholder}
|
||||
value={`${inputValue}`}
|
||||
onChange={this.handleInputChange}
|
||||
onBlur={this.handleInputBlur}
|
||||
onKeyPress={this.handleInputKeyPress}
|
||||
onBlur={this.emitValue}
|
||||
autoFocus={true}
|
||||
/>
|
||||
</div>
|
||||
|
@ -101,32 +98,41 @@ export default class AutoInput extends Component<Props, State> {
|
|||
}
|
||||
|
||||
private handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
const inputValue = Number(e.target.value)
|
||||
const {max, min} = this.props
|
||||
|
||||
let inputValue = e.target.value
|
||||
|
||||
if (Number(inputValue) < min) {
|
||||
inputValue = String(min)
|
||||
} else if (Number(inputValue) > max) {
|
||||
inputValue = String(max)
|
||||
}
|
||||
|
||||
this.setState({inputValue})
|
||||
}
|
||||
|
||||
private handleRadioClick = (inputMode: Mode) => {
|
||||
const {onChange} = this.props
|
||||
|
||||
if (inputMode === Mode.Custom) {
|
||||
this.setState({inputMode, inputValue: 0})
|
||||
onChange(null)
|
||||
} else {
|
||||
this.setState({inputMode, inputValue: null})
|
||||
if (inputMode === this.state.inputMode) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private handleInputBlur = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
const {onChange} = this.props
|
||||
const inputValue = Number(e.target.value)
|
||||
|
||||
onChange(inputValue)
|
||||
this.setState({inputMode, inputValue: ''}, this.emitValue)
|
||||
}
|
||||
|
||||
private handleInputKeyPress = (e: KeyboardEvent<HTMLInputElement>) => {
|
||||
if (e.key === 'Enter') {
|
||||
this.props.onChange(this.state.inputValue)
|
||||
this.emitValue()
|
||||
}
|
||||
}
|
||||
|
||||
private emitValue = () => {
|
||||
const {onChange} = this.props
|
||||
const {inputValue} = this.state
|
||||
|
||||
if (inputValue === '' || isNaN(Number(inputValue))) {
|
||||
onChange(null)
|
||||
} else {
|
||||
onChange(Number(inputValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,44 +3,29 @@
|
|||
------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
$card-select--gutter: 4px;
|
||||
|
||||
.grid-sizer {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.grid-sizer--cells {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.grid-sizer--cells:after {
|
||||
clear: both;
|
||||
content: "";
|
||||
display: block;
|
||||
}
|
||||
|
||||
.grid-sizer--cell {
|
||||
float: left;
|
||||
position: relative;
|
||||
width: calc(100% - #{$card-select--gutter});
|
||||
height: calc(100% - #{$card-select--gutter});
|
||||
margin: $card-select--gutter / 2;
|
||||
}
|
||||
|
||||
.grid-sizer--col-2 {
|
||||
width: calc(50% - #{$card-select--gutter});
|
||||
padding-bottom: 50%;
|
||||
}
|
||||
|
||||
.grid-sizer--col-3 {
|
||||
width: calc(33.3333% - #{$card-select--gutter});
|
||||
padding-bottom: 33.3333%;
|
||||
}
|
||||
|
||||
.grid-sizer--col-4 {
|
||||
width: calc(25% - #{$card-select--gutter});
|
||||
padding-bottom: 25%;
|
||||
}
|
||||
|
||||
.grid-sizer--col-5 {
|
||||
width: calc(20% - #{$card-select--gutter});
|
||||
padding-bottom: 20%;
|
||||
}
|
||||
|
||||
.grid-sizer--col-6 {
|
||||
width: calc(16.6667% - #{$card-select--gutter});
|
||||
padding-bottom: 16.6667%;
|
||||
}
|
||||
|
||||
.grid-sizer--content {
|
||||
|
|
|
@ -8,68 +8,81 @@ import {ErrorHandling} from 'src/shared/decorators/errors'
|
|||
interface Props {
|
||||
children?: JSX.Element[]
|
||||
cellWidth?: number
|
||||
recalculateFlag?: string
|
||||
width?: number
|
||||
wait?: number
|
||||
}
|
||||
|
||||
interface State {
|
||||
columns: number
|
||||
columnStyle: {
|
||||
width: string
|
||||
paddingBottom: string
|
||||
margin: string
|
||||
}
|
||||
}
|
||||
@ErrorHandling
|
||||
class GridSizer extends PureComponent<Props, State> {
|
||||
public static defaultProps: Partial<Props> = {
|
||||
cellWidth: 150,
|
||||
recalculateFlag: '',
|
||||
width: null,
|
||||
wait: 0,
|
||||
}
|
||||
|
||||
private timeoutID: NodeJS.Timer
|
||||
private debouncedSizeListener: () => void
|
||||
private isComponentMounted: boolean
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
columns: null,
|
||||
columnStyle: null,
|
||||
}
|
||||
}
|
||||
|
||||
public listener = () => {
|
||||
_.debounce(() => this.setColumns(this.getWidth()), 250)
|
||||
this.debouncedSizeListener = _.debounce(this.setColumnStyle, 250)
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
this.isComponentMounted = true
|
||||
const {width} = this.props
|
||||
const widthValue = width || this.getWidth()
|
||||
this.setColumns(widthValue)
|
||||
this.setColumnStyle()
|
||||
|
||||
if (!width) {
|
||||
window.addEventListener('resize', this.listener, false)
|
||||
window.addEventListener('resize', this.debouncedSizeListener, false)
|
||||
}
|
||||
}
|
||||
|
||||
public componentDidUpdate() {
|
||||
const {width} = this.props
|
||||
if (width) {
|
||||
this.setColumns(width)
|
||||
public componentDidUpdate(prevProps) {
|
||||
const {recalculateFlag, wait} = this.props
|
||||
if (prevProps.recalculateFlag !== recalculateFlag) {
|
||||
this.timeoutID = setTimeout(this.setColumnStyle, wait)
|
||||
}
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
window.removeEventListener('resize', this.listener, false)
|
||||
this.isComponentMounted = false
|
||||
clearInterval(this.timeoutID)
|
||||
window.removeEventListener('resize', this.debouncedSizeListener, false)
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div id="grid_sizer" className="grid-sizer">
|
||||
{this.sizeChildren}
|
||||
<div className="grid-sizer--cells">{this.sizeChildren}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private get sizeChildren() {
|
||||
const {columns} = this.state
|
||||
const {columnStyle} = this.state
|
||||
const {children} = this.props
|
||||
|
||||
if (columns) {
|
||||
if (columnStyle) {
|
||||
const wrappedChildren = children.map((child, i) => (
|
||||
<div
|
||||
key={`grid_cell_${i}`}
|
||||
className={`grid-sizer--cell grid-sizer--col-${columns}`}
|
||||
style={columnStyle}
|
||||
className={`grid-sizer--cell`}
|
||||
>
|
||||
<div className="grid-sizer--content">{child}</div>
|
||||
</div>
|
||||
|
@ -82,6 +95,10 @@ class GridSizer extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
private getWidth = () => {
|
||||
if (!this.isComponentMounted) {
|
||||
return
|
||||
}
|
||||
|
||||
const ele = document.getElementById('grid_sizer')
|
||||
const computedWidth = window
|
||||
.getComputedStyle(ele, null)
|
||||
|
@ -94,13 +111,24 @@ class GridSizer extends PureComponent<Props, State> {
|
|||
return widthValue
|
||||
}
|
||||
|
||||
private setColumns = (width: number) => {
|
||||
const {cellWidth} = this.props
|
||||
const columns = Math.round(width / cellWidth)
|
||||
private setColumnStyle = () => {
|
||||
const {cellWidth, width} = this.props
|
||||
const actualWidth = width || this.getWidth()
|
||||
const columns = Math.round(actualWidth / cellWidth)
|
||||
const columnsPercent = 1 / columns
|
||||
const calculatedCellWidth = actualWidth * columnsPercent
|
||||
const gutterWidth = 4
|
||||
const columnStyle = {
|
||||
width: `${calculatedCellWidth - gutterWidth}px`,
|
||||
margin: `${gutterWidth / 2}px`,
|
||||
paddingBottom: `${calculatedCellWidth - gutterWidth}px`,
|
||||
}
|
||||
|
||||
this.setState({
|
||||
columns,
|
||||
})
|
||||
if (this.isComponentMounted) {
|
||||
this.setState({
|
||||
columnStyle,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
align-items: center;
|
||||
cursor: pointer;
|
||||
margin: 0 $ix-marg-a;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.wizard--progress-button:hover {
|
||||
|
@ -84,7 +85,9 @@
|
|||
}
|
||||
|
||||
.wizard--progress-connector {
|
||||
width: 70px;
|
||||
min-width: 20px;
|
||||
width: 100%;
|
||||
max-width: 70px;
|
||||
margin: 0 $ix-marg-a;
|
||||
height: 2px;
|
||||
background-color: $g7-graphite;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
.wizard--full-screen {
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
max-height: 100%;
|
||||
padding: $ix-marg-d $ix-marg-e;
|
||||
z-index: 50;
|
||||
display: inline-flex;
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
.wizard--progress-header {
|
||||
position: relative;
|
||||
background-color: $g0-obsidian;
|
||||
width: 80%;
|
||||
max-width: 1000px;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
padding: 0 $ix-marg-c;
|
||||
display: inline-flex;
|
||||
|
|
|
@ -23,6 +23,7 @@ import IndexList from './components/index_views/IndexList'
|
|||
import Context from './components/context_menu/Context'
|
||||
import FormElement from 'src/clockface/components/form_layout/FormElement'
|
||||
import DraggableResizer from 'src/clockface/components/draggable_resizer/DraggableResizer'
|
||||
import GridSizer from 'src/clockface/components/grid_sizer/GridSizer'
|
||||
|
||||
// Import Types
|
||||
import {
|
||||
|
@ -58,6 +59,7 @@ export {
|
|||
EmptyState,
|
||||
Form,
|
||||
FormElement,
|
||||
GridSizer,
|
||||
IndexList,
|
||||
Input,
|
||||
InputType,
|
||||
|
|
|
@ -102,9 +102,8 @@ export enum CEOTabs {
|
|||
Vis = 'Visualization',
|
||||
}
|
||||
|
||||
export const MAX_TO_LOCALE_STRING_VAL = 20 // 20 is the max input to maximumFractionDigits in spec for "to locale string"
|
||||
export const MIN_DECIMAL_PLACES = '0'
|
||||
export const MAX_DECIMAL_PLACES = MAX_TO_LOCALE_STRING_VAL.toString()
|
||||
export const MIN_DECIMAL_PLACES = 0
|
||||
export const MAX_DECIMAL_PLACES = 10
|
||||
|
||||
// used in importing dashboards and mapping sources
|
||||
export const DYNAMIC_SOURCE = 'dynamic'
|
||||
|
|
|
@ -295,10 +295,7 @@ class LogsPage extends Component<Props, State> {
|
|||
|
||||
private setCurrentSource = async () => {
|
||||
if (!this.props.currentSource && this.props.sources.length > 0) {
|
||||
const source =
|
||||
this.props.sources.find(src => {
|
||||
return src.default
|
||||
}) || this.props.sources[0]
|
||||
const source = this.props.sources[0]
|
||||
|
||||
return await this.props.getSourceAndPopulateBuckets(source.links.self)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ import {oneline} from 'src/logs/utils/helpers/formatting'
|
|||
|
||||
import {QueryConfig} from 'src/types'
|
||||
import {Filter, LogQuery} from 'src/types/logs'
|
||||
import {InfluxLanguage, SourceType} from 'src/types/v2'
|
||||
import {InfluxLanguage} from 'src/types/v2'
|
||||
import {Source} from 'src/api'
|
||||
|
||||
describe('Logs.LogQuery', () => {
|
||||
let config: QueryConfig
|
||||
|
@ -39,7 +40,7 @@ describe('Logs.LogQuery', () => {
|
|||
const source = {
|
||||
id: '1',
|
||||
name: 'foo',
|
||||
type: SourceType.Self,
|
||||
type: Source.TypeEnum.Self,
|
||||
url: 'test.local',
|
||||
insecureSkipVerify: false,
|
||||
default: true,
|
||||
|
|
|
@ -12,8 +12,7 @@
|
|||
margin: $ix-marg-d;
|
||||
margin-top: $ix-marg-a;
|
||||
flex-grow: 1;
|
||||
width: 80%;
|
||||
max-width: 1000px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wizard-step--container {
|
||||
|
@ -26,6 +25,7 @@
|
|||
text-align: center;
|
||||
background-color: $g3-castle;
|
||||
border-radius: $radius;
|
||||
padding: 20px;
|
||||
flex: 1 0 100%;
|
||||
transition: flex 0.4s ease;
|
||||
transform: translate3d(0, 0, 0);
|
||||
|
@ -200,14 +200,8 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.wizard-step--grid-container-lg {
|
||||
max-width: 750px;
|
||||
.wizard-step--grid-container {
|
||||
width: 90%;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.wizard-step--grid-container-sm {
|
||||
max-width: 500px;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
|
@ -27,6 +27,7 @@ interface Props {
|
|||
notify: NotificationAction
|
||||
onTabClick: (tabID: string) => void
|
||||
currentStepIndex: number
|
||||
handleNewSourceClick: () => void
|
||||
}
|
||||
|
||||
const configStateToTabStatus = (cs: ConfigurationState): TabStatus => {
|
||||
|
@ -70,6 +71,7 @@ class OnboardingSideBar extends Component<Props> {
|
|||
}
|
||||
|
||||
private get buttons(): JSX.Element[] {
|
||||
const {handleNewSourceClick} = this.props
|
||||
return [
|
||||
<SideBar.Button
|
||||
key="Download Config File"
|
||||
|
@ -85,6 +87,7 @@ class OnboardingSideBar extends Component<Props> {
|
|||
titleText="Add New Source"
|
||||
color={ComponentColor.Default}
|
||||
icon={IconFont.Plus}
|
||||
onClick={handleNewSourceClick}
|
||||
/>,
|
||||
]
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
ComponentSize,
|
||||
ComponentStatus,
|
||||
} from 'src/clockface'
|
||||
import DataSourceTypeSelector from 'src/onboarding/components/selectionStep/TypeSelector'
|
||||
import TypeSelector from 'src/onboarding/components/selectionStep/TypeSelector'
|
||||
import StreamingDataSourceSelector from 'src/onboarding/components/selectionStep/StreamingSelector'
|
||||
|
||||
// Actions
|
||||
|
@ -107,7 +107,7 @@ class SelectDataSourceStep extends PureComponent<Props, State> {
|
|||
)
|
||||
}
|
||||
return (
|
||||
<DataSourceTypeSelector
|
||||
<TypeSelector
|
||||
onSelectTelegrafPlugin={this.handleSelectTelegrafPlugin}
|
||||
type={this.props.type}
|
||||
/>
|
||||
|
|
|
@ -1,42 +1,83 @@
|
|||
// Libraries
|
||||
import React, {PureComponent} from 'react'
|
||||
import uuid from 'uuid'
|
||||
|
||||
// Components
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
import CardSelectCard from 'src/clockface/components/card_select/CardSelectCard'
|
||||
import GridSizer from 'src/clockface/components/grid_sizer/GridSizer'
|
||||
import {GridSizer} from 'src/clockface'
|
||||
|
||||
// Constants
|
||||
import {PLUGIN_OPTIONS} from 'src/onboarding/constants/pluginConfigs'
|
||||
|
||||
// Types
|
||||
import {TelegrafPlugin} from 'src/types/v2/dataLoaders'
|
||||
import FancyScrollbar from 'src/shared/components/fancy_scrollbar/FancyScrollbar'
|
||||
|
||||
export interface Props {
|
||||
telegrafPlugins: TelegrafPlugin[]
|
||||
onToggleTelegrafPlugin: (telegrafPlugin: string, isSelected: boolean) => void
|
||||
}
|
||||
interface State {
|
||||
gridSizerUpdateFlag: string
|
||||
}
|
||||
|
||||
const ANIMATION_LENGTH = 400
|
||||
|
||||
@ErrorHandling
|
||||
class StreamingDataSourcesSelector extends PureComponent<Props> {
|
||||
class StreamingSelector extends PureComponent<Props, State> {
|
||||
private scrollMaxHeight = window.innerHeight * 0.45
|
||||
constructor(props: Props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
gridSizerUpdateFlag: uuid.v4(),
|
||||
}
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps) {
|
||||
const addFirst =
|
||||
prevProps.telegrafPlugins.length === 0 &&
|
||||
this.props.telegrafPlugins.length > 0
|
||||
|
||||
const removeLast =
|
||||
prevProps.telegrafPlugins.length > 0 &&
|
||||
this.props.telegrafPlugins.length === 0
|
||||
|
||||
if (addFirst || removeLast) {
|
||||
const gridSizerUpdateFlag = uuid.v4()
|
||||
this.setState({gridSizerUpdateFlag})
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {gridSizerUpdateFlag} = this.state
|
||||
|
||||
return (
|
||||
<div className="wizard-step--grid-container-lg">
|
||||
<GridSizer>
|
||||
{PLUGIN_OPTIONS.map(ds => {
|
||||
return (
|
||||
<CardSelectCard
|
||||
key={ds}
|
||||
id={ds}
|
||||
name={ds}
|
||||
label={ds}
|
||||
checked={this.isCardChecked(ds)}
|
||||
onClick={this.handleToggle(ds)}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</GridSizer>
|
||||
</div>
|
||||
<FancyScrollbar
|
||||
autoHide={false}
|
||||
autoHeight={true}
|
||||
maxHeight={this.scrollMaxHeight}
|
||||
>
|
||||
<div className="wizard-step--grid-container">
|
||||
<GridSizer
|
||||
wait={ANIMATION_LENGTH}
|
||||
recalculateFlag={gridSizerUpdateFlag}
|
||||
>
|
||||
{PLUGIN_OPTIONS.map(ds => {
|
||||
return (
|
||||
<CardSelectCard
|
||||
key={ds}
|
||||
id={ds}
|
||||
name={ds}
|
||||
label={ds}
|
||||
checked={this.isCardChecked(ds)}
|
||||
onClick={this.handleToggle(ds)}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</GridSizer>
|
||||
</div>
|
||||
</FancyScrollbar>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -57,4 +98,4 @@ class StreamingDataSourcesSelector extends PureComponent<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
export default StreamingDataSourcesSelector
|
||||
export default StreamingSelector
|
||||
|
|
|
@ -4,7 +4,7 @@ import React, {PureComponent} from 'react'
|
|||
// Components
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
import CardSelectCard from 'src/clockface/components/card_select/CardSelectCard'
|
||||
import GridSizer from 'src/clockface/components/grid_sizer/GridSizer'
|
||||
import {GridSizer} from 'src/clockface'
|
||||
|
||||
// Types
|
||||
import {DataLoaderType} from 'src/types/v2/dataLoaders'
|
||||
|
@ -21,10 +21,10 @@ const DATA_SOURCES_OPTIONS = [
|
|||
]
|
||||
|
||||
@ErrorHandling
|
||||
class DataSourceTypeSelector extends PureComponent<Props> {
|
||||
class TypeSelector extends PureComponent<Props> {
|
||||
public render() {
|
||||
return (
|
||||
<div className="wizard-step--grid-container-sm">
|
||||
<div className="wizard-step--grid-container">
|
||||
<GridSizer>
|
||||
{DATA_SOURCES_OPTIONS.map(ds => {
|
||||
return (
|
||||
|
@ -54,4 +54,4 @@ class DataSourceTypeSelector extends PureComponent<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
export default DataSourceTypeSelector
|
||||
export default TypeSelector
|
||||
|
|
|
@ -198,17 +198,17 @@ export const PLUGIN_OPTIONS: TelegrafPluginName[] = [
|
|||
TelegrafPluginInputDisk.NameEnum.Disk,
|
||||
TelegrafPluginInputDiskio.NameEnum.Diskio,
|
||||
TelegrafPluginInputDocker.NameEnum.Docker,
|
||||
// TelegrafPluginInputFile.NameEnum.File,
|
||||
TelegrafPluginInputFile.NameEnum.File,
|
||||
TelegrafPluginInputKernel.NameEnum.Kernel,
|
||||
TelegrafPluginInputKubernetes.NameEnum.Kubernetes,
|
||||
TelegrafPluginInputLogParser.NameEnum.Logparser,
|
||||
// TelegrafPluginInputMem.NameEnum.Mem,
|
||||
// TelegrafPluginInputNet.NameEnum.Net,
|
||||
// TelegrafPluginInputNetResponse.NameEnum.NetResponse,
|
||||
// TelegrafPluginInputNgnix.NameEnum.Ngnix,
|
||||
// TelegrafPluginInputProcesses.NameEnum.Processes,
|
||||
// TelegrafPluginInputProcstat.NameEnum.Procstat,
|
||||
// TelegrafPluginInputPrometheus.NameEnum.Prometheus,
|
||||
TelegrafPluginInputMem.NameEnum.Mem,
|
||||
TelegrafPluginInputNet.NameEnum.Net,
|
||||
TelegrafPluginInputNetResponse.NameEnum.NetResponse,
|
||||
TelegrafPluginInputNgnix.NameEnum.Ngnix,
|
||||
TelegrafPluginInputProcesses.NameEnum.Processes,
|
||||
TelegrafPluginInputProcstat.NameEnum.Procstat,
|
||||
TelegrafPluginInputPrometheus.NameEnum.Prometheus,
|
||||
TelegrafPluginInputRedis.NameEnum.Redis,
|
||||
TelegrafPluginInputSyslog.NameEnum.Syslog,
|
||||
TelegrafPluginInputSwap.NameEnum.Swap,
|
||||
|
|
|
@ -121,6 +121,7 @@ class OnboardingWizard extends PureComponent<Props> {
|
|||
onSaveTelegrafConfig,
|
||||
setupParams,
|
||||
notify,
|
||||
onDecrementCurrentStepIndex,
|
||||
} = this.props
|
||||
|
||||
return (
|
||||
|
@ -135,6 +136,7 @@ class OnboardingWizard extends PureComponent<Props> {
|
|||
title="Selected Sources"
|
||||
visible={this.sideBarVisible}
|
||||
currentStepIndex={currentStepIndex}
|
||||
handleNewSourceClick={onDecrementCurrentStepIndex}
|
||||
/>
|
||||
<div className="wizard-step--container">
|
||||
<OnboardingStepSwitcher
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
// Libraries
|
||||
import React, {SFC} from 'react'
|
||||
|
||||
interface Props {
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
const LogoApache: SFC<Props> = ({height, width}) => {
|
||||
return (
|
||||
<svg width={width} height={height} viewBox="0 0 49.92 100">
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="apache_c"
|
||||
x1={-1886.65}
|
||||
y1={4996.93}
|
||||
x2={-1872.53}
|
||||
y2={4980.42}
|
||||
gradientTransform="scale(1 -1) rotate(65.2 2995.766 3977.41)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset={0} stopColor="#f69923" />
|
||||
<stop offset={0.31} stopColor="#f79a23" />
|
||||
<stop offset={0.84} stopColor="#e97826" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="apache_a"
|
||||
x1={-1991.78}
|
||||
y1={4989.78}
|
||||
x2={-1891.01}
|
||||
y2={4989.78}
|
||||
gradientTransform="scale(1 -1) rotate(65.2 2995.766 3977.41)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset={0.32} stopColor="#9e2064" />
|
||||
<stop offset={0.63} stopColor="#c92037" />
|
||||
<stop offset={0.75} stopColor="#cd2335" />
|
||||
<stop offset={1} stopColor="#e97826" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="apache_d"
|
||||
x1={-1991.19}
|
||||
y1={4998.76}
|
||||
x2={-1890.42}
|
||||
y2={4998.76}
|
||||
xlinkHref="#apache_a"
|
||||
/>
|
||||
<linearGradient
|
||||
id="apache_e"
|
||||
x1={-1985.53}
|
||||
y1={4989.27}
|
||||
x2={-1884.76}
|
||||
y2={4989.27}
|
||||
xlinkHref="#apache_a"
|
||||
/>
|
||||
<linearGradient
|
||||
id="apache_f"
|
||||
x1={-1985.53}
|
||||
y1={4999.7}
|
||||
x2={-1884.76}
|
||||
y2={4999.7}
|
||||
xlinkHref="#apache_a"
|
||||
/>
|
||||
<linearGradient
|
||||
id="apache_b"
|
||||
x1={-1979.02}
|
||||
y1={4988.65}
|
||||
x2={-1918.97}
|
||||
y2={4988.65}
|
||||
gradientTransform="scale(1 -1) rotate(65.2 2995.766 3977.41)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset={0} stopColor="#282662" />
|
||||
<stop offset={0.1} stopColor="#662e8d" />
|
||||
<stop offset={0.79} stopColor="#9f2064" />
|
||||
<stop offset={0.95} stopColor="#cd2032" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="apache_g"
|
||||
x1={-1978.18}
|
||||
y1={4998.33}
|
||||
x2={-1925.22}
|
||||
y2={4998.33}
|
||||
xlinkHref="#apache_b"
|
||||
/>
|
||||
</defs>
|
||||
<title>{'logo_apache'}</title>
|
||||
<path
|
||||
d="M42.56.48C41 1.4 38.39 4 35.28 7.82l2.85 5.39a71.05 71.05 0 0 1 6.1-7.65 3.45 3.45 0 0 1 .25-.26l-.25.26a64.18 64.18 0 0 0-5.72 7.76A108.36 108.36 0 0 0 49.62 12c1.09-6.18-1.08-9-1.08-9S45.79-1.43 42.56.48z"
|
||||
fill="url(#apache_c)"
|
||||
/>
|
||||
<path
|
||||
d="M38.51 13.32q-1.26 1.93-2.75 4.42l-.15.26c-.85 1.43-1.76 3-2.71 4.74q-1.23 2.26-2.57 4.81-1.17 2.23-2.4 4.77l9.45-1a11.45 11.45 0 0 0 5.17-4.07c.32-.45.64-.93 1-1.43 1-1.51 1.92-3.18 2.77-4.84s1.54-3.19 2.1-4.62a22.75 22.75 0 0 0 .83-2.5c.17-.65.31-1.28.41-1.87a105.64 105.64 0 0 1-11.15 1.33z"
|
||||
fill="url(#apache_a)"
|
||||
/>
|
||||
<path
|
||||
d="M29.71 27.15c.87-1.62 1.75-3.21 2.64-4.75s1.85-3.16 2.8-4.66l.16-.27q1.41-2.22 2.83-4.26l-2.86-5.39c-.22.26-.43.53-.65.8-.83 1-1.68 2.13-2.56 3.3-1 1.32-2 2.74-3 4.21s-1.92 2.8-2.89 4.28c-.82 1.26-1.65 2.56-2.47 3.9l-.09.14 3.68 7.35c.79-1.57 1.6-3.12 2.41-4.65z"
|
||||
fill="url(#apache_d)"
|
||||
/>
|
||||
<path
|
||||
d="M27.87 32.42c-.1.22-.21.44-.32.66-.32.67-.65 1.34-1 2s-.71 1.51-1.08 2.3c-.18.39-.37.79-.55 1.2-.56 1.2-1.12 2.45-1.69 3.74-.71 1.59-1.42 3.23-2.15 5s-1.38 3.3-2.08 5.05-1.36 3.37-2 5.13c-.62 1.57-1.24 3.18-1.87 4.85l-.09.24q-.95 2.47-1.89 5.08v.12l3-.33a1.35 1.35 0 0 0-.18 0c3.5-.46 8.28-3.17 11.37-6.46a27.81 27.81 0 0 0 3.91-5.44 45.77 45.77 0 0 0 2.52-5.24c.7-1.68 1.36-3.51 2-5.49a10.65 10.65 0 0 1-2.82 1l-.56.11-.57.09a13.11 13.11 0 0 0 7-6.83 11.73 11.73 0 0 1-4 1.76 6 6 0 0 1-.72.13h-.18a13.55 13.55 0 0 0 3-1.67c.18-.14.36-.28.53-.43a9.88 9.88 0 0 0 .74-.71c.15-.16.3-.32.44-.49a11.23 11.23 0 0 0 .94-1.29l.27-.44.32-.63a35.043 35.043 0 0 0 1.53-3.52l.13-.37c.11-.35.21-.67.29-.94s.18-.75.22-1a3.77 3.77 0 0 1-.39.26 14.18 14.18 0 0 1-4.15 1.42h-.07l-.42.07h.07l-9.44 1z"
|
||||
fill="url(#apache_e)"
|
||||
/>
|
||||
<path
|
||||
d="M14.17 61.81q1-2.52 2-5.1t2-5q1-2.49 2.12-5c.74-1.69 1.49-3.39 2.25-5.07s1.52-3.32 2.3-5c.28-.59.57-1.18.85-1.76.49-1 1-2 1.49-3l.09-.16-3.72-7.35c-.06.1-.12.2-.19.3-.86 1.42-1.72 2.86-2.57 4.34s-1.7 3-2.52 4.56c-.69 1.3-1.37 2.61-2 3.94l-.39.8q-1.22 2.51-2.2 4.83c-.75 1.75-1.41 3.43-2 5q-.57 1.57-1 3c-.26.83-.5 1.66-.74 2.48q-.83 2.93-1.43 5.83l3.7 7.55c.5-1.32 1-2.66 1.52-4 .15-.43.27-.81.44-1.19z"
|
||||
fill="url(#apache_f)"
|
||||
/>
|
||||
<path
|
||||
d="M12.77 68.54c-.49 1.36-1 2.73-1.48 4.14v.06l-.21.6-1.32 3.75c1.1.49 2 1.81 2.81 3.3a6 6 0 0 0-1.94-4.12c5.4.25 10.06-1.12 12.46-5.07a9.11 9.11 0 0 0 .59-1.12c-1.09 1.39-2.45 2-5 1.84 3.76-1.69 5.64-3.3 7.31-6 .39-.63.78-1.32 1.17-2.09a11.77 11.77 0 0 1-11.1 3.6l-3 .33c-.06.24-.2.53-.29.78z"
|
||||
fill="url(#apache_b)"
|
||||
/>
|
||||
<path
|
||||
d="M8.43 59.84a55.52 55.52 0 0 0-1 7 2 2 0 0 0 0 .25 14.73 14.73 0 0 0-4.29-3.68c2.24 3.24 3.94 6.46 4.19 9.62a9.47 9.47 0 0 1-4.73-.81 9.38 9.38 0 0 0 4 2.45c-1.81.12-3.7 1.36-5.61 2.8 2.79-1.14 5-1.59 6.65-1.22C5.12 83.53 2.56 91.52 0 100a2.24 2.24 0 0 0 1.52-1.47C2 97 5 86.92 9.75 73.67c.14-.37.27-.75.41-1.13l.12-.32c.5-1.39 1-2.8 1.56-4.25.12-.33.24-.66.37-1l-3.73-7.39a2.38 2.38 0 0 0-.05.26z"
|
||||
fill="url(#apache_g)"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogoApache
|
|
@ -0,0 +1,67 @@
|
|||
// Libraries
|
||||
import React, {SFC} from 'react'
|
||||
|
||||
interface Props {
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
const LogoConsul: SFC<Props> = ({height, width}) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 100 96.81"
|
||||
>
|
||||
<style>
|
||||
{` .consul_a { fill: #8c1c59; }
|
||||
.consul_a, .consul_b {
|
||||
fill-rule: evenodd;
|
||||
}
|
||||
.consul_b, .consul_c {
|
||||
fill: #c62a71;
|
||||
}`}
|
||||
</style>
|
||||
<defs />
|
||||
<path
|
||||
className="consul_a"
|
||||
d="M48.23,58.73A10.45,10.45,0,1,1,58.65,48.27,10.42,10.42,0,0,1,48.23,58.73"
|
||||
/>
|
||||
<path
|
||||
className="consul_b"
|
||||
d="M68.55,53.1a4.82,4.82,0,1,1,4.81-4.81,4.8,4.8,0,0,1-4.81,4.81"
|
||||
/>
|
||||
<path
|
||||
className="consul_b"
|
||||
d="M86.17,57.64h0a4.69,4.69,0,1,1,.09-.38c0,.12,0,.24-.09.38"
|
||||
/>
|
||||
<path
|
||||
className="consul_b"
|
||||
d="M82.76,45.23a4.82,4.82,0,1,1,3.57-5.79,5,5,0,0,1,0,1.89,4.62,4.62,0,0,1-3.62,3.9"
|
||||
/>
|
||||
<path
|
||||
className="consul_b"
|
||||
d="M99.89,57.11a4.47,4.47,0,1,1,.09-.43,1.18,1.18,0,0,0-.09.43"
|
||||
/>
|
||||
<path
|
||||
className="consul_b"
|
||||
d="M96,45a4.8,4.8,0,1,1,4-5.53,5.16,5.16,0,0,1,0,1.24A4.79,4.79,0,0,1,96,45"
|
||||
/>
|
||||
<path
|
||||
className="consul_b"
|
||||
d="M92.61,73.78h0a4.85,4.85,0,1,1,.6-2,4.34,4.34,0,0,1-.6,2"
|
||||
/>
|
||||
<path
|
||||
className="consul_b"
|
||||
d="M90.87,29.53A4.83,4.83,0,1,1,92.71,23a4.52,4.52,0,0,1,.59,2.79,4.83,4.83,0,0,1-2.43,3.79"
|
||||
/>
|
||||
<path
|
||||
className="consul_c"
|
||||
d="M48.4,96.81A48.35,48.35,0,0,1,0,48.4,48.41,48.41,0,0,1,77.8,9.94l-5.91,7.72A38.7,38.7,0,0,0,21,75.78a38.72,38.72,0,0,0,50.85,3.36l5.91,7.73A48,48,0,0,1,48.4,96.81Z"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogoConsul
|
|
@ -0,0 +1,50 @@
|
|||
// Libraries
|
||||
import React, {SFC} from 'react'
|
||||
|
||||
interface Props {
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
const LogoCpu: SFC<Props> = ({height, width}) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
id="Layer_1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 100 100"
|
||||
>
|
||||
<g id="cpu_icon">
|
||||
<style>
|
||||
{`
|
||||
.cpu_a{fill:#7A65F1;}
|
||||
.cpu_b{fill:none;stroke:#2C323D;stroke-width:7;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||
.cpu_c{fill:#2C323D;}
|
||||
`}
|
||||
</style>
|
||||
<path
|
||||
className="cpu_a"
|
||||
d="M96,100H4c-2.2,0-4-1.8-4-4V4c0-2.2,1.8-4,4-4h92c2.2,0,4,1.8,4,4v92C100,98.2,98.2,100,96,100z"
|
||||
/>
|
||||
<line className="cpu_b" x1="22.2" y1="100" x2="22.2" />
|
||||
<line className="cpu_b" x1="40.7" y1="100" x2="40.7" />
|
||||
<line className="cpu_b" x1="59.3" y1="100" x2="59.3" />
|
||||
<line className="cpu_b" x1="77.8" y1="100" x2="77.8" />
|
||||
<line className="cpu_b" y1="22.2" x2="100" y2="22.2" />
|
||||
<line className="cpu_b" y1="40.7" x2="100" y2="40.7" />
|
||||
<line className="cpu_b" y1="59.3" x2="100" y2="59.3" />
|
||||
<line className="cpu_b" y1="77.8" x2="100" y2="77.8" />
|
||||
<g>
|
||||
<rect x="17" y="17" className="cpu_a" width="66" height="66" />
|
||||
<path
|
||||
className="cpu_c"
|
||||
d="M76,24v52H24V24H76 M88,10H12c-1.1,0-2,0.9-2,2v76c0,1.1,0.9,2,2,2h76c1.1,0,2-0.9,2-2V12 C90,10.9,89.1,10,88,10L88,10z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogoCpu
|
|
@ -0,0 +1,92 @@
|
|||
// Libraries
|
||||
import React, {SFC} from 'react'
|
||||
|
||||
interface Props {
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
const LogoDocker: SFC<Props> = ({height, width}) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 100 69.46"
|
||||
>
|
||||
<style>
|
||||
{`
|
||||
.docker_a, .docker_b {
|
||||
fill: #066da5;
|
||||
}
|
||||
.docker_a {
|
||||
fill-rule: evenodd;
|
||||
}`}
|
||||
</style>
|
||||
<defs />
|
||||
<path
|
||||
className="docker_a"
|
||||
d="M97.92,26.44c-2.26-1.51-7.44-2.06-11.43-1.31-.51-3.75-2.61-7-6.41-9.95l-2.19-1.46-1.46,2.19a17,17,0,0,0-2.5,10.47,13.29,13.29,0,0,0,1.93,5.75,15.74,15.74,0,0,1-7.57,1.66H.39l-.14.78c-.64,3.77-.62,15.52,7,24.55C13.05,66,21.75,69.46,33.09,69.46c24.6,0,42.8-11.32,51.32-31.9,3.35.07,10.56,0,14.27-7.06.1-.17.32-.59,1-1.93l.35-.74Z"
|
||||
/>
|
||||
<rect className="docker_b" x="44.36" width="10.33" height="9.39" />
|
||||
<rect
|
||||
className="docker_b"
|
||||
x="44.36"
|
||||
y="11.26"
|
||||
width="10.33"
|
||||
height="9.39"
|
||||
/>
|
||||
<rect
|
||||
className="docker_b"
|
||||
x="32.15"
|
||||
y="11.26"
|
||||
width="10.33"
|
||||
height="9.39"
|
||||
/>
|
||||
<rect
|
||||
className="docker_b"
|
||||
x="19.95"
|
||||
y="11.26"
|
||||
width="10.33"
|
||||
height="9.39"
|
||||
/>
|
||||
<rect
|
||||
className="docker_b"
|
||||
x="7.75"
|
||||
y="22.53"
|
||||
width="10.33"
|
||||
height="9.39"
|
||||
/>
|
||||
<rect
|
||||
className="docker_b"
|
||||
x="19.95"
|
||||
y="22.53"
|
||||
width="10.33"
|
||||
height="9.39"
|
||||
/>
|
||||
<rect
|
||||
className="docker_b"
|
||||
x="32.15"
|
||||
y="22.53"
|
||||
width="10.33"
|
||||
height="9.39"
|
||||
/>
|
||||
<rect
|
||||
className="docker_b"
|
||||
x="44.36"
|
||||
y="22.53"
|
||||
width="10.33"
|
||||
height="9.39"
|
||||
/>
|
||||
<rect
|
||||
className="docker_b"
|
||||
x="56.56"
|
||||
y="22.53"
|
||||
width="10.33"
|
||||
height="9.39"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogoDocker
|
|
@ -0,0 +1,80 @@
|
|||
// Libraries
|
||||
import React, {SFC} from 'react'
|
||||
|
||||
interface Props {
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
const LogoElastic: SFC<Props> = ({height, width}) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 100 99.61"
|
||||
>
|
||||
<style>
|
||||
{`
|
||||
.elastic_a {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
.elastic_b {
|
||||
fill: #ffd00a;
|
||||
}
|
||||
|
||||
.elastic_c {
|
||||
fill: #20b9af;
|
||||
}
|
||||
|
||||
.elastic_d {
|
||||
fill: #ee5096;
|
||||
}
|
||||
|
||||
.elastic_e {
|
||||
fill: #12a5df;
|
||||
}
|
||||
|
||||
.elastic_f {
|
||||
fill: #90c640;
|
||||
}
|
||||
|
||||
.elastic_g {
|
||||
fill: #05799f;
|
||||
}`}
|
||||
</style>
|
||||
<defs />
|
||||
<path
|
||||
className="elastic_a"
|
||||
d="M100,52.19A19.68,19.68,0,0,0,87,33.63a27.49,27.49,0,0,0,.53-5.38A28.24,28.24,0,0,0,36.36,11.72,15,15,0,0,0,13.12,28.8,20,20,0,0,0,0,47.44,19.69,19.69,0,0,0,13.08,66.05,28.17,28.17,0,0,0,63.63,87.84a14.84,14.84,0,0,0,9.19,3.21A15,15,0,0,0,86.88,70.82,19.94,19.94,0,0,0,100,52.19"
|
||||
/>
|
||||
<path
|
||||
className="elastic_b"
|
||||
d="M39.32,42.9l21.88,10L83.27,33.53a24.32,24.32,0,0,0,.48-4.85,24.67,24.67,0,0,0-45-13.95L35,33.78Z"
|
||||
/>
|
||||
<path
|
||||
className="elastic_c"
|
||||
d="M16.67,66.07A25.13,25.13,0,0,0,16.18,71a24.74,24.74,0,0,0,45.2,13.91l3.65-19-4.87-9.29-22-10Z"
|
||||
/>
|
||||
<path
|
||||
className="elastic_d"
|
||||
d="M16.53,28.2l15,3.55,3.29-17A11.84,11.84,0,0,0,16.53,28.2"
|
||||
/>
|
||||
<path
|
||||
className="elastic_e"
|
||||
d="M15.23,31.78A16.69,16.69,0,0,0,3.87,47.48,16.52,16.52,0,0,0,14.51,62.93l21-19-3.87-8.26Z"
|
||||
/>
|
||||
<path
|
||||
className="elastic_f"
|
||||
d="M65.23,84.91A11.82,11.82,0,0,0,83.47,71.42l-15-3.5Z"
|
||||
/>
|
||||
<path
|
||||
className="elastic_g"
|
||||
d="M68.28,64l16.49,3.86A16.7,16.7,0,0,0,96.13,52.14,16.49,16.49,0,0,0,85.47,36.72L63.9,55.62Z"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogoElastic
|
|
@ -0,0 +1,38 @@
|
|||
// Libraries
|
||||
import React, {SFC} from 'react'
|
||||
|
||||
interface Props {
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
const LogoEtcd: SFC<Props> = ({height, width}) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 100 96.61"
|
||||
>
|
||||
<style>{`
|
||||
.etcd_a {
|
||||
fill: #419eda;
|
||||
}`}</style>
|
||||
<defs />
|
||||
<path
|
||||
className="etcd_a"
|
||||
d="M45.77,43a6.52,6.52,0,1,1-6.52-6.52A6.52,6.52,0,0,1,45.77,43Z"
|
||||
/>
|
||||
<path
|
||||
className="etcd_a"
|
||||
d="M54.2,43a6.52,6.52,0,1,0,6.52-6.52A6.52,6.52,0,0,0,54.2,43Z"
|
||||
/>
|
||||
<path
|
||||
className="etcd_a"
|
||||
d="M98.59,50c-.47,0-.94.06-1.44.06a18.79,18.79,0,0,1-8.28-1.93A75.91,75.91,0,0,0,90,33.51a76.15,76.15,0,0,0-9.47-11.23,18.71,18.71,0,0,1,6.68-7.15l1.22-.76-1-1.08A49.92,49.92,0,0,0,70,.58L68.7,0l-.34,1.4A18.74,18.74,0,0,1,63.64,10,76.58,76.58,0,0,0,50,4.35,75.82,75.82,0,0,0,36.35,10a18.71,18.71,0,0,1-4.71-8.56L31.3,0,30,.58A50.43,50.43,0,0,0,12.55,13.29l-1,1.08,1.22.75a18.8,18.8,0,0,1,6.66,7.12A76.39,76.39,0,0,0,10,33.43a76.53,76.53,0,0,0,1.09,14.74,18.73,18.73,0,0,1-8.23,1.91c-.51,0-1,0-1.44,0L0,49.92l.13,1.43A49.62,49.62,0,0,0,6.84,71.87l.73,1.24,1.09-.93A18.73,18.73,0,0,1,17.55,68a75.64,75.64,0,0,0,7.6,12.38,77.51,77.51,0,0,0,14.4,3.54,18.65,18.65,0,0,1-1.2,9.83l-.54,1.33,1.4.31A50.56,50.56,0,0,0,50,96.61l10.79-1.2,1.4-.31-.55-1.33a18.79,18.79,0,0,1-1.19-9.84A77,77,0,0,0,74.81,80.4,76.56,76.56,0,0,0,82.42,68a18.9,18.9,0,0,1,8.92,4.17l1.1.93.73-1.24a49.56,49.56,0,0,0,6.7-20.51l.13-1.43ZM65.43,67.56a58.15,58.15,0,0,1-30.9,0,59.69,59.69,0,0,1-6.61-13.93,59.09,59.09,0,0,1-2.79-15.29,58.8,58.8,0,0,1,11.2-10.66A60,60,0,0,1,50,20.25a60.26,60.26,0,0,1,13.64,7.41A59.14,59.14,0,0,1,74.86,38.4a59.17,59.17,0,0,1-2.81,15.21A59.67,59.67,0,0,1,65.43,67.56Z"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogoEtcd
|
|
@ -0,0 +1,93 @@
|
|||
// Libraries
|
||||
import React, {SFC} from 'react'
|
||||
|
||||
interface Props {
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
const LogoIis: SFC<Props> = ({height, width}) => {
|
||||
return (
|
||||
<svg width={width} height={height} viewBox="0 0 100 100">
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="iis_b"
|
||||
x1={-514.77}
|
||||
y1={316.77}
|
||||
x2={-514.77}
|
||||
y2={316.81}
|
||||
gradientTransform="matrix(2493.7 0 0 -2493.7 1283740.92 790028.16)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset={0} stopColor="#574c4a" />
|
||||
<stop offset={1} stopColor="#80716d" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="iis_c"
|
||||
x1={-514.92}
|
||||
y1={316.94}
|
||||
x2={-514.95}
|
||||
y2={316.99}
|
||||
gradientTransform="matrix(1567.75 0 0 -1504.18 807337.55 476821.08)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset={0} stopColor="#268d83" />
|
||||
<stop offset={1} stopColor="#2ea19e" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
id="iis_a"
|
||||
cx={-517.38}
|
||||
cy={323.85}
|
||||
r={0.02}
|
||||
gradientTransform="matrix(181.37 0 0 -181.37 93879.52 58811.53)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset={0} stopColor="#db7c7c" />
|
||||
<stop offset={1} stopColor="#c83737" />
|
||||
</radialGradient>
|
||||
<radialGradient
|
||||
id="iis_d"
|
||||
cx={-519.14}
|
||||
cy={323.85}
|
||||
r={0.02}
|
||||
gradientTransform="matrix(181.36 0 0 -181.36 94206.95 58808.39)"
|
||||
xlinkHref="#iis_a"
|
||||
/>
|
||||
</defs>
|
||||
<title>{'logo_iis'}</title>
|
||||
<path
|
||||
d="M0 67.57V32.43C0 4.05 4.05 0 32.4 0h35.2C96 0 100 4.05 100 32.43v35.14C100 96 96 100 67.6 100H32.4C4.05 100 0 96 0 67.57z"
|
||||
fill="url(#iis_b)"
|
||||
/>
|
||||
<path
|
||||
d="M21.58 18.85a279.62 279.62 0 0 0-2.34 60.32H34.6c-1.46-7.78-6.7-43.31-2.34-43.43 2.34.37 13 30.15 13 30.15a42.66 42.66 0 0 1 4.72-.3 42.66 42.66 0 0 1 4.72.3s10.68-29.78 13-30.15c4.36.12-.88 35.65-2.34 43.43h15.4a279.62 279.62 0 0 0-2.34-60.32H64.19c-2.7 0-13 18.1-14.19 18.1s-11.48-18.07-14.19-18.1z"
|
||||
fill="url(#iis_c)"
|
||||
/>
|
||||
<path
|
||||
d="M47 75.53a3.64 3.64 0 1 1-3.64-3.64A3.64 3.64 0 0 1 47 75.53z"
|
||||
fill="url(#iis_a)"
|
||||
/>
|
||||
<path
|
||||
d="M60.3 75.53a3.64 3.64 0 1 1-3.63-3.64 3.63 3.63 0 0 1 3.63 3.64z"
|
||||
fill="url(#iis_d)"
|
||||
/>
|
||||
<path
|
||||
d="M77.69 19.88A272.7 272.7 0 0 1 80.39 60c0 11-.67 18.11-.67 18.11H66.79l-1.39 1h15.36a279.62 279.62 0 0 0-2.34-60.32l-.73 1zM37 19.5c4 4.5 11 16.41 12 16.41-2.6-3.28-8.89-13.72-12-16.41zm-5.78 15.2c-4.36.12.88 35.65 2.34 43.43H20.15l-.91 1H34.6c-1.45-7.74-6.65-43-2.41-43.43-.39-.59-.73-1-1-1zm35.48 0c-2.34.37-13 30.14-13 30.14a44.1 44.1 0 0 0-4.7-.29c-1.4 0-2.61.09-3.42.16l-.26 1.18a42.66 42.66 0 0 1 4.72-.3 42.66 42.66 0 0 1 4.72.3s10.6-29.58 13-30.15c-.26-.65-.58-1-1-1z"
|
||||
style={{
|
||||
isolation: 'isolate',
|
||||
}}
|
||||
opacity={0.1}
|
||||
/>
|
||||
<path
|
||||
d="M21.58 18.85a279.62 279.62 0 0 0-2.34 60.32l.9-1a279.63 279.63 0 0 1 2.48-58.26h14.23a2.21 2.21 0 0 1 1.17.65c-.93-1-1.7-1.69-2.21-1.69zm42.61 0c-2.7 0-13 18.1-14.19 18.1.48.61.88 1 1 1 1.19 0 11.49-18.07 14.19-18.1h12.6l.63-1zM33.24 36.78c3.45 5.19 12 29.11 12 29.11l.25-1.17c-2.12-5.81-10.2-27.61-12.23-27.94zm35.54 0c2.32 5.92-2.07 35.39-3.38 42.39l1.39-1.09c1.78-10.44 6.06-41.19 1.99-41.3z"
|
||||
style={{
|
||||
isolation: 'isolate',
|
||||
}}
|
||||
fill="#fff"
|
||||
opacity={0.3}
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogoIis
|
|
@ -0,0 +1,41 @@
|
|||
// Libraries
|
||||
import React, {SFC} from 'react'
|
||||
|
||||
interface Props {
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
const LogoKubernetes: SFC<Props> = ({height, width}) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 100 97.03"
|
||||
>
|
||||
<style>
|
||||
{`
|
||||
.kubernetes_a {
|
||||
fill: #326ce5;
|
||||
}
|
||||
.kubernetes_b {
|
||||
fill: #fff;
|
||||
stroke: #fff;
|
||||
stroke-width: 0.25px;
|
||||
}`}
|
||||
</style>
|
||||
<defs />
|
||||
<path
|
||||
className="kubernetes_a"
|
||||
d="M49.65,0a6.57,6.57,0,0,0-2.54.64L12.34,17.26a6.62,6.62,0,0,0-3.6,4.48L.17,59.05a6.55,6.55,0,0,0,.9,5.06,6.28,6.28,0,0,0,.38.52L25.51,94.55A6.67,6.67,0,0,0,30.71,97H69.3a6.65,6.65,0,0,0,5.19-2.48L98.55,64.62A6.56,6.56,0,0,0,99.83,59L91.24,21.73a6.59,6.59,0,0,0-3.59-4.47L52.88.65A6.66,6.66,0,0,0,49.65,0Z"
|
||||
/>
|
||||
<path
|
||||
className="kubernetes_b"
|
||||
d="M50,12.71A2.2,2.2,0,0,0,47.92,15v.06c0,.17,0,.38,0,.53a15.23,15.23,0,0,0,.28,2,19,19,0,0,1,.23,3.77,2.31,2.31,0,0,1-.67,1.08l0,.88A25.73,25.73,0,0,0,44,23.9a26.68,26.68,0,0,0-13.6,7.77l-.75-.54A1.63,1.63,0,0,1,28.36,31a19.42,19.42,0,0,1-2.8-2.53A16.86,16.86,0,0,0,24.19,27l-.46-.37a2.5,2.5,0,0,0-1.45-.54,2,2,0,0,0-1.66.73,2.2,2.2,0,0,0,.51,3.07l0,0,.43.35a17.22,17.22,0,0,0,1.73,1,19.64,19.64,0,0,1,3.09,2.17,2.29,2.29,0,0,1,.42,1.2l.67.6A26.91,26.91,0,0,0,23.25,54l-.87.25a2.9,2.9,0,0,1-.9.91,19.74,19.74,0,0,1-3.73.61,17.37,17.37,0,0,0-2,.16l-.56.13h0a2.09,2.09,0,1,0,.93,4.06h.07l.54-.12a16.34,16.34,0,0,0,1.86-.72,19.72,19.72,0,0,1,3.63-1.06,2.22,2.22,0,0,1,1.2.42l.91-.16a27.09,27.09,0,0,0,12,15l-.38.9a2.14,2.14,0,0,1,.18,1.18A20.07,20.07,0,0,1,34.21,79a17.78,17.78,0,0,0-1.12,1.66c-.08.15-.18.39-.26.56A2.09,2.09,0,1,0,36.58,83h0c.08-.16.19-.37.26-.53a18.84,18.84,0,0,0,.6-1.9c.55-1.39.85-2.84,1.61-3.74a1.6,1.6,0,0,1,.89-.44l.48-.85a26.86,26.86,0,0,0,15.63,1.12,27.81,27.81,0,0,0,3.57-1.07c.13.23.38.68.44.8a1.62,1.62,0,0,1,1.07.64,20,20,0,0,1,1.42,3.5,17.5,17.5,0,0,0,.61,1.91c.06.15.18.37.26.53a2.09,2.09,0,1,0,3.76-1.78l-.27-.56a19.21,19.21,0,0,0-1.12-1.66A19.55,19.55,0,0,1,64,75.62a1.69,1.69,0,0,1,.16-1.23c-.07-.09-.24-.6-.34-.84a27.07,27.07,0,0,0,12-15.09l.89.16a1.62,1.62,0,0,1,1.17-.43,19.72,19.72,0,0,1,3.63,1.06,16.34,16.34,0,0,0,1.86.72l.54.12h.07a2.09,2.09,0,1,0,.93-4.06c-.18,0-.43-.11-.61-.14a17.37,17.37,0,0,0-2-.16,19.74,19.74,0,0,1-3.73-.61,2.29,2.29,0,0,1-.9-.91L76.78,54a27.05,27.05,0,0,0-4.34-18.73l.74-.66a1.66,1.66,0,0,1,.39-1.18,19.31,19.31,0,0,1,3.1-2.17,18.41,18.41,0,0,0,1.73-1l.45-.37a2.09,2.09,0,1,0-2.59-3.26L75.8,27a16.86,16.86,0,0,0-1.37,1.46A20.12,20.12,0,0,1,71.62,31a2.3,2.3,0,0,1-1.26.13l-.79.57a27.32,27.32,0,0,0-17.28-8.35c0-.27,0-.78,0-.93a1.68,1.68,0,0,1-.68-1,19.1,19.1,0,0,1,.24-3.77,15.23,15.23,0,0,0,.28-2c0-.17,0-.41,0-.59A2.2,2.2,0,0,0,50,12.71ZM47.39,28.85l-.62,10.91,0,0a1.84,1.84,0,0,1-1.83,1.76,1.81,1.81,0,0,1-1.08-.35h0l-8.95-6.35a21.5,21.5,0,0,1,12.54-6Zm5.22,0a21.55,21.55,0,0,1,12.46,6l-8.89,6.3h0a1.84,1.84,0,0,1-2.92-1.4h0Zm-21,10.08,8.18,7.31v0A1.85,1.85,0,0,1,40,48.81a1.82,1.82,0,0,1-1,.63v0l-10.48,3A21.49,21.49,0,0,1,31.6,38.93Zm36.73,0a21.73,21.73,0,0,1,3.14,13.53l-10.53-3v0a1.83,1.83,0,0,1-1.3-2.18,1.86,1.86,0,0,1,.58-1v0l8.12-7.28Zm-20,7.87h3.35l2.08,2.61L53,52.65,50,54.1l-3-1.45-.74-3.25Zm10.73,8.91a1.53,1.53,0,0,1,.43,0v0l10.84,1.84a21.49,21.49,0,0,1-8.67,10.89L57.45,58.28h0a1.84,1.84,0,0,1,.89-2.38,1.81,1.81,0,0,1,.7-.18Zm-18.19,0a1.85,1.85,0,0,1,1.76,1.43,1.82,1.82,0,0,1-.11,1.13l0,0L38.38,68.4a21.45,21.45,0,0,1-8.64-10.82l10.74-1.82,0,0a2.19,2.19,0,0,1,.36,0Zm9.07,4.41a1.76,1.76,0,0,1,.86.18,1.82,1.82,0,0,1,.82.78h0L57,70.69a21.87,21.87,0,0,1-13.86,0l5.28-9.55h0A1.82,1.82,0,0,1,49.93,60.16Z"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogoKubernetes
|
|
@ -0,0 +1,127 @@
|
|||
// Libraries
|
||||
import React, {SFC} from 'react'
|
||||
|
||||
interface Props {
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
const LogoMesos: SFC<Props> = ({height, width}) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 87.83 100"
|
||||
>
|
||||
<style>
|
||||
{`
|
||||
.mesos_a {
|
||||
fill: #00445e;
|
||||
}
|
||||
.mesos_b {
|
||||
fill: #00aede;
|
||||
}`}
|
||||
</style>
|
||||
<defs />
|
||||
<polyline
|
||||
className="mesos_a"
|
||||
points="65.28 60.91 65.28 39.09 46.46 50.02 65.28 60.91"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_b"
|
||||
points="64.06 36.96 45.21 26.06 45.21 47.89 64.06 36.96"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_b"
|
||||
points="42.76 47.89 42.76 26.06 23.89 36.96 42.76 47.89"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_b"
|
||||
points="41.54 23.96 22.69 13 22.69 34.86 41.54 23.96"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_a"
|
||||
points="64.06 63.01 45.21 52.12 45.21 73.95 64.06 63.01"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_a"
|
||||
points="42.76 73.95 42.76 52.12 23.89 63.01 42.76 73.95"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_b"
|
||||
points="86.61 50.02 67.73 39.09 67.73 60.91 86.61 50.02"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_b"
|
||||
points="20.23 34.86 20.23 13 1.24 23.96 20.23 34.86"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_a"
|
||||
points="41.54 76.05 22.69 65.12 22.69 86.97 41.54 76.05"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_b"
|
||||
points="20.23 86.97 20.23 65.12 1.24 76.05 20.23 86.97"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_a"
|
||||
points="41.54 50.02 22.69 39.09 22.69 60.91 41.54 50.02"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_b"
|
||||
points="65.28 34.86 65.28 13 46.46 23.96 65.28 34.86"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_a"
|
||||
points="45.21 0 45.21 21.82 64.06 10.9 45.21 0"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_a"
|
||||
points="23.89 10.9 42.76 21.82 42.76 0 23.89 10.9"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_a"
|
||||
points="64.06 89.07 45.21 78.18 45.21 100 64.06 89.07"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_a"
|
||||
points="42.76 100 42.76 78.18 23.89 89.07 42.76 100"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_b"
|
||||
points="87.83 73.95 87.83 52.12 69 63.01 87.83 73.95"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_b"
|
||||
points="20.23 60.91 20.23 39.05 1.24 50.02 20.23 60.91"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_b"
|
||||
points="19.02 63.01 0 52.12 0 73.95 19.02 63.01"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_b"
|
||||
points="87.83 47.89 87.83 26.06 69 36.96 87.83 47.89"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_b"
|
||||
points="86.61 23.96 67.73 13 67.73 34.86 86.61 23.96"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_b"
|
||||
points="86.61 76.05 67.73 65.12 67.73 86.97 86.61 76.05"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_a"
|
||||
points="65.28 86.97 65.28 65.12 46.46 76.05 65.28 86.97"
|
||||
/>
|
||||
<polyline
|
||||
className="mesos_b"
|
||||
points="19.02 36.96 0 26.06 0 47.89 19.02 36.96"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogoMesos
|
|
@ -0,0 +1,76 @@
|
|||
// Libraries
|
||||
import React, {SFC} from 'react'
|
||||
|
||||
interface Props {
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
const LogoMongodb: SFC<Props> = ({height, width}) => {
|
||||
return (
|
||||
<svg width={width} height={height} viewBox="0 0 44.83 100">
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="mongodb_a"
|
||||
x1={-960.8}
|
||||
y1={-1260.14}
|
||||
x2={-992.42}
|
||||
y2={-1260.35}
|
||||
gradientTransform="matrix(-.98 -.32 .29 -.88 -566.27 -1364.86)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset={0.23} stopColor="#999875" />
|
||||
<stop offset={0.56} stopColor="#9b9977" />
|
||||
<stop offset={0.68} stopColor="#a09f7e" />
|
||||
<stop offset={0.77} stopColor="#a9a889" />
|
||||
<stop offset={0.84} stopColor="#b7b69a" />
|
||||
<stop offset={0.9} stopColor="#c9c7b0" />
|
||||
<stop offset={0.95} stopColor="#deddcb" />
|
||||
<stop offset={0.99} stopColor="#f8f6eb" />
|
||||
<stop offset={1} stopColor="#fbf9ef" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="mongodb_b"
|
||||
x1={-955.93}
|
||||
y1={-1204.8}
|
||||
x2={-1001.42}
|
||||
y2={-1283.59}
|
||||
gradientTransform="matrix(-.98 -.32 .29 -.88 -566.27 -1364.86)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset={0} stopColor="#48a547" />
|
||||
<stop offset={1} stopColor="#3f9143" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="mongodb_c"
|
||||
x1={-951.77}
|
||||
y1={-1261.44}
|
||||
x2={-984.01}
|
||||
y2={-1239.78}
|
||||
gradientTransform="matrix(-.98 -.32 .29 -.88 -566.27 -1364.86)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset={0} stopColor="#41a247" />
|
||||
<stop offset={0.35} stopColor="#4ba74b" />
|
||||
<stop offset={0.96} stopColor="#67b554" />
|
||||
<stop offset={1} stopColor="#69b655" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<title>{'logo_mongodb'}</title>
|
||||
<path
|
||||
d="M24.7 100l-2.7-.89s.34-13.57-4.55-14.52c-3.23-3.74.49-159.8 12.22-.54 0 0-4 2-4.77 5.44S24.7 100 24.7 100z"
|
||||
fill="url(#mongodb_a)"
|
||||
/>
|
||||
<path
|
||||
d="M26.15 86.89S49.46 71.54 44 39.66C38.74 16.5 26.32 8.88 25 6a35 35 0 0 1-3-5.73l1 64.54s-2 19.7 3.15 22.08z"
|
||||
fill="url(#mongodb_b)"
|
||||
/>
|
||||
<path
|
||||
d="M20.66 87.75S-1.21 72.83.05 46.52s16.7-39.26 19.71-41.6C21.7 2.84 21.78 2 21.93 0c1.37 2.93 1.14 43.73 1.29 48.49.56 18.57-1.03 35.75-2.56 39.26z"
|
||||
fill="url(#mongodb_c)"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogoMongodb
|
|
@ -0,0 +1,43 @@
|
|||
// Libraries
|
||||
import React, {SFC} from 'react'
|
||||
|
||||
interface Props {
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
const LogoMysql: SFC<Props> = ({height, width}) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 100 98.16"
|
||||
>
|
||||
<style>
|
||||
{` .mysql_a {
|
||||
fill: #687e91;
|
||||
}
|
||||
|
||||
.mysql_a, .mysql_b {
|
||||
fill-rule: evenodd;
|
||||
}
|
||||
|
||||
.mysql_b {
|
||||
fill: #00758f;
|
||||
}`}
|
||||
</style>
|
||||
<defs />
|
||||
<path
|
||||
className="mysql_a"
|
||||
d="M22.74,16.82a11,11,0,0,0-2.79.34v.14h.13a22.93,22.93,0,0,0,2.18,2.79c.55,1.09,1,2.17,1.56,3.26l.14-.14a3.81,3.81,0,0,0,1.43-3.4c-.41-.48-.47-.95-.82-1.43-.4-.68-1.29-1-1.83-1.56"
|
||||
/>
|
||||
<path
|
||||
className="mysql_b"
|
||||
d="M92.11,75.92c-5.44-.13-9.66.41-13.19,1.91-1,.41-2.65.41-2.79,1.7.54.54.61,1.43,1.09,2.18a16,16,0,0,0,3.53,4.15C82.18,86.94,83.61,88,85.11,89c2.65,1.64,5.64,2.59,8.22,4.22,1.5,1,3,2.18,4.5,3.2.74.54,1.21,1.43,2.17,1.76V98c-.48-.61-.61-1.5-1.09-2.18-.68-.68-1.36-1.29-2-2a32.43,32.43,0,0,0-7.07-6.87c-2.18-1.5-6.94-3.54-7.82-6l-.14-.13a27.9,27.9,0,0,0,4.7-1.1c2.3-.61,4.41-.47,6.79-1.08,1.09-.28,2.18-.62,3.27-1V77c-1.23-1.22-2.11-2.86-3.4-4A91.89,91.89,0,0,0,82,64.63c-2.11-1.36-4.83-2.24-7.08-3.4-.81-.41-2.17-.61-2.65-1.29a27.59,27.59,0,0,1-2.79-5.24c-2-3.73-3.88-7.88-5.57-11.83-1.23-2.65-2-5.3-3.47-7.75-7-11.57-14.63-18.57-26.32-25.44-2.52-1.43-5.51-2-8.71-2.79-1.7-.07-3.4-.2-5.1-.27-1.09-.48-2.18-1.77-3.13-2.38C13.28,1.79,3.29-3.52.43,3.49c-1.84,4.42,2.72,8.77,4.28,11a31.2,31.2,0,0,1,3.47,5.1c.48,1.15.61,2.38,1.09,3.6a82,82,0,0,0,3.54,9.12,31.18,31.18,0,0,0,2.51,4.21c.55.75,1.5,1.09,1.7,2.32-.95,1.36-1,3.4-1.56,5.1-2.45,7.68-1.5,17.21,2,22.85,1.09,1.7,3.67,5.44,7.14,4,3.06-1.22,2.38-5.1,3.27-8.5.2-.82.07-1.36.47-1.9v.14c1,1.9,1.91,3.73,2.79,5.64A38.69,38.69,0,0,0,40,75.31c1.62,1.23,2.92,3.33,5,4.08v-.2h-.14a7.51,7.51,0,0,0-1.56-1.36,33.69,33.69,0,0,1-3.54-4.08,87.87,87.87,0,0,1-7.61-12.38C31,59.26,30,57,29.13,54.84c-.41-.81-.41-2-1.09-2.45-1,1.5-2.51,2.79-3.26,4.62-1.29,2.93-1.43,6.53-1.91,10.28-.27.07-.13,0-.27.13-2.17-.54-2.92-2.79-3.74-4.69-2-4.83-2.38-12.58-.61-18.16.47-1.43,2.52-5.92,1.7-7.28-.41-1.29-1.77-2-2.52-3.06A26.58,26.58,0,0,1,15,29.88c-1.64-3.81-2.46-8-4.22-11.84a36.81,36.81,0,0,0-3.4-5.23C6.07,11,4.65,9.68,3.62,7.5c-.33-.75-.81-2-.27-2.78a1.09,1.09,0,0,1,1-.89c.88-.75,3.4.2,4.28.61a34.22,34.22,0,0,1,6.73,3.4c1,.68,2,2,3.2,2.32H20c2.17.47,4.62.13,6.67.74a43.68,43.68,0,0,1,9.79,4.7A60.31,60.31,0,0,1,57.62,38.86c.82,1.56,1.17,3,1.91,4.62,1.43,3.34,3.2,6.74,4.63,10A44.15,44.15,0,0,0,69,62.59c1,1.43,5.1,2.18,6.94,2.93a48.85,48.85,0,0,1,4.69,1.9c2.31,1.43,4.62,3.06,6.8,4.63,1.08.81,4.49,2.51,4.69,3.87"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogoMysql
|
|
@ -0,0 +1,39 @@
|
|||
// Libraries
|
||||
import React, {SFC} from 'react'
|
||||
|
||||
interface Props {
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
const LogoNginx: SFC<Props> = ({height, width}) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 87.14 100"
|
||||
>
|
||||
<style>
|
||||
{`
|
||||
.nginx_a {
|
||||
fill: #009438;
|
||||
}
|
||||
.nginx_b {
|
||||
fill: #fefefe;
|
||||
}`}
|
||||
</style>
|
||||
<defs />
|
||||
<path
|
||||
className="nginx_a"
|
||||
d="M0,50.07V26.21a2.14,2.14,0,0,1,1.2-2C15,16.21,28.68,8.35,42.37.4A2.09,2.09,0,0,1,44.68.3L86,24.17a2.22,2.22,0,0,1,1.11,2V73.84a2.22,2.22,0,0,1-1.11,2L50.51,96.42c-1.85,1.11-3.8,2.22-5.65,3.23a2.37,2.37,0,0,1-2.49,0C32,93.73,21.74,87.72,11.38,81.8c-3.42-1.94-6.85-4-10.27-5.92A2.08,2.08,0,0,1,0,73.94Z"
|
||||
/>
|
||||
<path
|
||||
className="nginx_b"
|
||||
d="M29.14,41.19V69a5.75,5.75,0,0,1-5.83,5.83,5.51,5.51,0,0,1-4.72-2.68,4.86,4.86,0,0,1-.74-2.78V30.74a5.59,5.59,0,0,1,3.61-5.27,8.63,8.63,0,0,1,6.11,0,9.8,9.8,0,0,1,4.71,3.23c4,4.81,8,9.62,12,14.43,4.16,5,8.42,10,12.58,15.08a5.25,5.25,0,0,0,.37.46V30.55A5.39,5.39,0,0,1,62.16,25a5.61,5.61,0,0,1,6.39,4.81V69.22A5.16,5.16,0,0,1,65.68,74a8.17,8.17,0,0,1-4.44.83,10.08,10.08,0,0,1-6.11-2.59,35.29,35.29,0,0,1-2.4-2.77C48.19,64,43.66,58.67,39.13,53.22L29.32,41.47C29.32,41.38,29.23,41.28,29.14,41.19Z"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogoNginx
|
|
@ -0,0 +1,27 @@
|
|||
import LogoApache from 'src/onboarding/graphics/LogoApache'
|
||||
import LogoConsul from 'src/onboarding/graphics/LogoConsul'
|
||||
import LogoCpu from 'src/onboarding/graphics/LogoCpu'
|
||||
import LogoDocker from 'src/onboarding/graphics/LogoDocker'
|
||||
import LogoElastic from 'src/onboarding/graphics/LogoElastic'
|
||||
import LogoEtcd from 'src/onboarding/graphics/LogoEtcd'
|
||||
import LogoIis from 'src/onboarding/graphics/LogoIis'
|
||||
import LogoKubernetes from 'src/onboarding/graphics/LogoKubernetes'
|
||||
import LogoMesos from 'src/onboarding/graphics/LogoMesos'
|
||||
import LogoMongodb from 'src/onboarding/graphics/LogoMongodb'
|
||||
import LogoMysql from 'src/onboarding/graphics/LogoMysql'
|
||||
import LogoNginx from 'src/onboarding/graphics/LogoNginx'
|
||||
|
||||
export {
|
||||
LogoApache,
|
||||
LogoConsul,
|
||||
LogoCpu,
|
||||
LogoDocker,
|
||||
LogoElastic,
|
||||
LogoEtcd,
|
||||
LogoIis,
|
||||
LogoKubernetes,
|
||||
LogoMongodb,
|
||||
LogoMesos,
|
||||
LogoMysql,
|
||||
LogoNginx,
|
||||
}
|
|
@ -8,14 +8,26 @@ import dataLoadersReducer, {
|
|||
import {
|
||||
setDataLoadersType,
|
||||
addTelegrafPlugin,
|
||||
addConfigValue,
|
||||
removeConfigValue,
|
||||
removeTelegrafPlugin,
|
||||
setActiveTelegrafPlugin,
|
||||
setTelegrafConfigID,
|
||||
updateTelegrafPluginConfig,
|
||||
} from 'src/onboarding/actions/dataLoaders'
|
||||
|
||||
// Types
|
||||
import {TelegrafPluginInputCpu, TelegrafPluginInputDisk} from 'src/api'
|
||||
import {DataLoaderType, ConfigurationState} from 'src/types/v2/dataLoaders'
|
||||
import {
|
||||
TelegrafPluginInputCpu,
|
||||
TelegrafPluginInputDisk,
|
||||
TelegrafPluginInputRedis,
|
||||
} from 'src/api'
|
||||
import {
|
||||
DataLoaderType,
|
||||
ConfigurationState,
|
||||
TelegrafPlugin,
|
||||
} from 'src/types/v2/dataLoaders'
|
||||
import {redisPlugin} from 'mocks/dummyData'
|
||||
|
||||
describe('dataLoader reducer', () => {
|
||||
it('can set a type', () => {
|
||||
|
@ -129,4 +141,112 @@ describe('dataLoader reducer', () => {
|
|||
|
||||
expect(actual).toEqual(expected)
|
||||
})
|
||||
|
||||
it('can update a plugin config field', () => {
|
||||
const plugin = {
|
||||
...redisPlugin,
|
||||
config: {servers: [], password: ''},
|
||||
}
|
||||
const tp: TelegrafPlugin = {
|
||||
name: TelegrafPluginInputRedis.NameEnum.Redis,
|
||||
configured: ConfigurationState.Unconfigured,
|
||||
active: true,
|
||||
plugin,
|
||||
}
|
||||
const actual = dataLoadersReducer(
|
||||
{...INITIAL_STATE, telegrafPlugins: [tp]},
|
||||
updateTelegrafPluginConfig(
|
||||
TelegrafPluginInputRedis.NameEnum.Redis,
|
||||
'password',
|
||||
'pa$$w0rd'
|
||||
)
|
||||
)
|
||||
|
||||
const expected = {
|
||||
...INITIAL_STATE,
|
||||
telegrafPlugins: [
|
||||
{
|
||||
...tp,
|
||||
plugin: {
|
||||
...plugin,
|
||||
config: {servers: [], password: 'pa$$w0rd'},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
expect(actual).toEqual(expected)
|
||||
})
|
||||
|
||||
it('can add a plugin config value', () => {
|
||||
const plugin = {
|
||||
...redisPlugin,
|
||||
config: {servers: ['first'], password: ''},
|
||||
}
|
||||
const tp: TelegrafPlugin = {
|
||||
name: TelegrafPluginInputRedis.NameEnum.Redis,
|
||||
configured: ConfigurationState.Unconfigured,
|
||||
active: true,
|
||||
plugin,
|
||||
}
|
||||
const actual = dataLoadersReducer(
|
||||
{...INITIAL_STATE, telegrafPlugins: [tp]},
|
||||
addConfigValue(
|
||||
TelegrafPluginInputRedis.NameEnum.Redis,
|
||||
'servers',
|
||||
'second'
|
||||
)
|
||||
)
|
||||
|
||||
const expected = {
|
||||
...INITIAL_STATE,
|
||||
telegrafPlugins: [
|
||||
{
|
||||
...tp,
|
||||
plugin: {
|
||||
...plugin,
|
||||
config: {servers: ['first', 'second'], password: ''},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
expect(actual).toEqual(expected)
|
||||
})
|
||||
|
||||
it('can remove a plugin config value', () => {
|
||||
const plugin = {
|
||||
...redisPlugin,
|
||||
config: {servers: ['first', 'second'], password: ''},
|
||||
}
|
||||
const tp: TelegrafPlugin = {
|
||||
name: TelegrafPluginInputRedis.NameEnum.Redis,
|
||||
configured: ConfigurationState.Unconfigured,
|
||||
active: true,
|
||||
plugin,
|
||||
}
|
||||
const actual = dataLoadersReducer(
|
||||
{...INITIAL_STATE, telegrafPlugins: [tp]},
|
||||
removeConfigValue(
|
||||
TelegrafPluginInputRedis.NameEnum.Redis,
|
||||
'servers',
|
||||
'first'
|
||||
)
|
||||
)
|
||||
|
||||
const expected = {
|
||||
...INITIAL_STATE,
|
||||
telegrafPlugins: [
|
||||
{
|
||||
...tp,
|
||||
plugin: {
|
||||
...plugin,
|
||||
config: {servers: ['second'], password: ''},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
expect(actual).toEqual(expected)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
import _ from 'lodash'
|
||||
|
||||
// Utils
|
||||
import {createNewPlugin} from 'src/onboarding/utils/pluginConfigs'
|
||||
import {
|
||||
createNewPlugin,
|
||||
updateConfigFields,
|
||||
} from 'src/onboarding/utils/pluginConfigs'
|
||||
|
||||
// Types
|
||||
import {Action} from 'src/onboarding/actions/dataLoaders'
|
||||
|
@ -67,10 +70,11 @@ export default (state = INITIAL_STATE, action: Action): DataLoadersState => {
|
|||
|
||||
return {
|
||||
...tp,
|
||||
plugin: {
|
||||
...plugin,
|
||||
[action.payload.field]: action.payload.value,
|
||||
},
|
||||
plugin: updateConfigFields(
|
||||
plugin,
|
||||
action.payload.field,
|
||||
action.payload.value
|
||||
),
|
||||
}
|
||||
}
|
||||
return tp
|
||||
|
@ -90,10 +94,11 @@ export default (state = INITIAL_STATE, action: Action): DataLoadersState => {
|
|||
|
||||
return {
|
||||
...tp,
|
||||
plugin: {
|
||||
...plugin,
|
||||
[action.payload.fieldName]: updatedConfigFieldValue,
|
||||
},
|
||||
plugin: updateConfigFields(
|
||||
plugin,
|
||||
action.payload.fieldName,
|
||||
updatedConfigFieldValue
|
||||
),
|
||||
}
|
||||
}
|
||||
return tp
|
||||
|
@ -117,10 +122,11 @@ export default (state = INITIAL_STATE, action: Action): DataLoadersState => {
|
|||
|
||||
return {
|
||||
...tp,
|
||||
plugin: {
|
||||
...plugin,
|
||||
[action.payload.fieldName]: filteredConfigFieldValue,
|
||||
},
|
||||
plugin: updateConfigFields(
|
||||
plugin,
|
||||
action.payload.fieldName,
|
||||
filteredConfigFieldValue
|
||||
),
|
||||
}
|
||||
}
|
||||
return tp
|
||||
|
|
|
@ -14,6 +14,16 @@ export const getConfigFields = (
|
|||
return telegrafPluginsInfo[pluginName].fields
|
||||
}
|
||||
|
||||
export const updateConfigFields = <T extends Plugin>(
|
||||
plugin: T,
|
||||
fieldName: string,
|
||||
value: string[] | string
|
||||
): T => {
|
||||
return Object.assign({}, plugin, {
|
||||
config: Object.assign({}, plugin.config, {[fieldName]: value}),
|
||||
})
|
||||
}
|
||||
|
||||
export const createNewPlugin = (name: TelegrafPluginName): Plugin => {
|
||||
return telegrafPluginsInfo[name].defaults
|
||||
}
|
||||
|
|
|
@ -6,17 +6,18 @@ import {executeQuery, ExecuteFluxQueryResult} from 'src/shared/apis/v2/query'
|
|||
import {parseResponse} from 'src/shared/parsing/flux/response'
|
||||
|
||||
// Types
|
||||
import {SourceType, InfluxLanguage} from 'src/types/v2'
|
||||
import {InfluxLanguage} from 'src/types/v2'
|
||||
import {Source} from 'src/api'
|
||||
|
||||
export const SEARCH_DURATION = '30d'
|
||||
export const LIMIT = 200
|
||||
|
||||
export async function findBuckets(
|
||||
url: string,
|
||||
sourceType: SourceType,
|
||||
sourceType: Source.TypeEnum,
|
||||
searchTerm?: string
|
||||
) {
|
||||
if (sourceType === SourceType.V1) {
|
||||
if (sourceType === Source.TypeEnum.V1) {
|
||||
throw new Error('metaqueries not yet implemented for SourceType.V1')
|
||||
}
|
||||
|
||||
|
@ -28,11 +29,11 @@ export async function findBuckets(
|
|||
|
||||
export async function findMeasurements(
|
||||
url: string,
|
||||
sourceType: SourceType,
|
||||
sourceType: Source.TypeEnum,
|
||||
bucket: string,
|
||||
searchTerm: string = ''
|
||||
): Promise<string[]> {
|
||||
if (sourceType === SourceType.V1) {
|
||||
if (sourceType === Source.TypeEnum.V1) {
|
||||
throw new Error('metaqueries not yet implemented for SourceType.V1')
|
||||
}
|
||||
|
||||
|
@ -44,12 +45,12 @@ export async function findMeasurements(
|
|||
|
||||
export async function findFields(
|
||||
url: string,
|
||||
sourceType: SourceType,
|
||||
sourceType: Source.TypeEnum,
|
||||
bucket: string,
|
||||
measurements: string[],
|
||||
searchTerm: string = ''
|
||||
): Promise<string[]> {
|
||||
if (sourceType === SourceType.V1) {
|
||||
if (sourceType === Source.TypeEnum.V1) {
|
||||
throw new Error('metaqueries not yet implemented for SourceType.V1')
|
||||
}
|
||||
|
||||
|
|
|
@ -1,119 +1,12 @@
|
|||
/*
|
||||
Color Dropdown
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
$color-dropdown--circle: 14px;
|
||||
$color-dropdown--bar: 104px;
|
||||
$color-dropdown--bar-height: 10px;
|
||||
$color-dropdown--left-padding: 11px;
|
||||
$color-dropdown--name-padding: 20px;
|
||||
|
||||
.color-dropdown {
|
||||
width: 140px;
|
||||
height: 30px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.color-dropdown.color-dropdown--stretch {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.color-dropdown--toggle {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.color-dropdown--toggle span.caret {
|
||||
font-style: normal !important;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 11px;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.color-dropdown--menu {
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
left: 0;
|
||||
z-index: 5;
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 5px 0.6px fade-out($g0-obsidian, 0.7);
|
||||
@include gradient-h($g0-obsidian, $g2-kevlar);
|
||||
}
|
||||
.color-dropdown--item {
|
||||
@include no-user-select();
|
||||
width: 100%;
|
||||
height: 28px;
|
||||
position: relative;
|
||||
color: $g11-sidewalk;
|
||||
transition: color 0.25s ease, background-color 0.25s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $g4-onyx;
|
||||
color: $g18-cloud;
|
||||
}
|
||||
&:hover,
|
||||
&:hover > * {
|
||||
cursor: pointer !important;
|
||||
}
|
||||
&.active {
|
||||
background-color: $g3-castle;
|
||||
color: $g15-platinum;
|
||||
}
|
||||
&:first-child {
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
&:last-child {
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
}
|
||||
.color-dropdown--swatch,
|
||||
.color-dropdown--swatches,
|
||||
.color-dropdown--name {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.color-dropdown--swatch {
|
||||
width: $color-dropdown--circle;
|
||||
height: $color-dropdown--circle;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
left: $color-dropdown--left-padding;
|
||||
}
|
||||
.color-dropdown--swatches {
|
||||
width: $color-dropdown--bar;
|
||||
height: $color-dropdown--bar-height;
|
||||
border-radius: $color-dropdown--bar-height / 2;
|
||||
left: $color-dropdown--left-padding;
|
||||
}
|
||||
.color-dropdown--name {
|
||||
text-align: left;
|
||||
right: $color-dropdown--name-padding;
|
||||
left: $color-dropdown--circle + $color-dropdown--name-padding;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
text-transform: capitalize;
|
||||
|
||||
.color-dropdown--swatches + & {
|
||||
left: $color-dropdown--bar + $color-dropdown--name-padding;
|
||||
}
|
||||
}
|
||||
.color-dropdown
|
||||
.color-dropdown--menu
|
||||
.fancy-scroll--container
|
||||
.fancy-scroll--track-v
|
||||
.fancy-scroll--thumb-v {
|
||||
@include gradient-v($g9-mountain, $g7-graphite);
|
||||
}
|
||||
.color-dropdown--toggle.color-dropdown__disabled {
|
||||
color: $g7-graphite;
|
||||
font-style: italic;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.color-dropdown--toggle.color-dropdown__disabled > .color-dropdown--swatch {
|
||||
background-color: $g7-graphite !important;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
// Libraries
|
||||
import React, {Component} from 'react'
|
||||
import classnames from 'classnames'
|
||||
import React, {SFC} from 'react'
|
||||
|
||||
// Components
|
||||
import {ClickOutside} from 'src/shared/components/ClickOutside'
|
||||
import FancyScrollbar from 'src/shared/components/fancy_scrollbar/FancyScrollbar'
|
||||
|
||||
// Utils
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
// Constants
|
||||
import {DROPDOWN_MENU_MAX_HEIGHT} from 'src/shared/constants/index'
|
||||
import {Dropdown, ComponentStatus} from 'src/clockface'
|
||||
|
||||
// Types
|
||||
import {ColorLabel} from 'src/types/colors'
|
||||
|
@ -23,110 +15,34 @@ interface Props {
|
|||
onChoose: (colors: ColorLabel) => void
|
||||
}
|
||||
|
||||
interface State {
|
||||
expanded: boolean
|
||||
}
|
||||
const titleCase = (name: string) => `${name[0].toUpperCase()}${name.slice(1)}`
|
||||
|
||||
@ErrorHandling
|
||||
export default class ColorDropdown extends Component<Props, State> {
|
||||
public static defaultProps: Partial<Props> = {
|
||||
stretchToFit: false,
|
||||
disabled: false,
|
||||
}
|
||||
const ColorDropdown: SFC<Props> = props => {
|
||||
const {selected, colors, onChoose, disabled, stretchToFit} = props
|
||||
|
||||
public state: State = {expanded: false}
|
||||
const status = disabled ? ComponentStatus.Disabled : ComponentStatus.Default
|
||||
const widthPixels = stretchToFit ? null : 200
|
||||
|
||||
public render() {
|
||||
const {expanded} = this.state
|
||||
const {selected} = this.props
|
||||
|
||||
return (
|
||||
<ClickOutside onClickOutside={this.handleClickOutside}>
|
||||
<div className={this.dropdownClassNames}>
|
||||
<div
|
||||
className={this.buttonClassNames}
|
||||
onClick={this.handleToggleMenu}
|
||||
>
|
||||
return (
|
||||
<Dropdown
|
||||
selectedID={selected.name}
|
||||
onChange={onChoose}
|
||||
status={status}
|
||||
widthPixels={widthPixels}
|
||||
>
|
||||
{colors.map(color => (
|
||||
<Dropdown.Item id={color.name} key={color.name} value={color}>
|
||||
<div className="color-dropdown--item">
|
||||
<div
|
||||
className="color-dropdown--swatch"
|
||||
style={{backgroundColor: selected.hex}}
|
||||
style={{backgroundColor: color.hex}}
|
||||
/>
|
||||
<div className="color-dropdown--name">{selected.name}</div>
|
||||
<span className="caret" />
|
||||
<div className="color-dropdown--name">{titleCase(color.name)}</div>
|
||||
</div>
|
||||
{expanded && this.renderMenu}
|
||||
</div>
|
||||
</ClickOutside>
|
||||
)
|
||||
}
|
||||
|
||||
private get dropdownClassNames(): string {
|
||||
const {stretchToFit} = this.props
|
||||
const {expanded} = this.state
|
||||
|
||||
return classnames('color-dropdown', {
|
||||
open: expanded,
|
||||
'color-dropdown--stretch': stretchToFit,
|
||||
})
|
||||
}
|
||||
|
||||
private get buttonClassNames(): string {
|
||||
const {disabled} = this.props
|
||||
const {expanded} = this.state
|
||||
|
||||
return classnames('btn btn-sm btn-default color-dropdown--toggle', {
|
||||
active: expanded,
|
||||
'color-dropdown__disabled': disabled,
|
||||
})
|
||||
}
|
||||
|
||||
private get renderMenu(): JSX.Element {
|
||||
const {colors, selected} = this.props
|
||||
|
||||
return (
|
||||
<div className="color-dropdown--menu">
|
||||
<FancyScrollbar
|
||||
autoHide={false}
|
||||
autoHeight={true}
|
||||
maxHeight={DROPDOWN_MENU_MAX_HEIGHT}
|
||||
>
|
||||
{colors.map((color, i) => (
|
||||
<div
|
||||
className={
|
||||
color.name === selected.name
|
||||
? 'color-dropdown--item active'
|
||||
: 'color-dropdown--item'
|
||||
}
|
||||
key={i}
|
||||
onClick={this.handleColorClick(color)}
|
||||
>
|
||||
<span
|
||||
className="color-dropdown--swatch"
|
||||
style={{backgroundColor: color.hex}}
|
||||
/>
|
||||
<span className="color-dropdown--name">{color.name}</span>
|
||||
</div>
|
||||
))}
|
||||
</FancyScrollbar>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private handleToggleMenu = (): void => {
|
||||
const {disabled} = this.props
|
||||
|
||||
if (disabled) {
|
||||
return
|
||||
}
|
||||
this.setState({expanded: !this.state.expanded})
|
||||
}
|
||||
|
||||
private handleClickOutside = (): void => {
|
||||
this.setState({expanded: false})
|
||||
}
|
||||
|
||||
private handleColorClick = color => (): void => {
|
||||
this.props.onChoose(color)
|
||||
this.setState({expanded: false})
|
||||
}
|
||||
</Dropdown.Item>
|
||||
))}
|
||||
</Dropdown>
|
||||
)
|
||||
}
|
||||
|
||||
export default ColorDropdown
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
DEFAULT_VALUE_MIN,
|
||||
MIN_THRESHOLDS,
|
||||
} from 'src/shared/constants/thresholds'
|
||||
import {MAX_TO_LOCALE_STRING_VAL} from 'src/dashboards/constants'
|
||||
import {MAX_DECIMAL_PLACES} from 'src/dashboards/constants'
|
||||
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
|
@ -320,7 +320,7 @@ class Gauge extends Component<Props> {
|
|||
ctx.textBaseline = 'middle'
|
||||
ctx.textAlign = 'center'
|
||||
|
||||
const valueString = this.valueToString(gaugePosition)
|
||||
const valueString = this.labelToString(gaugePosition)
|
||||
|
||||
const textY = radius
|
||||
const textContent = `${prefix}${valueString}${suffix}`
|
||||
|
@ -328,45 +328,15 @@ class Gauge extends Component<Props> {
|
|||
}
|
||||
|
||||
private labelToString(value: number): string {
|
||||
const {decimalPlaces} = this.props
|
||||
const {isEnforced, digits} = this.props.decimalPlaces
|
||||
|
||||
let valueString
|
||||
|
||||
if (decimalPlaces.isEnforced) {
|
||||
const digits = Math.min(decimalPlaces.digits, MAX_TO_LOCALE_STRING_VAL)
|
||||
valueString = value.toLocaleString(undefined, {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: digits,
|
||||
})
|
||||
} else {
|
||||
valueString = value.toLocaleString(undefined, {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: MAX_TO_LOCALE_STRING_VAL,
|
||||
})
|
||||
if (isEnforced && digits) {
|
||||
return value.toFixed(Math.min(digits, MAX_DECIMAL_PLACES))
|
||||
}
|
||||
|
||||
return valueString
|
||||
}
|
||||
|
||||
private valueToString(value: number): string {
|
||||
const {decimalPlaces} = this.props
|
||||
|
||||
let valueString
|
||||
|
||||
if (decimalPlaces.isEnforced) {
|
||||
const digits = Math.min(decimalPlaces.digits, MAX_TO_LOCALE_STRING_VAL)
|
||||
valueString = value.toLocaleString(undefined, {
|
||||
minimumFractionDigits: digits,
|
||||
maximumFractionDigits: digits,
|
||||
})
|
||||
} else {
|
||||
valueString = value.toLocaleString(undefined, {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: MAX_TO_LOCALE_STRING_VAL,
|
||||
})
|
||||
}
|
||||
|
||||
return valueString
|
||||
// Ensure the number has at most MAX_DECIMAL_PLACES digits after the
|
||||
// decimal place
|
||||
return String(Number(value.toFixed(MAX_DECIMAL_PLACES)))
|
||||
}
|
||||
|
||||
private drawNeedle = (ctx, radius, minValue, maxValue) => {
|
||||
|
|
|
@ -71,7 +71,7 @@ describe('GaugeChart', () => {
|
|||
const wrapper = setup({tables})
|
||||
|
||||
expect(wrapper.find(Gauge).exists()).toBe(true)
|
||||
expect(wrapper.find(Gauge).props().gaugePosition).toBe('2')
|
||||
expect(wrapper.find(Gauge).props().gaugePosition).toBe(2)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -44,7 +44,7 @@ class GaugeChart extends PureComponent<Props> {
|
|||
const {values} = getLastValues(tables)
|
||||
const lastValue = _.get(values, 0, 0)
|
||||
|
||||
return lastValue
|
||||
return Number(lastValue)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,11 +18,11 @@ $time-machine--controls-height: 62px;
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
background-color: $g3-castle;
|
||||
}
|
||||
|
||||
.time-machine--top {
|
||||
position: relative;
|
||||
background-color: $g3-castle;
|
||||
}
|
||||
|
||||
.time-machine--bottom {
|
||||
|
|
|
@ -55,7 +55,7 @@ class TimeMachineFluxEditor extends PureComponent<Props> {
|
|||
},
|
||||
{
|
||||
render: () => <FluxFunctionsToolbar />,
|
||||
handlePixels: 10,
|
||||
handlePixels: 6,
|
||||
size: 0.25,
|
||||
},
|
||||
]
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
border-bottom: 4px solid $g3-castle;
|
||||
background: $g2-kevlar;
|
||||
padding: 8px 10px 0 10px;
|
||||
}
|
||||
|
||||
.time-machine-queries--tabs {
|
||||
|
|
|
@ -29,7 +29,8 @@ import 'src/shared/components/TimeMachineQueryBuilder.scss'
|
|||
|
||||
// Types
|
||||
import {RemoteDataState} from 'src/types'
|
||||
import {AppState, Source, SourceType, BuilderConfig} from 'src/types/v2'
|
||||
import {AppState, BuilderConfig} from 'src/types/v2'
|
||||
import {Source} from 'src/api'
|
||||
|
||||
const EMPTY_FIELDS_MESSAGE = 'Select at least one bucket and measurement'
|
||||
const EMPTY_FUNCTIONS_MESSAGE = 'Select at least one bucket and measurement'
|
||||
|
@ -39,7 +40,7 @@ const mergeUnique = (items: string[], selection: string[]) =>
|
|||
|
||||
interface StateProps {
|
||||
queryURL: string
|
||||
sourceType: SourceType
|
||||
sourceType: Source.TypeEnum
|
||||
}
|
||||
|
||||
interface DispatchProps {
|
||||
|
|
|
@ -1,22 +1,41 @@
|
|||
@import "src/style/modules";
|
||||
|
||||
$time-machine-query-tab--lr-padding: 12px;
|
||||
|
||||
.time-machine-query-tab {
|
||||
background: $g2-kevlar;
|
||||
border-radius: 5px 5px 0 0;
|
||||
margin-right: 3px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 15px;
|
||||
padding-right: $time-machine-query-tab--lr-padding;
|
||||
color: $g10-wolf;
|
||||
font-weight: 700;
|
||||
font-size: 13px;
|
||||
cursor: pointer !important;
|
||||
@include no-user-select();
|
||||
|
||||
|
||||
&:not(.active):before {
|
||||
content: "";
|
||||
height: 60%;
|
||||
border-left: 1px solid $g3-castle;
|
||||
padding-right: $time-machine-query-tab--lr-padding;
|
||||
margin-left: -1px;
|
||||
}
|
||||
|
||||
&:first-child:before {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
&:first-child.active {
|
||||
margin-left: -1px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: $g3-castle;
|
||||
color: $g16-pearl;
|
||||
padding-left: $time-machine-query-tab--lr-padding;
|
||||
}
|
||||
|
||||
&:hover:not(.active) {
|
||||
|
@ -27,8 +46,9 @@
|
|||
.time-machine-query-tab--close {
|
||||
margin-left: 30px;
|
||||
margin-bottom: 2px;
|
||||
color: $g7-graphite;
|
||||
|
||||
&:hover {
|
||||
color: $g19-ghost;
|
||||
color: $g16-pearl;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
@import 'src/style/modules';
|
||||
|
||||
.view-options {
|
||||
padding: $ix-marg-d;
|
||||
padding: $ix-marg-c $ix-marg-d;
|
||||
}
|
||||
|
||||
.view-options--header {
|
||||
|
|
|
@ -31,8 +31,8 @@ class DecimalPlacesOption extends PureComponent<Props> {
|
|||
inputPlaceholder="Enter a number"
|
||||
onChange={this.handleSetValue}
|
||||
value={this.value}
|
||||
min={Number(MIN_DECIMAL_PLACES)}
|
||||
max={Number(MAX_DECIMAL_PLACES)}
|
||||
min={MIN_DECIMAL_PLACES}
|
||||
max={MAX_DECIMAL_PLACES}
|
||||
/>
|
||||
</Form.Element>
|
||||
)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Libraries
|
||||
import React, {PureComponent} from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
import {get} from 'lodash'
|
||||
|
||||
// Actions
|
||||
import {setActiveSource} from 'src/sources/actions'
|
||||
|
@ -51,7 +50,6 @@ class SetActiveSource extends PureComponent<Props> {
|
|||
private resolveActiveSource() {
|
||||
const {sources, activeSourceID, onSetActiveSource} = this.props
|
||||
|
||||
const defaultSourceID = get(sources.find(s => s.default), 'id')
|
||||
const querySourceID = readQueryParams().sourceID
|
||||
|
||||
let resolvedSourceID
|
||||
|
@ -60,8 +58,6 @@ class SetActiveSource extends PureComponent<Props> {
|
|||
resolvedSourceID = activeSourceID
|
||||
} else if (sources.find(s => s.id === querySourceID)) {
|
||||
resolvedSourceID = querySourceID
|
||||
} else if (defaultSourceID) {
|
||||
resolvedSourceID = defaultSourceID
|
||||
} else if (sources.length) {
|
||||
resolvedSourceID = sources[0]
|
||||
} else {
|
||||
|
|
|
@ -260,13 +260,31 @@ export const timeMachineReducer = (
|
|||
case 'SET_PREFIX': {
|
||||
const {prefix} = action.payload
|
||||
|
||||
return setYAxis(state, {prefix})
|
||||
switch (state.view.properties.type) {
|
||||
case ViewType.Gauge:
|
||||
case ViewType.SingleStat:
|
||||
return setViewProperties(state, {prefix})
|
||||
case ViewType.XY:
|
||||
case ViewType.LinePlusSingleStat:
|
||||
return setYAxis(state, {prefix})
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
case 'SET_SUFFIX': {
|
||||
const {suffix} = action.payload
|
||||
|
||||
return setYAxis(state, {suffix})
|
||||
switch (state.view.properties.type) {
|
||||
case ViewType.Gauge:
|
||||
case ViewType.SingleStat:
|
||||
return setViewProperties(state, {suffix})
|
||||
case ViewType.XY:
|
||||
case ViewType.LinePlusSingleStat:
|
||||
return setYAxis(state, {suffix})
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
case 'SET_COLORS': {
|
||||
|
|
|
@ -10,7 +10,8 @@ import {
|
|||
} from 'src/sources/apis'
|
||||
|
||||
// Types
|
||||
import {Source, GetState} from 'src/types/v2'
|
||||
import {GetState} from 'src/types/v2'
|
||||
import {Source} from 'src/api'
|
||||
|
||||
export type Action =
|
||||
| SetActiveSourceAction
|
||||
|
@ -68,12 +69,8 @@ export const removeSource = (sourceID: string): RemoveSourceAction => ({
|
|||
payload: {sourceID},
|
||||
})
|
||||
|
||||
export const readSources = () => async (
|
||||
dispatch: Dispatch<Action>,
|
||||
getState: GetState
|
||||
) => {
|
||||
const sourcesLink = getState().links.sources
|
||||
const sources = await readSourcesAJAX(sourcesLink)
|
||||
export const readSources = () => async (dispatch: Dispatch<Action>) => {
|
||||
const sources = await readSourcesAJAX()
|
||||
|
||||
dispatch(setSources(sources))
|
||||
}
|
||||
|
@ -91,7 +88,7 @@ export const createSource = (attrs: Partial<Source>) => async (
|
|||
export const updateSource = (source: Source) => async (
|
||||
dispatch: Dispatch<Action>
|
||||
) => {
|
||||
const updatedSource = await updateSourceAJAX(source)
|
||||
const updatedSource = await updateSourceAJAX(source.id, source)
|
||||
|
||||
dispatch(setSource(updatedSource))
|
||||
}
|
||||
|
|
|
@ -1,57 +1,40 @@
|
|||
import AJAX from 'src/utils/ajax'
|
||||
import {Source} from 'src/types/v2'
|
||||
import {Source} from 'src/api'
|
||||
import {sourcesAPI} from 'src/utils/api'
|
||||
|
||||
export const readSources = async (url): Promise<Source[]> => {
|
||||
const {data} = await AJAX({url})
|
||||
export const readSources = async (): Promise<Source[]> => {
|
||||
const {data} = await sourcesAPI.sourcesGet('')
|
||||
|
||||
return data.sources
|
||||
}
|
||||
|
||||
export const readSource = async (url: string): Promise<Source> => {
|
||||
const {data: source} = await AJAX({
|
||||
url,
|
||||
})
|
||||
export const readSource = async (id: string): Promise<Source> => {
|
||||
const {data} = await sourcesAPI.sourcesSourceIDGet(id)
|
||||
|
||||
return source
|
||||
return data
|
||||
}
|
||||
|
||||
export const createSource = async (
|
||||
url: string,
|
||||
org: string,
|
||||
attributes: Partial<Source>
|
||||
): Promise<Source> => {
|
||||
const {data: source} = await AJAX({
|
||||
url,
|
||||
method: 'POST',
|
||||
data: attributes,
|
||||
})
|
||||
const {data} = await sourcesAPI.sourcesPost(org, attributes)
|
||||
|
||||
return source
|
||||
return data
|
||||
}
|
||||
|
||||
export const updateSource = async (
|
||||
newSource: Partial<Source>
|
||||
id: string,
|
||||
source: Partial<Source>
|
||||
): Promise<Source> => {
|
||||
const {data: source} = await AJAX({
|
||||
url: newSource.links.self,
|
||||
method: 'PATCH',
|
||||
data: newSource,
|
||||
})
|
||||
const {data} = await sourcesAPI.sourcesSourceIDPatch(id, source)
|
||||
|
||||
return source
|
||||
return data
|
||||
}
|
||||
|
||||
export function deleteSource(source) {
|
||||
return AJAX({
|
||||
url: source.links.self,
|
||||
method: 'DELETE',
|
||||
})
|
||||
export async function deleteSource(source: Source): Promise<void> {
|
||||
await sourcesAPI.sourcesSourceIDDelete(source.id)
|
||||
}
|
||||
|
||||
export const getSourceHealth = async (url: string): Promise<void> => {
|
||||
try {
|
||||
await AJAX({url})
|
||||
} catch (error) {
|
||||
console.error(`Unable to contact source ${url}`, error)
|
||||
throw error
|
||||
}
|
||||
export const getSourceHealth = async (id: string): Promise<void> => {
|
||||
await sourcesAPI.sourcesSourceIDHealthGet(id)
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import {sourceCreationFailed} from 'src/shared/copy/notifications'
|
|||
import 'src/sources/components/CreateSourceOverlay.scss'
|
||||
|
||||
// Types
|
||||
import {Source, SourceType} from 'src/types/v2'
|
||||
import {Source} from 'src/api'
|
||||
import {RemoteDataState} from 'src/types'
|
||||
|
||||
interface DispatchProps {
|
||||
|
@ -49,7 +49,7 @@ class CreateSourceOverlay extends PureComponent<Props, State> {
|
|||
public state: State = {
|
||||
draftSource: {
|
||||
name: '',
|
||||
type: SourceType.V1,
|
||||
type: Source.TypeEnum.V1,
|
||||
url: '',
|
||||
},
|
||||
creationStatus: RemoteDataState.NotStarted,
|
||||
|
@ -94,16 +94,16 @@ class CreateSourceOverlay extends PureComponent<Props, State> {
|
|||
<Form.Element label="Type">
|
||||
<Radio>
|
||||
<Radio.Button
|
||||
active={draftSource.type === SourceType.V1}
|
||||
active={draftSource.type === Source.TypeEnum.V1}
|
||||
onClick={this.handleChangeType}
|
||||
value={SourceType.V1}
|
||||
value={Source.TypeEnum.V1}
|
||||
>
|
||||
v1
|
||||
</Radio.Button>
|
||||
<Radio.Button
|
||||
active={draftSource.type === SourceType.V2}
|
||||
active={draftSource.type === Source.TypeEnum.V2}
|
||||
onClick={this.handleChangeType}
|
||||
value={SourceType.V2}
|
||||
value={Source.TypeEnum.V2}
|
||||
>
|
||||
v2
|
||||
</Radio.Button>
|
||||
|
@ -144,7 +144,7 @@ class CreateSourceOverlay extends PureComponent<Props, State> {
|
|||
this.setState({draftSource})
|
||||
}
|
||||
|
||||
private handleChangeType = (type: SourceType) => {
|
||||
private handleChangeType = (type: Source.TypeEnum) => {
|
||||
const draftSource = {
|
||||
...this.state.draftSource,
|
||||
type,
|
||||
|
|
|
@ -20,7 +20,7 @@ import 'src/sources/components/SourcesListRow.scss'
|
|||
|
||||
// Types
|
||||
import {AppState} from 'src/types/v2'
|
||||
import {Source, SourceType} from 'src/types/v2'
|
||||
import {Source} from 'src/api'
|
||||
|
||||
interface StateProps {
|
||||
activeSourceID: string
|
||||
|
@ -43,7 +43,7 @@ const SourcesListRow: SFC<Props> = ({
|
|||
onSetActiveSource,
|
||||
onDeleteSource,
|
||||
}) => {
|
||||
const canDelete = source.type !== SourceType.Self
|
||||
const canDelete = source.type !== Source.TypeEnum.Self
|
||||
const isActiveSource = source.id === activeSourceID
|
||||
const onButtonClick = () => onSetActiveSource(source.id)
|
||||
const onDeleteClick = () => onDeleteSource(source.id)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import {Index} from 'react-virtualized'
|
||||
|
||||
import {Bucket, Source} from 'src/types/v2'
|
||||
import {Bucket} from 'src/types/v2'
|
||||
import {QueryConfig} from 'src/types'
|
||||
import {Source} from 'src/api'
|
||||
|
||||
import {FieldOption, TimeSeriesValue} from 'src/types/v2/dashboards'
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Source, SourceType} from 'src/types/v2/sources'
|
||||
import {SourceType} from 'src/types/v2/sources'
|
||||
import {Bucket, RetentionRule, RetentionRuleTypes} from 'src/types/v2/buckets'
|
||||
import {RangeState} from 'src/dashboards/reducers/v2/ranges'
|
||||
import {ViewsState} from 'src/dashboards/reducers/v2/views'
|
||||
|
@ -17,7 +17,7 @@ import {
|
|||
InfluxLanguage,
|
||||
} from 'src/types/v2/dashboards'
|
||||
|
||||
import {Cell, Dashboard} from 'src/api'
|
||||
import {Cell, Dashboard, Source} from 'src/api'
|
||||
import {Task} from 'src/types/v2/tasks'
|
||||
import {Member} from 'src/types/v2/members'
|
||||
import {Organization} from 'src/types/v2/orgs'
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
AuthorizationsApi,
|
||||
ViewsApi,
|
||||
WriteApi,
|
||||
SourcesApi,
|
||||
} from 'src/api'
|
||||
|
||||
const basePath = '/api/v2'
|
||||
|
@ -19,3 +20,4 @@ export const cellsAPI = new CellsApi({basePath})
|
|||
export const telegrafsAPI = new TelegrafsApi({basePath})
|
||||
export const authorizationsAPI = new AuthorizationsApi({basePath})
|
||||
export const writeAPI = new WriteApi({basePath})
|
||||
export const sourcesAPI = new SourcesApi({basePath})
|
||||
|
|
10
user.go
10
user.go
|
@ -8,6 +8,16 @@ type User struct {
|
|||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// Ops for user errors and op log.
|
||||
const (
|
||||
OpFindUserByID = "FindUserByID"
|
||||
OpFindUser = "FindUser"
|
||||
OpFindUsers = "FindUsers"
|
||||
OpCreateUser = "CreateUser"
|
||||
OpUpdateUser = "UpdateUser"
|
||||
OpDeleteUser = "DeleteUser"
|
||||
)
|
||||
|
||||
// UserService represents a service for managing user data.
|
||||
type UserService interface {
|
||||
|
||||
|
|
Loading…
Reference in New Issue