forked from TrueCloudLab/certificates
Add methods to initialize ssh templates in provisioners.
This commit is contained in:
parent
af3eeb870e
commit
c6746425a3
1 changed files with 107 additions and 0 deletions
107
authority/provisioner/ssh_options.go
Normal file
107
authority/provisioner/ssh_options.go
Normal file
|
@ -0,0 +1,107 @@
|
|||
package provisioner
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/smallstep/certificates/sshutil"
|
||||
)
|
||||
|
||||
// CertificateOptions is an interface that returns a list of options passed when
|
||||
// creating a new certificate.
|
||||
type SSHCertificateOptions interface {
|
||||
Options(SignSSHOptions) []sshutil.Option
|
||||
}
|
||||
|
||||
type sshCertificateOptionsFunc func(SignSSHOptions) []sshutil.Option
|
||||
|
||||
func (fn sshCertificateOptionsFunc) Options(so SignSSHOptions) []sshutil.Option {
|
||||
return fn(so)
|
||||
}
|
||||
|
||||
// SSHOptions are a collection of custom options that can be added to each
|
||||
// provisioner.
|
||||
type SSHOptions struct {
|
||||
// Template contains an SSH certificate template. It can be a JSON template
|
||||
// escaped in a string or it can be also encoded in base64.
|
||||
Template string `json:"template,omitempty"`
|
||||
|
||||
// TemplateFile points to a file containing a SSH certificate template.
|
||||
TemplateFile string `json:"templateFile,omitempty"`
|
||||
|
||||
// TemplateData is a JSON object with variables that can be used in custom
|
||||
// templates.
|
||||
TemplateData json.RawMessage `json:"templateData,omitempty"`
|
||||
}
|
||||
|
||||
// HasTemplate returns true if a template is defined in the provisioner options.
|
||||
func (o *SSHOptions) HasTemplate() bool {
|
||||
return o != nil && (o.Template != "" || o.TemplateFile != "")
|
||||
}
|
||||
|
||||
// SSHTemplateOptions generates a CertificateOptions with the template and data
|
||||
// defined in the ProvisionerOptions, the provisioner generated data, and the
|
||||
// user data provided in the request. If no template has been provided,
|
||||
// x509util.DefaultLeafTemplate will be used.
|
||||
func TemplateSSHOptions(o *SSHOptions, data sshutil.TemplateData) (SSHCertificateOptions, error) {
|
||||
return CustomSSHTemplateOptions(o, data, sshutil.DefaultCertificate)
|
||||
}
|
||||
|
||||
// CustomTemplateOptions generates a CertificateOptions with the template, data
|
||||
// defined in the ProvisionerOptions, the provisioner generated data and the
|
||||
// user data provided in the request. If no template has been provided in the
|
||||
// ProvisionerOptions, the given template will be used.
|
||||
func CustomSSHTemplateOptions(o *SSHOptions, data sshutil.TemplateData, defaultTemplate string) (SSHCertificateOptions, error) {
|
||||
if o != nil {
|
||||
if data == nil {
|
||||
data = sshutil.NewTemplateData()
|
||||
}
|
||||
|
||||
// Add template data if any.
|
||||
if len(o.TemplateData) > 0 {
|
||||
if err := json.Unmarshal(o.TemplateData, &data); err != nil {
|
||||
return nil, errors.Wrap(err, "error unmarshaling template data")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sshCertificateOptionsFunc(func(so SignSSHOptions) []sshutil.Option {
|
||||
// We're not provided user data without custom templates.
|
||||
if !o.HasTemplate() {
|
||||
return []sshutil.Option{
|
||||
sshutil.WithTemplate(defaultTemplate, data),
|
||||
}
|
||||
}
|
||||
|
||||
// Add user provided data.
|
||||
if len(so.TemplateData) > 0 {
|
||||
userObject := make(map[string]interface{})
|
||||
if err := json.Unmarshal(so.TemplateData, &userObject); err != nil {
|
||||
data.SetUserData(map[string]interface{}{})
|
||||
} else {
|
||||
data.SetUserData(userObject)
|
||||
}
|
||||
}
|
||||
|
||||
// Load a template from a file if Template is not defined.
|
||||
if o.Template == "" && o.TemplateFile != "" {
|
||||
return []sshutil.Option{
|
||||
sshutil.WithTemplateFile(o.TemplateFile, data),
|
||||
}
|
||||
}
|
||||
|
||||
// Load a template from the Template fields
|
||||
// 1. As a JSON in a string.
|
||||
template := strings.TrimSpace(o.Template)
|
||||
if strings.HasPrefix(template, "{") {
|
||||
return []sshutil.Option{
|
||||
sshutil.WithTemplate(template, data),
|
||||
}
|
||||
}
|
||||
// 2. As a base64 encoded JSON.
|
||||
return []sshutil.Option{
|
||||
sshutil.WithTemplateBase64(template, data),
|
||||
}
|
||||
}), nil
|
||||
}
|
Loading…
Reference in a new issue