Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(influx): extend stacks update cmd with ability to add resources #18758

Merged
merged 1 commit into from
Jun 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
## v2.0.0-beta.14 [unreleased]

### Features

1. [18758](https://github.com/influxdata/influxdb/pull/18758): Extend influx stacks update cmd with ability to add resources without apply template

### Bug Fixes

## v2.0.0-beta.13 [2020-06-25]
Expand Down
143 changes: 106 additions & 37 deletions cmd/influx/pkg.go → cmd/influx/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ type cmdPkgBuilder struct {
telegrafs string
variables string
}

updateStackOpts struct {
addResources []string
}
}

func newCmdPkgBuilder(svcFn pkgSVCsFn, f *globalFlags, opts genericCLIOpts) *cmdPkgBuilder {
Expand Down Expand Up @@ -410,17 +414,10 @@ func (b *cmdPkgBuilder) exportRunEFn(cmd *cobra.Command, args []string) error {
}

if b.exportOpts.resourceType == "" {
return b.exportPkg(cmd.OutOrStdout(), pkgSVC, b.file, opts...)
return b.exportTemplate(cmd.OutOrStdout(), pkgSVC, b.file, opts...)
}

resType := strings.ToLower(b.exportOpts.resourceType)
resKind := pkger.KindUnknown
for _, k := range pkger.Kinds() {
if strings.ToLower(string(k)) == resType {
resKind = k
break
}
}
resKind := templateKindFold(b.exportOpts.resourceType)

if err := resKind.OK(); err != nil {
return errors.New("resource type is invalid; got: " + b.exportOpts.resourceType)
Expand All @@ -439,7 +436,7 @@ func (b *cmdPkgBuilder) exportRunEFn(cmd *cobra.Command, args []string) error {
}
opts = append(opts, resTypeOpt)

return b.exportPkg(cmd.OutOrStdout(), pkgSVC, b.file, opts...)
return b.exportTemplate(cmd.OutOrStdout(), pkgSVC, b.file, opts...)
}

func (b *cmdPkgBuilder) cmdExportAll() *cobra.Command {
Expand Down Expand Up @@ -526,7 +523,7 @@ func (b *cmdPkgBuilder) exportAllRunEFn(cmd *cobra.Command, args []string) error
LabelNames: labelNames,
ResourceKinds: resourceKinds,
})
return b.exportPkg(cmd.OutOrStdout(), pkgSVC, b.file, orgOpt)
return b.exportTemplate(cmd.OutOrStdout(), pkgSVC, b.file, orgOpt)
}

func (b *cmdPkgBuilder) cmdExportStack() *cobra.Command {
Expand Down Expand Up @@ -680,10 +677,10 @@ func (b *cmdPkgBuilder) cmdStackInit() *cobra.Command {

Examples:
# Initialize a stack with a name and description
influx stack init -n $STACK_NAME -d $STACK_DESCRIPTION
influx stacks init -n $STACK_NAME -d $STACK_DESCRIPTION
Copy link
Contributor Author

@jsteenb2 jsteenb2 Jun 26, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦 , I forgot this a while back 🤦 x1000


# Initialize a stack with a name and urls to associate with stack.
influx stack init -n $STACK_NAME -u $PATH_TO_TEMPLATE
influx stacks init -n $STACK_NAME -u $PATH_TO_TEMPLATE

For information about how stacks work with InfluxDB templates, see
https://v2.docs.influxdata.com/v2.0/reference/cli/influx/stacks/
Expand Down Expand Up @@ -714,10 +711,10 @@ func (b *cmdPkgBuilder) stackInitRunEFn(cmd *cobra.Command, args []string) error

const fakeUserID = 0 // is 0 because user is pulled from token...
stack, err := pkgSVC.InitStack(context.Background(), fakeUserID, pkger.Stack{
OrgID: orgID,
Name: b.name,
Description: b.description,
URLs: b.urls,
OrgID: orgID,
Name: b.name,
Description: b.description,
TemplateURLs: b.urls,
})
if err != nil {
return err
Expand Down Expand Up @@ -791,7 +788,7 @@ func (b *cmdPkgBuilder) stackListRunEFn(cmd *cobra.Command, args []string) error
"Description": stack.Description,
"Num Resources": len(stack.Resources),
"Sources": stack.Sources,
"URLs": stack.URLs,
"URLs": stack.TemplateURLs,
"Created At": stack.CreatedAt,
})
}
Expand Down Expand Up @@ -862,7 +859,7 @@ func (b *cmdPkgBuilder) stackRemoveRunEFn(cmd *cobra.Command, args []string) err
"Description": stack.Description,
"Num Resources": len(stack.Resources),
"Sources": stack.Sources,
"URLs": stack.URLs,
"URLs": stack.TemplateURLs,
"Created At": stack.CreatedAt,
})

