Skip to content

Commit

Permalink
feat: Add bucket schema management commands
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartcarnie committed Apr 30, 2021
1 parent 571b1de commit 178c072
Show file tree
Hide file tree
Showing 30 changed files with 2,720 additions and 1 deletion.
6 changes: 6 additions & 0 deletions cmd/influx/bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ func newBucketCreateCmd() *cli.Command {
EnvVars: []string{"INFLUX_ORG"},
Destination: &params.OrgName,
},
&cli.StringFlag{
Name: "schema-type",
Usage: "The schema type (implicit, explicit)",
DefaultText: "implicit",
Destination: &params.SchemaType,
},
),
Action: func(ctx *cli.Context) error {
clients := getBucketsClient(ctx)
Expand Down
1 change: 1 addition & 0 deletions cmd/influx/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ var app = cli.App{
newSetupCmd(),
newWriteCmd(),
newBucketCmd(),
newMeasurementSchemaCmd(),
},
}

Expand Down
247 changes: 247 additions & 0 deletions cmd/influx/measurement_schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
package main

import (
"bytes"
"fmt"
"io"
"os"

"github.com/influxdata/influx-cli/v2/internal"
"github.com/influxdata/influx-cli/v2/internal/cmd/measurement_schema"
"github.com/influxdata/influx-cli/v2/internal/schema"
"github.com/influxdata/influx-cli/v2/pkg/cli/middleware"
"github.com/influxdata/influx-cli/v2/pkg/influxid"
"github.com/urfave/cli/v2"
)

func withMSClient() cli.BeforeFunc {
return middleware.WithBeforeFns(
withCli(),
withApi(),
func(ctx *cli.Context) error {
c := getCLI(ctx)
client := getAPI(ctx)
ctx.App.Metadata["measurement_schema"] = measurement_schema.Client{
BucketApi: client.BucketsApi,
BucketSchemasApi: client.BucketSchemasApi,
CLI: c,
}
return nil
})
}

func getMSClient(ctx *cli.Context) measurement_schema.Client {
i, ok := ctx.App.Metadata["measurement_schema"].(measurement_schema.Client)
if !ok {
panic("missing measurement schema client")
}
return i
}

func newMeasurementSchemaCmd() *cli.Command {
return &cli.Command{
Name: "bucket-schema",
Usage: "Bucket schema management commands",
Subcommands: []*cli.Command{
newMeasurementSchemaCreateCmd(),
newMeasurementSchemaUpdateCmd(),
newMeasurementSchemaListCmd(),
},
}
}

func newMeasurementSchemaCreateCmd() *cli.Command {
var params struct {
internal.OrgBucketParams
Name string
ColumnsFile string
ColumnsFormat schema.Format
ExtendedOutput bool
}
return &cli.Command{
Name: "create",
Usage: "Create a measurement schema for a bucket",
Before: withMSClient(),
Flags: append(
commonFlags,
append(
getOrgBucketFlags(&params.OrgBucketParams),
&cli.StringFlag{
Name: "name",
Usage: "Name of the measurement",
Destination: &params.Name,
},
&cli.StringFlag{
Name: "columns-file",
Usage: "A path referring to list of column definitions",
Destination: &params.ColumnsFile,
},
&cli.GenericFlag{
Name: "columns-format",
Usage: "The format of the columns file. \"auto\" will attempt to guess the format.",
DefaultText: "auto",
Value: &params.ColumnsFormat,
},
&cli.BoolFlag{
Name: "extended-output",
Usage: "Print column information for each measurement",
Aliases: []string{"x"},
Destination: &params.ExtendedOutput,
},
)...,
),
Action: func(ctx *cli.Context) error {
var (
r io.Reader
name string
)

arg := ctx.Args().First()
if arg == "-" || params.ColumnsFile == "" {
// stdio
r = ctx.App.Reader
name = "stdio"
} else {
data, err := os.ReadFile(params.ColumnsFile)
if err != nil {
return fmt.Errorf("unable to read file %q: %w", params.ColumnsFile, err)
}
r = bytes.NewReader(data)
name = params.ColumnsFile
}

reader, err := params.ColumnsFormat.FormatFn(name)
if err != nil {
return err
}

cols, err := reader(r)
if err != nil {
return fmt.Errorf("unable to decode file %q: %w", name, err)
}

return getMSClient(ctx).Create(ctx.Context, measurement_schema.CreateParams{
OrgBucketParams: params.OrgBucketParams,
Name: params.Name,
Columns: cols,
ExtendedOutput: params.ExtendedOutput,
})
},
}
}

