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

closes: #18646
pull/18776/head
Johnny Steenbergen 2020-06-26 15:12:57 -07:00 committed by Johnny Steenbergen
parent c93408dca8
commit 2f2140e7a7
12 changed files with 212 additions and 126 deletions

View File

@ -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]

View File

@ -87,6 +87,10 @@ type cmdPkgBuilder struct {
telegrafs string
variables string
}
updateStackOpts struct {
addResources []string
}
}
func newCmdPkgBuilder(svcFn pkgSVCsFn, f *globalFlags, opts genericCLIOpts) *cmdPkgBuilder {
@ -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)
@ -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 {
@ -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 {
@ -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
# 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/
@ -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
@ -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,
})
}
@ -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,
})
@ -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
@ -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
@ -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 {
@ -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
@ -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
@ -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 {

View File

@ -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",
},
@ -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",
},

View File

@ -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() {
@ -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()
})
@ -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()
@ -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,
@ -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,
@ -483,7 +483,7 @@ func TestLauncher_Pkger(t *testing.T) {
}
newStack, cleanup := newStackFn(t, pkger.Stack{
URLs: expectedURLs,
TemplateURLs: expectedURLs,
})
defer cleanup()

View File

@ -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
@ -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{
@ -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{

View File

@ -227,10 +227,10 @@ func (s *HTTPServer) createStack(w http.ResponseWriter, r *http.Request) {
}
stack, err := s.svc.InitStack(r.Context(), auth.GetUserID(), Stack{
OrgID: reqBody.orgID(),
Name: reqBody.Name,
Description: reqBody.Description,
URLs: reqBody.URLs,
OrgID: reqBody.orgID(),
Name: reqBody.Name,
Description: reqBody.Description,
TemplateURLs: reqBody.URLs,
})
if err != nil {
s.api.Err(w, r, err)
@ -354,10 +354,10 @@ func (s *HTTPServer) updateStack(w http.ResponseWriter, r *http.Request) {
}
update := StackUpdate{
ID: stackID,
Name: req.Name,
Description: req.Description,
URLs: append(req.TemplateURLs, req.URLs...),
ID: stackID,
Name: req.Name,
Description: req.Description,
TemplateURLs: append(req.TemplateURLs, req.URLs...),
}
for _, res := range req.AdditionalResources {
id, err := influxdb.IDFromString(res.ID)
@ -912,7 +912,7 @@ func convertStackToRespStack(st Stack) RespStack {
Description: st.Description,
Resources: resources,
Sources: append([]string{}, st.Sources...),
URLs: append([]string{}, st.URLs...),
URLs: append([]string{}, st.TemplateURLs...),
CRUDLog: st.CRUDLog,
}
}

View File

@ -763,12 +763,12 @@ func TestPkgerHTTPServer(t *testing.T) {
{
name: "for stack that has all fields available",
stub: pkger.Stack{
ID: 1,
OrgID: expectedOrgID,
Name: "name",
Description: "desc",
Sources: []string{"threeve"},
URLs: []string{"http://example.com"},
ID: 1,
OrgID: expectedOrgID,
Name: "name",
Description: "desc",
Sources: []string{"threeve"},
TemplateURLs: []string{"http://example.com"},
Resources: []pkger.StackResource{
{
APIVersion: pkger.APIVersion,
@ -995,8 +995,8 @@ func TestPkgerHTTPServer(t *testing.T) {
if upd.Description != nil {
st.Description = *upd.Description
}
if upd.URLs != nil {
st.URLs = upd.URLs
if upd.TemplateURLs != nil {
st.TemplateURLs = upd.TemplateURLs
}
return st, nil
},

View File

@ -31,13 +31,13 @@ type (
// platform. This stack is updated only after side effects of applying a pkg.
// If the pkg is applied, and no changes are had, then the stack is not updated.
Stack struct {
ID influxdb.ID
OrgID influxdb.ID
Name string
Description string
Sources []string
URLs []string
Resources []StackResource
ID influxdb.ID
OrgID influxdb.ID
Name string
Description string
Sources []string
TemplateURLs []string
Resources []StackResource
influxdb.CRUDLog
}
@ -63,7 +63,7 @@ type (
ID influxdb.ID
Name *string
Description *string
URLs []string
TemplateURLs []string
AdditionalResources []StackAdditionalResource
}
@ -306,7 +306,7 @@ func NewService(opts ...ServiceSetterFn) *Service {
// with urls that point to the location of packages that are included as part of the stack when
// it is applied.
func (s *Service) InitStack(ctx context.Context, userID influxdb.ID, stack Stack) (Stack, error) {
if err := validURLs(stack.URLs); err != nil {
if err := validURLs(stack.TemplateURLs); err != nil {
return Stack{}, err
}
@ -403,8 +403,8 @@ func (s *Service) applyStackUpdate(existing Stack, upd StackUpdate) Stack {
if upd.Description != nil {
existing.Description = *upd.Description
}
if upd.URLs != nil {
existing.URLs = upd.URLs
if upd.TemplateURLs != nil {
existing.TemplateURLs = upd.TemplateURLs
}
existing.UpdatedAt = s.timeGen.Now()
@ -1563,7 +1563,7 @@ func (s *Service) applyBuckets(ctx context.Context, buckets []*stateBucket) appl
func (s *Service) rollbackBuckets(ctx context.Context, buckets []*stateBucket) error {
rollbackFn := func(b *stateBucket) error {
if !IsNew(b.stateStatus) && b.existing == nil {
if !IsNew(b.stateStatus) && b.existing == nil || isSystemBucket(b.existing) {
return nil
}
@ -1599,6 +1599,9 @@ func (s *Service) rollbackBuckets(ctx context.Context, buckets []*stateBucket) e
}
func (s *Service) applyBucket(ctx context.Context, b *stateBucket) (influxdb.Bucket, error) {
if isSystemBucket(b.existing) {
return *b.existing, nil
}
switch {
case IsRemoval(b.stateStatus):
if err := s.bucketSVC.DeleteBucket(ctx, b.ID()); err != nil {
@ -2406,6 +2409,9 @@ func (s *Service) applyTasks(ctx context.Context, tasks []*stateTask) applier {
}
func (s *Service) applyTask(ctx context.Context, userID influxdb.ID, t *stateTask) (influxdb.Task, error) {
if isRestrictedTask(t.existing) {
return *t.existing, nil
}
switch {
case IsRemoval(t.stateStatus):
if err := s.taskSVC.DeleteTask(ctx, t.ID()); err != nil {
@ -2460,7 +2466,7 @@ func (s *Service) applyTask(ctx context.Context, userID influxdb.ID, t *stateTas
func (s *Service) rollbackTasks(ctx context.Context, tasks []*stateTask) error {
rollbackFn := func(t *stateTask) error {
if !IsNew(t.stateStatus) && t.existing == nil {
if !IsNew(t.stateStatus) && t.existing == nil || isRestrictedTask(t.existing) {
return nil
}
@ -2909,7 +2915,7 @@ func (s *Service) getStackRemotePackages(ctx context.Context, stackID influxdb.I
}
var remotePkgs []*Pkg
for _, rawURL := range stack.URLs {
for _, rawURL := range stack.TemplateURLs {
u, err := url.Parse(rawURL)
if err != nil {
return nil, &influxdb.Error{
@ -2951,7 +2957,7 @@ func (s *Service) updateStackAfterSuccess(ctx context.Context, stackID influxdb.
var stackResources []StackResource
for _, b := range state.mBuckets {
if IsRemoval(b.stateStatus) {
if IsRemoval(b.stateStatus) || isSystemBucket(b.existing) {
continue
}
stackResources = append(stackResources, StackResource{
@ -3025,7 +3031,7 @@ func (s *Service) updateStackAfterSuccess(ctx context.Context, stackID influxdb.
})
}
for _, t := range state.mTasks {
if IsRemoval(t.stateStatus) {
if IsRemoval(t.stateStatus) || isRestrictedTask(t.existing) {
continue
}
stackResources = append(stackResources, StackResource{
@ -3478,6 +3484,14 @@ func validURLs(urls []string) error {
return nil
}
func isRestrictedTask(t *influxdb.Task) bool {
return t != nil && t.Type != influxdb.TaskSystemType
}
func isSystemBucket(b *influxdb.Bucket) bool {
return b != nil && b.Type == influxdb.BucketTypeSystem
}
func labelSlcToMap(labels []*stateLabel) map[string]*stateLabel {
m := make(map[string]*stateLabel)
for i := range labels {

View File

@ -36,7 +36,7 @@ func (s *loggingMW) InitStack(ctx context.Context, userID influxdb.ID, newStack
zap.Error(err),
zap.Stringer("orgID", newStack.OrgID),
zap.Stringer("userID", userID),
zap.Strings("urls", newStack.URLs),
zap.Strings("urls", newStack.TemplateURLs),
zap.Duration("took", time.Since(start)),
)
}(time.Now())
@ -112,7 +112,7 @@ func (s *loggingMW) UpdateStack(ctx context.Context, upd StackUpdate) (_ Stack,
fields = append(fields, zap.String("desc", *upd.Description))
}
fields = append(fields,
zap.Strings("urls", upd.URLs),
zap.Strings("urls", upd.TemplateURLs),
zap.Duration("took", time.Since(start)),
)

View File

@ -3545,31 +3545,31 @@ func TestService(t *testing.T) {
{
name: "update URLs",
input: StackUpdate{
URLs: []string{"http://example.com"},
TemplateURLs: []string{"http://example.com"},
},
expected: Stack{
URLs: []string{"http://example.com"},
TemplateURLs: []string{"http://example.com"},
},
},
{
name: "update first 3",
input: StackUpdate{
Name: strPtr("name"),
Description: strPtr("desc"),
URLs: []string{"http://example.com"},
Name: strPtr("name"),
Description: strPtr("desc"),
TemplateURLs: []string{"http://example.com"},
},
expected: Stack{
Name: "name",
Description: "desc",
URLs: []string{"http://example.com"},
Name: "name",
Description: "desc",
TemplateURLs: []string{"http://example.com"},
},
},
{
name: "update with metaname collisions",
input: StackUpdate{
Name: strPtr("name"),
Description: strPtr("desc"),
URLs: []string{"http://example.com"},
Name: strPtr("name"),
Description: strPtr("desc"),
TemplateURLs: []string{"http://example.com"},
AdditionalResources: []StackAdditionalResource{
{
APIVersion: APIVersion,
@ -3586,9 +3586,9 @@ func TestService(t *testing.T) {
},
},
expected: Stack{
Name: "name",
Description: "desc",
URLs: []string{"http://example.com"},
Name: "name",
Description: "desc",
TemplateURLs: []string{"http://example.com"},
Resources: []StackResource{
{
APIVersion: APIVersion,
@ -3608,9 +3608,9 @@ func TestService(t *testing.T) {
{
name: "update all",
input: StackUpdate{
Name: strPtr("name"),
Description: strPtr("desc"),
URLs: []string{"http://example.com"},
Name: strPtr("name"),
Description: strPtr("desc"),
TemplateURLs: []string{"http://example.com"},
AdditionalResources: []StackAdditionalResource{
{
APIVersion: APIVersion,
@ -3621,9 +3621,9 @@ func TestService(t *testing.T) {
},
},
expected: Stack{
Name: "name",
Description: "desc",
URLs: []string{"http://example.com"},
Name: "name",
Description: "desc",
TemplateURLs: []string{"http://example.com"},
Resources: []StackResource{
{
APIVersion: APIVersion,
@ -3669,7 +3669,7 @@ func TestService(t *testing.T) {
assert.Zero(t, stack.CreatedAt) // should always zero value in these tests
assert.Equal(t, tt.expected.Name, stack.Name)
assert.Equal(t, tt.expected.Description, stack.Description)
assert.Equal(t, tt.expected.URLs, stack.URLs)
assert.Equal(t, tt.expected.TemplateURLs, stack.TemplateURLs)
assert.Equal(t, now, stack.UpdatedAt)
}

View File

@ -294,7 +294,7 @@ func convertStackToEnt(stack Stack) (kv.Entity, error) {
CreatedAt: stack.CreatedAt,
UpdatedAt: stack.UpdatedAt,
Sources: stack.Sources,
URLs: stack.URLs,
URLs: stack.TemplateURLs,
}
for _, res := range stack.Resources {
@ -323,10 +323,10 @@ func convertStackToEnt(stack Stack) (kv.Entity, error) {
func convertStackEntToStack(ent *entStack) (Stack, error) {
stack := Stack{
Name: ent.Name,
Description: ent.Description,
Sources: ent.Sources,
URLs: ent.URLs,
Name: ent.Name,
Description: ent.Description,
Sources: ent.Sources,
TemplateURLs: ent.URLs,
CRUDLog: influxdb.CRUDLog{
CreatedAt: ent.CreatedAt,
UpdatedAt: ent.UpdatedAt,

View File

@ -30,8 +30,8 @@ func TestStoreKV(t *testing.T) {
CreatedAt: now,
UpdatedAt: now.Add(time.Hour),
},
Sources: urls,
URLs: urls,
Sources: urls,
TemplateURLs: urls,
Resources: []pkger.StackResource{
{
APIVersion: pkger.APIVersion,