Expand Down Expand Up @@ -901,10 +898,23 @@ func (b *cmdPkgBuilder) cmdStackUpdate() *cobra.Command {

Examples:
# Update a stack with a name and description
influx stack update -i $STACK_ID -n $STACK_NAME -d $STACK_DESCRIPTION
influx stacks update -i $STACK_ID -n $STACK_NAME -d $STACK_DESCRIPTION

# Update a stack with a name and urls to associate with stack.
influx stack update --stack-id $STACK_ID --stack-name $STACK_NAME --template-url $PATH_TO_TEMPLATE
influx stacks update --stack-id $STACK_ID --stack-name $STACK_NAME --template-url $PATH_TO_TEMPLATE

# Update stack with new resources to manage
influx stacks update \
--stack-id $STACK_ID \
--addResource=Bucket=$BUCKET_ID \
--addResource=Dashboard=$DASH_ID

# Update stack with new resources to manage and export stack
# as a template
influx stacks update \
--stack-id $STACK_ID \
--addResource=Bucket=$BUCKET_ID \
--export-file /path/to/file.yml

For information about how stacks work with InfluxDB templates, see
https://v2.docs.influxdata.com/v2.0/reference/cli/influx/stacks
Expand All @@ -917,6 +927,8 @@ func (b *cmdPkgBuilder) cmdStackUpdate() *cobra.Command {
cmd.Flags().StringVarP(&b.name, "stack-name", "n", "", "Name for stack")
cmd.Flags().StringVarP(&b.description, "stack-description", "d", "", "Description for stack")
cmd.Flags().StringArrayVarP(&b.urls, "template-url", "u", nil, "Template urls to associate with stack")
cmd.Flags().StringArrayVar(&b.updateStackOpts.addResources, "addResource", nil, "Additional resources to associate with stack")
cmd.Flags().StringVarP(&b.file, "export-file", "f", "", "Destination for exported template")
registerPrintOptions(cmd, &b.hideHeaders, &b.json)

return cmd
Expand All @@ -933,17 +945,62 @@ func (b *cmdPkgBuilder) stackUpdateRunEFn(cmd *cobra.Command, args []string) err
return ierror.Wrap(err, "required stack id is invalid")
}

stack, err := pkgSVC.UpdateStack(context.Background(), pkger.StackUpdate{
ID: *stackID,
Name: &b.name,
Description: &b.description,
URLs: b.urls,
})
update := pkger.StackUpdate{
ID: *stackID,
Name: &b.name,
Description: &b.description,
TemplateURLs: b.urls,
}

for _, res := range b.updateStackOpts.addResources {
parts := strings.SplitN(res, "=", 2)
if len(parts) < 2 {
continue
}

kind, idRaw := templateKindFold(parts[0]), parts[1]
if err := kind.OK(); err != nil {
return errors.New("resource type is invalid; got: " + b.exportOpts.resourceType)
}

id, err := influxdb.IDFromString(idRaw)
if err != nil {
return ierror.Wrap(err, fmt.Sprintf("%s resource id %q is invalid", kind, idRaw))
}
update.AdditionalResources = append(update.AdditionalResources, pkger.StackAdditionalResource{
APIVersion: pkger.APIVersion,
ID: *id,
Kind: kind,
})
}

stack, err := pkgSVC.UpdateStack(context.Background(), update)
if err != nil {
return err
}

return b.writeStack(b.w, stack)
if err := b.writeStack(b.w, stack); err != nil {
return err
}

if len(update.AdditionalResources) == 0 {
return nil
}

if b.file == "" {
const msg = `
Your stack now differs from your template. Applying an outdated template will revert
these updates. Export a new template with these updates to prevent accidental changes? (y/n)`
for range make([]struct{}, 3) {
if in := b.getInput(msg, "n"); in == "y" {
break
} else if in == "n" {
return nil
}
}
}

return b.exportTemplate(cmd.OutOrStdout(), pkgSVC, b.file, pkger.ExportWithStackID(*stackID))
}