func newMeasurementSchemaUpdateCmd() *cli.Command {
var params struct {
internal.OrgBucketParams
ID influxid.ID
Name string
ColumnsFile string
ColumnsFormat schema.Format
ExtendedOutput bool
}
return &cli.Command{
Name: "update",
Usage: "Update a measurement schema for a bucket",
Before: withMSClient(),
Flags: append(
commonFlags,
append(
getOrgBucketFlags(&params.OrgBucketParams),
&cli.GenericFlag{
Name: "id",
Usage: "ID of the measurement",
Value: &params.ID,
},
&cli.StringFlag{
Name: "name",
Usage: "Name of the measurement",
Destination: &params.Name,
},
&cli.StringFlag{
Name: "columns-file",
Usage: "A path referring to list of column definitions",
Destination: &params.ColumnsFile,
},
&cli.GenericFlag{
Name: "columns-format",
Usage: "The format of the columns file. \"auto\" will attempt to guess the format.",
DefaultText: "auto",
Value: &params.ColumnsFormat,
},
&cli.BoolFlag{
Name: "extended-output",
Usage: "Print column information for each measurement",
Aliases: []string{"x"},
Destination: &params.ExtendedOutput,
},
)...,
),
Action: func(ctx *cli.Context) error {
var (
r io.Reader
name string
)

arg := ctx.Args().First()
if arg == "-" || params.ColumnsFile == "" {
// stdio
r = ctx.App.Reader
name = "stdio"
} else {
data, err := os.ReadFile(params.ColumnsFile)
if err != nil {
return fmt.Errorf("unable to read file %q: %w", params.ColumnsFile, err)
}
r = bytes.NewReader(data)
name = params.ColumnsFile
}

reader, err := params.ColumnsFormat.FormatFn(name)
if err != nil {
return err
}

cols, err := reader(r)
if err != nil {
return fmt.Errorf("unable to decode file %q: %w", name, err)
}

return getMSClient(ctx).Update(ctx.Context, measurement_schema.UpdateParams{
OrgBucketParams: params.OrgBucketParams,
ID: params.ID.String(),
Name: params.Name,
Columns: cols,
ExtendedOutput: params.ExtendedOutput,
})
},
}
}

func newMeasurementSchemaListCmd() *cli.Command {
var params measurement_schema.ListParams
return &cli.Command{
Name: "list",
Usage: "List schemas for a bucket",
Before: withMSClient(),
Flags: append(
commonFlags,
append(
getOrgBucketFlags(&params.OrgBucketParams),
&cli.StringFlag{
Name: "name",
Usage: "Name of single measurement to find",
Destination: &params.Name,
},
&cli.BoolFlag{
Name: "extended-output",
Usage: "Print column information for each measurement",
Aliases: []string{"x"},
Destination: &params.ExtendedOutput,
},
)...,
),
Action: func(ctx *cli.Context) error {
return getMSClient(ctx).List(ctx.Context, params)
},
}
}
36 changes: 36 additions & 0 deletions cmd/influx/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package main

import (
"github.com/influxdata/influx-cli/v2/internal"
"github.com/urfave/cli/v2"
)

func getOrgBucketFlags(c *internal.OrgBucketParams) []cli.Flag {
return []cli.Flag{
&cli.GenericFlag{
Name: "bucket-id",
Usage: "The bucket ID, required if name isn't provided",
Aliases: []string{"i"},
Value: &c.BucketID,
},
&cli.StringFlag{
Name: "bucket",
Usage: "The bucket name, org or org-id will be required by choosing this",
Aliases: []string{"n"},
Destination: &c.BucketName,
},
&cli.GenericFlag{
Name: "org-id",
Usage: "The ID of the organization",
EnvVars: []string{"INFLUX_ORG_ID"},
Value: &c.OrgID,
},
&cli.StringFlag{
Name: "org",
Usage: "The name of the organization",
Aliases: []string{"o"},
EnvVars: []string{"INFLUX_ORG"},
Destination: &c.OrgName,
},
}
}
4 changes: 4 additions & 0 deletions columns.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name,type,data_type
time,timestamp,
host,tag,
usage_user,field,float
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ go 1.16
require (
github.com/AlecAivazis/survey/v2 v2.2.9
github.com/BurntSushi/toml v0.3.1
github.com/MakeNowJust/heredoc/v2 v2.0.1
github.com/daixiang0/gci v0.2.8
github.com/fujiwara/shapeio v1.0.0
github.com/gocarina/gocsv v0.0.0-20210408192840-02d7211d929d
github.com/kr/pretty v0.1.0 // indirect
github.com/stretchr/testify v1.7.0
github.com/urfave/cli/v2 v2.3.0
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ github.com/AlecAivazis/survey/v2 v2.2.9 h1:LWvJtUswz/W9/zVVXELrmlvdwWcKE60ZAw0FW
github.com/AlecAivazis/survey/v2 v2.2.9/go.mod h1:9DYvHgXtiXm6nCn+jXnOXLKbH+Yo9u8fAS/SduGdoPk=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/MakeNowJust/heredoc/v2 v2.0.1 h1:rlCHh70XXXv7toz95ajQWOWQnN4WNLt0TdpZYIR/J6A=
github.com/MakeNowJust/heredoc/v2 v2.0.1/go.mod h1:6/2Abh5s+hc3g9nbWLe9ObDIOhaRrqsyY9MWy+4JdRM=
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
Expand All @@ -15,6 +17,8 @@ github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/fujiwara/shapeio v1.0.0 h1:xG5D9oNqCSUUbryZ/jQV3cqe1v2suEjwPIcEg1gKM8M=
github.com/fujiwara/shapeio v1.0.0/go.mod h1:LmEmu6L/8jetyj1oewewFb7bZCNRwE7wLCUNzDLaLVA=
github.com/gocarina/gocsv v0.0.0-20210408192840-02d7211d929d h1:r3mStZSyjKhEcgbJ5xtv7kT5PZw/tDiFBTMgQx2qsXE=
github.com/gocarina/gocsv v0.0.0-20210408192840-02d7211d929d/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
Expand Down
Loading

0 comments on commit 178c072

Please sign in to comment.