forked from TrueCloudLab/certificates
Merge pull request #195 from smallstep/custom-templates
Templates without the filesystem
This commit is contained in:
commit
91f0caa6ff
2 changed files with 33 additions and 12 deletions
|
@ -106,6 +106,7 @@ type Template struct {
|
||||||
TemplatePath string `json:"template"`
|
TemplatePath string `json:"template"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Comment string `json:"comment"`
|
Comment string `json:"comment"`
|
||||||
|
Content []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate returns an error if the template is not valid.
|
// Validate returns an error if the template is not valid.
|
||||||
|
@ -117,10 +118,12 @@ func (t *Template) Validate() error {
|
||||||
return errors.New("template name cannot be empty")
|
return errors.New("template name cannot be empty")
|
||||||
case t.Type != Snippet && t.Type != File && t.Type != Directory:
|
case t.Type != Snippet && t.Type != File && t.Type != Directory:
|
||||||
return errors.Errorf("invalid template type %s, it must be %s, %s, or %s", t.Type, Snippet, File, Directory)
|
return errors.Errorf("invalid template type %s, it must be %s, %s, or %s", t.Type, Snippet, File, Directory)
|
||||||
case t.TemplatePath == "" && t.Type != Directory:
|
case t.TemplatePath == "" && t.Type != Directory && len(t.Content) == 0:
|
||||||
return errors.New("template template cannot be empty")
|
return errors.New("template template cannot be empty")
|
||||||
case t.TemplatePath != "" && t.Type == Directory:
|
case t.TemplatePath != "" && t.Type == Directory:
|
||||||
return errors.New("template template must be empty with directory type")
|
return errors.New("template template must be empty with directory type")
|
||||||
|
case t.TemplatePath != "" && len(t.Content) > 0:
|
||||||
|
return errors.New("template template must be empty with content")
|
||||||
case t.Path == "":
|
case t.Path == "":
|
||||||
return errors.New("template path cannot be empty")
|
return errors.New("template path cannot be empty")
|
||||||
}
|
}
|
||||||
|
@ -148,20 +151,30 @@ func (t *Template) Validate() error {
|
||||||
// template fails.
|
// template fails.
|
||||||
func (t *Template) Load() error {
|
func (t *Template) Load() error {
|
||||||
if t.Template == nil && t.Type != Directory {
|
if t.Template == nil && t.Type != Directory {
|
||||||
filename := config.StepAbs(t.TemplatePath)
|
switch {
|
||||||
b, err := ioutil.ReadFile(filename)
|
case t.TemplatePath != "":
|
||||||
if err != nil {
|
filename := config.StepAbs(t.TemplatePath)
|
||||||
return errors.Wrapf(err, "error reading %s", filename)
|
b, err := ioutil.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error reading %s", filename)
|
||||||
|
}
|
||||||
|
return t.LoadBytes(b)
|
||||||
|
default:
|
||||||
|
return t.LoadBytes(t.Content)
|
||||||
}
|
}
|
||||||
tmpl, err := template.New(t.Name).Funcs(sprig.TxtFuncMap()).Parse(string(b))
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, "error parsing %s", filename)
|
|
||||||
}
|
|
||||||
t.Template = tmpl
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Template) LoadBytes(b []byte) error {
|
||||||
|
tmpl, err := template.New(t.Name).Funcs(sprig.TxtFuncMap()).Parse(string(b))
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error parsing template %s", t.Name)
|
||||||
|
}
|
||||||
|
t.Template = tmpl
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Render executes the template with the given data and returns the rendered
|
// Render executes the template with the given data and returns the rendered
|
||||||
// version.
|
// version.
|
||||||
func (t *Template) Render(data interface{}) ([]byte, error) {
|
func (t *Template) Render(data interface{}) ([]byte, error) {
|
||||||
|
|
|
@ -62,6 +62,12 @@ func TestSSHTemplates_Validate(t *testing.T) {
|
||||||
host := []Template{
|
host := []Template{
|
||||||
{Name: "ca.tpl", Type: File, TemplatePath: "../authority/testdata/templates/ca.tpl", Path: "/etc/ssh/ca.pub", Comment: "#"},
|
{Name: "ca.tpl", Type: File, TemplatePath: "../authority/testdata/templates/ca.tpl", Path: "/etc/ssh/ca.pub", Comment: "#"},
|
||||||
}
|
}
|
||||||
|
content := []Template{
|
||||||
|
{Name: "test.tpl", Type: File, Content: []byte("some content"), Path: "/test.pub", Comment: "#"},
|
||||||
|
}
|
||||||
|
badContent := []Template{
|
||||||
|
{Name: "ca.tpl", Type: File, TemplatePath: "../authority/testdata/templates/ca.tpl", Content: []byte("some content"), Path: "/etc/ssh/ca.pub", Comment: "#"},
|
||||||
|
}
|
||||||
|
|
||||||
type fields struct {
|
type fields struct {
|
||||||
User []Template
|
User []Template
|
||||||
|
@ -75,8 +81,10 @@ func TestSSHTemplates_Validate(t *testing.T) {
|
||||||
{"ok", fields{user, host}, false},
|
{"ok", fields{user, host}, false},
|
||||||
{"user", fields{user, nil}, false},
|
{"user", fields{user, nil}, false},
|
||||||
{"host", fields{nil, host}, false},
|
{"host", fields{nil, host}, false},
|
||||||
|
{"content", fields{content, nil}, false},
|
||||||
{"badUser", fields{[]Template{{}}, nil}, true},
|
{"badUser", fields{[]Template{{}}, nil}, true},
|
||||||
{"badHost", fields{nil, []Template{{}}}, true},
|
{"badHost", fields{nil, []Template{{}}}, true},
|
||||||
|
{"badContent", fields{badContent, nil}, true},
|
||||||
}
|
}
|
||||||
var nilValue *SSHTemplates
|
var nilValue *SSHTemplates
|
||||||
assert.NoError(t, nilValue.Validate())
|
assert.NoError(t, nilValue.Validate())
|
||||||
|
@ -163,8 +171,8 @@ func TestLoadAll(t *testing.T) {
|
||||||
{"ok", args{tmpl}, false},
|
{"ok", args{tmpl}, false},
|
||||||
{"empty", args{&Templates{}}, false},
|
{"empty", args{&Templates{}}, false},
|
||||||
{"nil", args{nil}, false},
|
{"nil", args{nil}, false},
|
||||||
{"badUser", args{&Templates{SSH: &SSHTemplates{User: []Template{{}}}}}, true},
|
{"badUser", args{&Templates{SSH: &SSHTemplates{User: []Template{{TemplatePath: "missing"}}}}}, true},
|
||||||
{"badHost", args{&Templates{SSH: &SSHTemplates{Host: []Template{{}}}}}, true},
|
{"badHost", args{&Templates{SSH: &SSHTemplates{Host: []Template{{TemplatePath: "missing"}}}}}, true},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue