Skip to content

Commit

Permalink
feat: [PC-13433]: add get Adjustment Events (#228)
Browse files Browse the repository at this point in the history
## Motivation

This change is a part of new Error Budget Adjustments management
feature. We need to have a way to get/update/delete Events related to an
Adjustments.

## Summary

Add new command to `sloctl` to 

- get Adjustment Events for adjustment and optional SLO filter
- delete Adjustment Events for adjustment
- update Adjustment Events for adjustment


## Testing

See added examples of usage

## Release Notes

New Past Adjustment functionality. Allow users to manage past events.

---------

Co-authored-by: dawidwisn <[email protected]>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Mateusz Hawrus <[email protected]>
  • Loading branch information
4 people authored Dec 11, 2024
1 parent 2af304a commit 6e938bd
Show file tree
Hide file tree
Showing 28 changed files with 727 additions and 73 deletions.
16 changes: 8 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/go-playground/validator/v10 v10.23.0
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db
github.com/nobl9/go-yaml v1.0.1
github.com/nobl9/nobl9-go v0.87.1-0.20241003100141-13a5a306624d
github.com/nobl9/nobl9-go v0.92.1
github.com/pkg/errors v0.9.1
github.com/schollz/progressbar/v3 v3.17.1
github.com/spf13/cobra v1.8.1
Expand All @@ -19,9 +19,9 @@ require (
github.com/MicahParks/jwkset v0.5.20 // indirect
github.com/MicahParks/keyfunc/v3 v3.3.5 // indirect
github.com/aws/aws-sdk-go v1.55.5 // indirect
github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fatih/color v1.17.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
Expand All @@ -33,19 +33,19 @@ require (
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/nobl9/govy v0.3.0 // indirect
github.com/nobl9/govy v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/teambition/rrule-go v1.8.2 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/term v0.26.0 // indirect
golang.org/x/text v0.18.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/time v0.7.0 // indirect
golang.org/x/tools v0.24.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
Expand Down
32 changes: 16 additions & 16 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ github.com/MicahParks/keyfunc/v3 v3.3.5 h1:7ceAJLUAldnoueHDNzF8Bx06oVcQ5CfJnYwNt
github.com/MicahParks/keyfunc/v3 v3.3.5/go.mod h1:SdCCyMJn/bYqWDvARspC6nCT8Sk74MjuAY22C7dCST8=
github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I=
github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM=
github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
Expand Down Expand Up @@ -55,10 +55,10 @@ github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2Em
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/nobl9/go-yaml v1.0.1 h1:Aj1kSaYdRQTKlvS6ihvXzQJhCpoHhtf9nfA95zqWH4Q=
github.com/nobl9/go-yaml v1.0.1/go.mod h1:t7vCO8ctYdBweZxU5lUgxzAw31+ZcqJYeqRtrv+5RHI=
github.com/nobl9/govy v0.3.0 h1:OokgZ9PHfFNt2TkX8h/9rF0Y3doj/nnr0BlPo1BsasY=
github.com/nobl9/govy v0.3.0/go.mod h1:O+xSiKwZ6gs/orRvH5qLkfkgyT7CkuXprRIq3C5uNXQ=
github.com/nobl9/nobl9-go v0.87.1-0.20241003100141-13a5a306624d h1:jDCIdJPMEOW3cSDHajeX9mxAm/kuBxeI6ifC9xRU1ck=
github.com/nobl9/nobl9-go v0.87.1-0.20241003100141-13a5a306624d/go.mod h1:jICYB6/RFcKs/Mqm3ltGbsD2Ign64/uy8JMaHxpYQ5o=
github.com/nobl9/govy v0.9.1 h1:ht+mgbDB40QEZEmHpzG2xqey+PbfzCwgj3+vdJuHAVQ=
github.com/nobl9/govy v0.9.1/go.mod h1:O+xSiKwZ6gs/orRvH5qLkfkgyT7CkuXprRIq3C5uNXQ=
github.com/nobl9/nobl9-go v0.92.1 h1:NASqZVOjyUiSSWgAgbyUJArXZQOs7AQmmpUtfFLgTXw=
github.com/nobl9/nobl9-go v0.92.1/go.mod h1:SWvmmfSGCairnWDCdRLusRB0zROxF+7XiA9aho2f7rA=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand All @@ -78,14 +78,14 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/teambition/rrule-go v1.8.2 h1:lIjpjvWTj9fFUZCmuoVDrKVOtdiyzbzc93qTmRVe/J8=
github.com/teambition/rrule-go v1.8.2/go.mod h1:Ieq5AbrKGciP1V//Wq8ktsTXwSwJHDD5mD/wLBGl3p4=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand All @@ -94,10 +94,10 @@ golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
Expand Down
2 changes: 1 addition & 1 deletion internal/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.8.0
0.9.0
4 changes: 3 additions & 1 deletion internal/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"github.com/nobl9/nobl9-go/manifest"
"github.com/nobl9/nobl9-go/manifest/v1alpha"
"github.com/nobl9/nobl9-go/sdk"

"github.com/nobl9/sloctl/internal/flags"
)

type ApplyCmd struct {
Expand All @@ -18,7 +20,7 @@ type ApplyCmd struct {
dryRun bool
autoConfirm bool
replay bool
replayFrom TimeValue
replayFrom flags.TimeValue
project string
}

Expand Down
7 changes: 6 additions & 1 deletion internal/aws_iam_ids.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ func (r *RootCmd) NewAwsIamIds() *cobra.Command {
PersistentPreRun: func(iamIdsCmd *cobra.Command, args []string) { awsIamIds.client = r.GetClient() },
RunE: func(iamIdsCmd *cobra.Command, args []string) error { return awsIamIds.Direct(iamIdsCmd) },
}
registerOutputFormatFlags(direct, &awsIamIds.outputFormat, &awsIamIds.fieldSeparator, &awsIamIds.recordSeparator)
printer.MustRegisterOutputFormatFlags(
direct,
&awsIamIds.outputFormat,
&awsIamIds.fieldSeparator,
&awsIamIds.recordSeparator,
)
cobraCmd.AddCommand(direct)

dataExport := &cobra.Command{
Expand Down
67 changes: 67 additions & 0 deletions internal/budgetadjustments/events/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package events

import (
"bytes"
_ "embed"
"fmt"
"net/http"

"github.com/nobl9/go-yaml"
"github.com/nobl9/nobl9-go/sdk"
"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/nobl9/sloctl/internal/budgetadjustments/sdkclient"
)

type DeleteCmd struct {
client *sdk.Client
filepath string
adjustment string
}

//go:embed examples/delete_example.sh
var deleteExample string

func NewDeleteCmd(clientProvider sdkclient.SdkClientProvider) *cobra.Command {
deleteCmd := &DeleteCmd{}

cmd := &cobra.Command{
Use: "delete",
Short: "Delete existing past events.",
Example: deleteExample,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
deleteCmd.client = clientProvider.GetClient()
},
RunE: func(cmd *cobra.Command, args []string) error { return deleteCmd.run(cmd) },
}

mustRegisterFileFlag(cmd, &deleteCmd.filepath)
mustRegisterAdjustmentFlag(cmd, &deleteCmd.adjustment)

return cmd
}

func (g *DeleteCmd) run(cmd *cobra.Command) error {
data, err := readFile(g.filepath)
if err != nil {
return errors.Wrap(err, "failed to read input data")
}
body, err := yaml.YAMLToJSON(data)
if err != nil {
return errors.Wrap(err, "failed to convert input data to JSON")
}

if _, err = DoRequest(
g.client,
cmd.Context(),
http.MethodPost,
fmt.Sprintf("%s/%s/events/delete", BudgetAdjustmentAPI, g.adjustment),
nil,
bytes.NewReader(body),
); err != nil {
return err
}

return nil
}
23 changes: 23 additions & 0 deletions internal/budgetadjustments/events/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package events

import (
"fmt"

"github.com/spf13/cobra"

"github.com/nobl9/sloctl/internal/budgetadjustments/sdkclient"
)

func NewRootCmd(clientProvider sdkclient.SdkClientProvider) *cobra.Command {
cmd := &cobra.Command{
Use: "events",
Short: "Budget adjustments events management",
Long: "The 'events' command allows you to manage events related to SLO error budget adjustments",
}
cmd.PersistentFlags().BoolP("help", "h", false, fmt.Sprintf("Help for %s.", cmd.Name()))
cmd.AddCommand(NewGetCmd(clientProvider))
cmd.AddCommand(NewDeleteCmd(clientProvider))
cmd.AddCommand(NewUpdateCmd(clientProvider))

return cmd
}
17 changes: 17 additions & 0 deletions internal/budgetadjustments/events/examples/delete_example.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Delete Adjustment Events using a file:
cat <<EOF > ./events.yaml
- eventStart: 2024-10-24T04:07:04Z
eventEnd: 2024-10-24T05:27:04Z
slos:
- project: test-project
name: sample-slo-1
- eventStart: 2024-10-25T04:07:04Z
eventEnd: 2024-10-25T05:27:04Z
slos:
- project: test-project
name: sample-slo-2
EOF
sloctl budgetadjustments events delete --adjustment-name=sample-adjustment-name -f ./events.yaml

# Delete Adjustment Events using stdin:
sloctl budgetadjustments events delete --adjustment-name=sample-adjustment-name -f - <./events.yaml
12 changes: 12 additions & 0 deletions internal/budgetadjustments/events/examples/get_example.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Get Adjustment Events for 'sample-adjustment-name' from 2024-09-23T00:45:00 UTC to 2024-09-23T20:46:00 UTC.
sloctl budgetadjustments events get --adjustment-name=sample-adjustment-name --from=2024-09-23T00:45:00Z --to=2024-09-23T20:46:00Z


# Get Adjustment Events for 'sample-adjustment-name' from 2024-09-23T00:45:00 UTC to 2024-09-23T20:46:00 UTC
# only for one slo with sloName and project filters.
sloctl budgetadjustments events get \
--adjustment-name=sample-adjustment-name \
--from=2024-09-23T00:45:00Z \
--to=2024-09-23T20:46:00Z \
--slo-project=sample-project-name \
--slo-name=sample-slo-name
23 changes: 23 additions & 0 deletions internal/budgetadjustments/events/examples/update_example.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Update Adjustment Events using a file:
cat <<EOF > ./events.yaml
- eventStart: 2024-10-24T04:07:04Z
eventEnd: 2024-10-24T05:27:04Z
slos:
- project: test-project
name: sample-slo-1
update:
eventStart: 2024-10-24T03:07:04Z
eventEnd: 2024-10-24T04:27:04Z
- eventStart: 2024-10-25T04:07:04Z
eventEnd: 2024-10-25T05:27:04Z
slos:
- project: test-project
name: sample-slo-2
update:
eventStart: 2024-10-25T03:07:04Z
eventEnd: 2024-10-25T04:27:04Z
EOF
sloctl budgetadjustments events update --adjustment-name=sample-adjustment-name -f ./events.yaml

# Update Adjustment Events using stdin:
sloctl budgetadjustments events update --adjustment-name=sample-adjustment-name -f - <./events.yaml
62 changes: 62 additions & 0 deletions internal/budgetadjustments/events/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package events

import (
"github.com/spf13/cobra"

"github.com/nobl9/sloctl/internal/flags"
)

const (
FlagFile = "file"
FlagAdjustment = "adjustment-name"
FlagFrom = "from"
FlagTo = "to"
FlagSloProject = "slo-project"
FlagSloName = "slo-name"
)

func mustRegisterFileFlag(cmd *cobra.Command, storeIn *string) {
cmd.Flags().StringVarP(storeIn, FlagFile, "f", "",
"File path to events definitions in YAML.")
if err := cmd.MarkFlagRequired(FlagFile); err != nil {
panic(err)
}
}

func mustRegisterAdjustmentFlag(cmd *cobra.Command, storeIn *string) {
cmd.Flags().StringVar(storeIn, FlagAdjustment, "", "Name of the Adjustment.")
if err := cmd.MarkFlagRequired(FlagAdjustment); err != nil {
panic(err)
}
}

func registerProjectFlag(cmd *cobra.Command, storeIn *string) {
cmd.Flags().StringVarP(storeIn, FlagSloProject, "", "",
"Name of the project. Required when sloName is defined.")
}

func registerSloNameFlag(cmd *cobra.Command, storeIn *string) {
cmd.Flags().StringVarP(storeIn, FlagSloName, "", "",
"Name of the SLO. Required when sloName is defined.")
}

func mustRegisterFromFlag(
cmd *cobra.Command,
storeIn *flags.TimeValue,
) {
cmd.Flags().
Var(storeIn, FlagFrom, "Specifies the start date and time for the data range (in UTC).")
if err := cmd.MarkFlagRequired(FlagFrom); err != nil {
panic(err)
}
}

func mustRegisterToFlag(
cmd *cobra.Command,
storeIn *flags.TimeValue,
) {
cmd.Flags().Var(storeIn, FlagTo, "Specifies the end date and time for the data range (in UTC).")
if err := cmd.MarkFlagRequired(FlagTo); err != nil {
panic(err)
}
}
Loading

0 comments on commit 6e938bd

Please sign in to comment.