diff --git a/pkg/config/config.go b/pkg/config/config.go index 33e5e48b3a..d9338d5f08 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -149,7 +149,7 @@ func (c *Config) Render(properties map[string]interface{}) (string, error) { return "", nil } - templatePath := c.Template.Id() + var templatePath string // include path in errors if we know it if t, ok := c.Template.(*template.FileBasedTemplate); ok { templatePath = t.FilePath() } diff --git a/pkg/config/template/filebased.go b/pkg/config/template/filebased.go index 21fcc6e9bb..edccfde0d6 100644 --- a/pkg/config/template/filebased.go +++ b/pkg/config/template/filebased.go @@ -31,11 +31,13 @@ var ( // FileBasedTemplate is a JSON Template stored in a file - when it's Template.Content is accessed, that file is read. // This is the usual type of Template monaco uses. type FileBasedTemplate struct { - fs afero.Fs + // fs is the file system the to read the template file from + fs afero.Fs + // path of the template file path string } -func (t *FileBasedTemplate) Id() string { +func (t *FileBasedTemplate) ID() string { return t.path } @@ -63,6 +65,8 @@ func (t *FileBasedTemplate) UpdateContent(newContent string) error { return nil } +// NewFileTemplate creates a FileBasedTemplate for a given afero.Fs and filepath. +// If the file can not be accessed an error will be returned. func NewFileTemplate(fs afero.Fs, path string) (Template, error) { sanitizedPath := filepath.Clean(strings.ReplaceAll(path, `\`, `/`)) diff --git a/pkg/config/template/filebased_test.go b/pkg/config/template/filebased_test.go index 4397e34ad2..7615f3606e 100644 --- a/pkg/config/template/filebased_test.go +++ b/pkg/config/template/filebased_test.go @@ -35,7 +35,7 @@ func TestLoadTemplate(t *testing.T) { got, gotErr := template.NewFileTemplate(testFs, testFilepath) assert.NilError(t, gotErr) - assert.Equal(t, got.Id(), testFilepath) + assert.Equal(t, got.ID(), testFilepath) assert.Equal(t, got.(*template.FileBasedTemplate).FilePath(), testFilepath) gotContent, err := got.Content() assert.NilError(t, err) diff --git a/pkg/config/template/inmemory.go b/pkg/config/template/inmemory.go index 137ebf0fc2..9924f9039c 100644 --- a/pkg/config/template/inmemory.go +++ b/pkg/config/template/inmemory.go @@ -20,13 +20,18 @@ var ( _ Template = (*InMemoryTemplate)(nil) ) +// InMemoryTemplate is a JSON Template created in-memory. This is generally used by downloads and conversions, where +// a Template is created on the fly. Deployments generally use FileBasedTemplate instead. +// An InMemoryTemplate may define a dedicated path to write it to when persisting - converted Template are create with a +// path, download ones are not. type InMemoryTemplate struct { id string content string - path *string + // optional path we'd like this Template to be written to if it's persisted + path *string } -func (t *InMemoryTemplate) Id() string { +func (t *InMemoryTemplate) ID() string { return t.id } @@ -39,10 +44,15 @@ func (t *InMemoryTemplate) UpdateContent(newContent string) error { return nil } +// FilePath returns the optional path this Template should be written to if it's persisted. If an InMemoryTemplate has +// not defined a path nil will be returned and the file may be persisted anywhere. Generally a converted v1 Template will +// have a defined FilePath, while a downloaded template does not. func (t *InMemoryTemplate) FilePath() *string { return t.path } +// NewInMemoryTemplate creates a new InMemoryTemplate without a dedicated path it should be written to if persisted. +// To create an InMemoryTemplate with a fixed target path, use NewInMemoryTemplateWithPath. func NewInMemoryTemplate(id, content string) Template { return &InMemoryTemplate{ id: id, @@ -50,6 +60,8 @@ func NewInMemoryTemplate(id, content string) Template { } } +// NewInMemoryTemplateWithPath creates a new InMemoryTemplate with a dedicated path it should be written to if persisted. +// To create a simple InMemoryTemplate without filepath, use NewInMemoryTemplate. func NewInMemoryTemplateWithPath(filepath, content string) Template { return &InMemoryTemplate{ path: &filepath, diff --git a/pkg/config/template/renderer.go b/pkg/config/template/renderer.go index ac8b6ba394..da99c2b34f 100644 --- a/pkg/config/template/renderer.go +++ b/pkg/config/template/renderer.go @@ -25,20 +25,20 @@ import ( func Render(template Template, properties map[string]interface{}) (string, error) { content, err := template.Content() if err != nil { - return "", fmt.Errorf("failure trying to render template %s: %w", template.Id(), err) + return "", fmt.Errorf("failure trying to render template %s: %w", template.ID(), err) } - parsedTemplate, err := ParseTemplate(template.Id(), content) + parsedTemplate, err := ParseTemplate(template.ID(), content) if err != nil { - return "", fmt.Errorf("failure trying to render template %s: %w", template.Id(), err) + return "", fmt.Errorf("failure trying to render template %s: %w", template.ID(), err) } result := bytes.Buffer{} err = parsedTemplate.Execute(&result, properties) if err != nil { - return "", fmt.Errorf("failure trying to render template %s: %w", template.Id(), err) + return "", fmt.Errorf("failure trying to render template %s: %w", template.ID(), err) } return result.String(), nil diff --git a/pkg/config/template/template.go b/pkg/config/template/template.go index a6b367eab3..85a0e15df2 100644 --- a/pkg/config/template/template.go +++ b/pkg/config/template/template.go @@ -18,12 +18,12 @@ package template // The main implementation is FileBasedTemplate, which loads its Content from a file on disk. An InMemoryTemplate exists // as well and is used in cases where Template data is not related to a file - e.g. during download or convert. type Template interface { - // ID of the template - Id() string + // ID is a unique identifier for this template. It should be usable in user-facing messages. + ID() string - // Content returns the string content of the template, returns error if content is not accessible + // Content returns the string content of the template, returns error if content is not accessible. Content() (string, error) - // UpdateContent sets the content of the template to the new provided one, returns error if update failed + // UpdateContent sets the content of the template to the new provided one, returns error if update failed. UpdateContent(newContent string) error } diff --git a/pkg/delete/delete_test.go b/pkg/delete/delete_test.go index b04640d7ed..d23d0c81cf 100644 --- a/pkg/delete/delete_test.go +++ b/pkg/delete/delete_test.go @@ -546,7 +546,7 @@ func TestSplitConfigsForDeletion(t *testing.T) { }, }, { - name: "Id-fallback", + name: "ID-fallback", args: args{ entries: []pointer.DeletePointer{{Identifier: "d1"}, {Identifier: "d2-id"}}, values: []dtclient.Value{{Name: "d1", Id: "id1"}, {Name: "d2", Id: "d2-id"}, {Name: "d3", Id: "id3"}}, diff --git a/pkg/download/classic/downloader.go b/pkg/download/classic/downloader.go index 7ef5c07a91..51592d5572 100644 --- a/pkg/download/classic/downloader.go +++ b/pkg/download/classic/downloader.go @@ -206,7 +206,7 @@ func (d *Downloader) createConfigForDownloadedJson(mappedJson map[string]interfa coord := coordinate.Coordinate{ Project: projectId, - ConfigId: templ.Id(), + ConfigId: templ.ID(), Type: theApi.ID, } diff --git a/pkg/download/dependency_resolution/resolver/ahocorasick_dep_resolver.go b/pkg/download/dependency_resolution/resolver/ahocorasick_dep_resolver.go index dac5b8bf72..8a6d46325e 100644 --- a/pkg/download/dependency_resolution/resolver/ahocorasick_dep_resolver.go +++ b/pkg/download/dependency_resolution/resolver/ahocorasick_dep_resolver.go @@ -112,7 +112,7 @@ func findAndReplaceIDs(apiName string, configToBeUpdated config.Config, c depend continue // skip self referencing configs } - log.Debug("\treference: '%v/%v' referencing '%v' in coordinate '%v' ", apiName, configToBeUpdated.Template.Id(), key, conf.Coordinate) + log.Debug("\treference: '%v/%v' referencing '%v' in coordinate '%v' ", apiName, configToBeUpdated.Template.ID(), key, conf.Coordinate) parameterName := CreateParameterName(conf.Coordinate.Type, conf.Coordinate.ConfigId) coord := conf.Coordinate diff --git a/pkg/download/dependency_resolution/resolver/basic_dep_resolver.go b/pkg/download/dependency_resolution/resolver/basic_dep_resolver.go index 76a784a2f9..c8211731a3 100644 --- a/pkg/download/dependency_resolution/resolver/basic_dep_resolver.go +++ b/pkg/download/dependency_resolution/resolver/basic_dep_resolver.go @@ -58,7 +58,7 @@ func basicFindAndReplaceIDs(apiName string, configToBeUpdated config.Config, con for key, conf := range configs { if shouldReplaceReference(configToBeUpdated, conf, content, key) { - log.Debug("\treference: '%v/%v' referencing '%v' in coordinate '%v' ", apiName, configToBeUpdated.Template.Id(), key, conf.Coordinate) + log.Debug("\treference: '%v/%v' referencing '%v' in coordinate '%v' ", apiName, configToBeUpdated.Template.ID(), key, conf.Coordinate) parameterName := CreateParameterName(conf.Coordinate.Type, conf.Coordinate.ConfigId) coord := conf.Coordinate @@ -80,5 +80,5 @@ func shouldReplaceReference(configToBeUpdated config.Config, configToUpdateFrom return false //dashboards can not actually reference each other, but often contain a link to another inside a markdown tile } - return configToUpdateFrom.Template.Id() != configToBeUpdated.Template.Id() && strings.Contains(contentToBeUpdated, keyToReplace) + return configToUpdateFrom.Template.ID() != configToBeUpdated.Template.ID() && strings.Contains(contentToBeUpdated, keyToReplace) } diff --git a/pkg/persistence/config/writer/config_writer.go b/pkg/persistence/config/writer/config_writer.go index 90d8bc82b7..b447a58e31 100644 --- a/pkg/persistence/config/writer/config_writer.go +++ b/pkg/persistence/config/writer/config_writer.go @@ -614,13 +614,13 @@ func extractTemplate(context *detailedSerializerContext, cfg config.Config) (str } name = n } else { - name = sanitize(t.Id()) + ".json" + name = sanitize(t.ID()) + ".json" path = filepath.Join(context.configFolder, name) } case *template.FileBasedTemplate: path = t.FilePath() if path == "" { - return "", configTemplate{}, newDetailedConfigWriterError(context.serializerContext, fmt.Errorf("file-based template %q is missing file path - can not write to file", t.Id())) + return "", configTemplate{}, newDetailedConfigWriterError(context.serializerContext, fmt.Errorf("file-based template %q is missing file path - can not write to file", t.ID())) } n, err := filepath.Rel(context.configFolder, filepath.Clean(path)) if err != nil {