func (b *cmdPkgBuilder) writeStack(w io.Writer, stack pkger.Stack) error {
Expand All @@ -956,15 +1013,16 @@ func (b *cmdPkgBuilder) writeStack(w io.Writer, stack pkger.Stack) error {

tabW.HideHeaders(b.hideHeaders)

tabW.WriteHeaders("ID", "OrgID", "Name", "Description", "Sources", "URLs", "Created At")
tabW.WriteHeaders("ID", "OrgID", "Name", "Description", "Num Resources", "Sources", "URLs", "Created At")
tabW.Write(map[string]interface{}{
"ID": stack.ID,
"OrgID": stack.OrgID,
"Name": stack.Name,
"Description": stack.Description,
"Sources": stack.Sources,
"URLs": stack.URLs,
"Created At": stack.CreatedAt,
"ID": stack.ID,
"OrgID": stack.OrgID,
"Name": stack.Name,
"Description": stack.Description,
"Num Resources": len(stack.Resources),
"Sources": stack.Sources,
"URLs": stack.TemplateURLs,
"Created At": stack.CreatedAt,
})

return nil
Expand Down Expand Up @@ -994,7 +1052,7 @@ func (b *cmdPkgBuilder) registerPkgFileFlags(cmd *cobra.Command) {
cmd.MarkFlagFilename("encoding", "yaml", "yml", "json", "jsonnet")
}

func (b *cmdPkgBuilder) exportPkg(w io.Writer, pkgSVC pkger.SVC, outPath string, opts ...pkger.ExportOptFn) error {
func (b *cmdPkgBuilder) exportTemplate(w io.Writer, pkgSVC pkger.SVC, outPath string, opts ...pkger.ExportOptFn) error {
pkg, err := pkgSVC.Export(context.Background(), opts...)
if err != nil {
return err
Expand Down Expand Up @@ -2089,6 +2147,17 @@ func missingValKeys(m map[string]string) []string {
return out
}

func templateKindFold(resType string) pkger.Kind {
resKind := pkger.KindUnknown
for _, k := range pkger.Kinds() {
if strings.EqualFold(string(k), resType) {
resKind = k
break
}
}
return resKind
}

func find(needle string, haystack []string) int {
for i, h := range haystack {
if strings.ToLower(h) == needle {
Expand Down
4 changes: 2 additions & 2 deletions cmd/influx/pkg_test.go → cmd/influx/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ func Test_Template_Commands(t *testing.T) {
OrgID: 1,
Name: "foo",
Description: "desc",
URLs: []string{
TemplateURLs: []string{
"http://example.com/1",
"http://example.com/2",
},
Expand All @@ -557,7 +557,7 @@ func Test_Template_Commands(t *testing.T) {
OrgID: 1,
Name: "foo",
Description: "desc",
URLs: []string{
TemplateURLs: []string{
"http://example.com/1",
"http://example.com/2",
},
Expand Down
32 changes: 16 additions & 16 deletions cmd/influxd/launcher/pkger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ func TestLauncher_Pkger(t *testing.T) {
assert.Equal(t, stack.Name, newStack.Name)
assert.Equal(t, stack.Description, newStack.Description)
assert.NotNil(t, newStack.Resources, "failed to match stack resources")
expectedURLs := stack.URLs
expectedURLs := stack.TemplateURLs
if expectedURLs == nil {
expectedURLs = []string{}
}
assert.Equal(t, expectedURLs, newStack.URLs, "failed to match stack URLs")
assert.Equal(t, expectedURLs, newStack.TemplateURLs, "failed to match stack URLs")
assert.NotZero(t, newStack.CRUDLog)

return newStack, func() {
Expand Down Expand Up @@ -252,10 +252,10 @@ func TestLauncher_Pkger(t *testing.T) {

t.Run("creating a stack", func(t *testing.T) {
_, cleanup := newStackFn(t, pkger.Stack{
OrgID: l.Org.ID,
Name: "first stack",
Description: "desc",
URLs: []string{"http://example.com"},
OrgID: l.Org.ID,
Name: "first stack",
Description: "desc",
TemplateURLs: []string{"http://example.com"},
})
cleanup()
})
Expand Down Expand Up @@ -406,10 +406,10 @@ func TestLauncher_Pkger(t *testing.T) {

t.Run("updating a stack", func(t *testing.T) {
stack, cleanup := newStackFn(t, pkger.Stack{
OrgID: l.Org.ID,
Name: "first name",
Description: "first desc",
URLs: []string{},
OrgID: l.Org.ID,
Name: "first name",
Description: "first desc",
TemplateURLs: []string{},
})
defer cleanup()

Expand All @@ -418,7 +418,7 @@ func TestLauncher_Pkger(t *testing.T) {
assert.Equal(t, stack.ID, st.ID)
assert.Equal(t, "2nd name", st.Name)
assert.Equal(t, "2nd desc", st.Description)
assert.Equal(t, []string{"http://example.com"}, st.URLs)
assert.Equal(t, []string{"http://example.com"}, st.TemplateURLs)
resources := []pkger.StackResource{
{
APIVersion: pkger.APIVersion,
Expand All @@ -432,10 +432,10 @@ func TestLauncher_Pkger(t *testing.T) {
}

updStack, err := svc.UpdateStack(ctx, pkger.StackUpdate{
ID: stack.ID,
Name: strPtr("2nd name"),
Description: strPtr("2nd desc"),
URLs: []string{"http://example.com"},
ID: stack.ID,
Name: strPtr("2nd name"),
Description: strPtr("2nd desc"),
TemplateURLs: []string{"http://example.com"},
AdditionalResources: []pkger.StackAdditionalResource{
{
APIVersion: pkger.APIVersion,
Expand Down Expand Up @@ -483,7 +483,7 @@ func TestLauncher_Pkger(t *testing.T) {
}

newStack, cleanup := newStackFn(t, pkger.Stack{
URLs: expectedURLs,
TemplateURLs: expectedURLs,
})
defer cleanup()

Expand Down
16 changes: 8 additions & 8 deletions pkger/http_remote_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (s *HTTPRemoteService) InitStack(ctx context.Context, userID influxdb.ID, s
OrgID: stack.OrgID.String(),
Name: stack.Name,
Description: stack.Description,
URLs: stack.URLs,
URLs: stack.TemplateURLs,
}

var respBody RespStack
Expand Down Expand Up @@ -89,7 +89,7 @@ func (s *HTTPRemoteService) UpdateStack(ctx context.Context, upd StackUpdate) (S
reqBody := ReqUpdateStack{
Name: upd.Name,
Description: upd.Description,
TemplateURLs: upd.URLs,
TemplateURLs: upd.TemplateURLs,
}
for _, r := range upd.AdditionalResources {
reqBody.AdditionalResources = append(reqBody.AdditionalResources, ReqUpdateStackResource{
Expand Down Expand Up @@ -242,12 +242,12 @@ func (s *HTTPRemoteService) apply(ctx context.Context, orgID influxdb.ID, dryRun

func convertRespStackToStack(respStack RespStack) (Stack, error) {
newStack := Stack{
Name: respStack.Name,
Description: respStack.Description,
Sources: respStack.Sources,
URLs: respStack.URLs,
Resources: make([]StackResource, 0, len(respStack.Resources)),
CRUDLog: respStack.CRUDLog,
Name: respStack.Name,
Description: respStack.Description,
Sources: respStack.Sources,
TemplateURLs: respStack.URLs,
Resources: make([]StackResource, 0, len(respStack.Resources)),
CRUDLog: respStack.CRUDLog,
}
for _, r := range respStack.Resources {
sr := StackResource{
Expand Down
Loading