mirror of
https://github.com/hanzokms/packer-plugin.git
synced 2026-10-30 20:38:34 +00:00
147 lines
4.6 KiB
Go
147 lines
4.6 KiB
Go
//go:generate packer-sdc struct-markdown
|
|
//go:generate packer-sdc mapstructure-to-hcl2 -type DatasourceOutput,Config,Secret,UniversalAuth
|
|
|
|
package secrets
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
kms "github.com/hanzokms/packer-plugin/client"
|
|
|
|
"github.com/hashicorp/hcl/v2/hcldec"
|
|
"github.com/hashicorp/packer-plugin-sdk/template/config"
|
|
"github.com/zclconf/go-cty/cty"
|
|
)
|
|
|
|
type Datasource struct {
|
|
config Config
|
|
client *kms.Client
|
|
}
|
|
|
|
type UniversalAuth struct {
|
|
// The Client ID for Hanzo KMS Universal Authentication.
|
|
ClientID string `mapstructure:"client_id" required:"true"`
|
|
// The Client Secret for Hanzo KMS Universal Authentication. You may use KMS_UNIVERSAL_AUTH_CLIENT_SECRET env variable instead.
|
|
ClientSecret string `mapstructure:"client_secret"`
|
|
}
|
|
|
|
type Config struct {
|
|
// The host URL of your Hanzo KMS instance. If a value isn't provided, KMS_HOST may be used. Default: https://kms.hanzo.ai
|
|
Host string `mapstructure:"host"`
|
|
// The project to list secrets from.
|
|
ProjectId string `mapstructure:"project_id" required:"true"`
|
|
// The secret path to list secrets from. Default: /
|
|
FolderPath string `mapstructure:"folder_path"`
|
|
// The environment to list secrets from. (e.g. dev, staging, prod)
|
|
EnvSlug string `mapstructure:"env_slug" required:"true"`
|
|
|
|
// Configuration for Hanzo KMS Universal Authentication.
|
|
UniversalAuth UniversalAuth `mapstructure:"universal_auth"`
|
|
}
|
|
|
|
type Secret struct {
|
|
Version int `mapstructure:"version" required:"true"`
|
|
Workspace string `mapstructure:"workspace" required:"true"`
|
|
Type string `mapstructure:"type" required:"true"`
|
|
Environment string `mapstructure:"environment" required:"true"`
|
|
SecretKey string `mapstructure:"secret_key" required:"true"`
|
|
SecretValue string `mapstructure:"secret_value" required:"true"`
|
|
SecretComment string `mapstructure:"secret_comment" required:"true"`
|
|
}
|
|
|
|
type DatasourceOutput struct {
|
|
Secrets map[string]Secret `mapstructure:"secrets" required:"true"`
|
|
}
|
|
|
|
func (d *Datasource) ConfigSpec() hcldec.ObjectSpec {
|
|
return d.config.FlatMapstructure().HCL2Spec()
|
|
}
|
|
|
|
func (d *Datasource) Configure(raws ...interface{}) error {
|
|
err := config.Decode(&d.config, nil, raws...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Verify required variables are passed
|
|
if d.config.ProjectId == "" {
|
|
return fmt.Errorf("project_id is required")
|
|
}
|
|
if d.config.EnvSlug == "" {
|
|
return fmt.Errorf("env_slug is required")
|
|
}
|
|
|
|
if d.config.FolderPath == "" {
|
|
d.config.FolderPath = "/"
|
|
}
|
|
|
|
if d.config.Host == "" {
|
|
envHost := os.Getenv("KMS_HOST")
|
|
if envHost == "" {
|
|
d.config.Host = "https://kms.hanzo.ai"
|
|
} else {
|
|
d.config.Host = envHost
|
|
}
|
|
}
|
|
|
|
// Validate UniversalAuth credentials
|
|
if d.config.UniversalAuth.ClientID == "" {
|
|
return fmt.Errorf("universal_auth.client_id is required")
|
|
}
|
|
if d.config.UniversalAuth.ClientSecret == "" {
|
|
clientSecret := os.Getenv("KMS_UNIVERSAL_AUTH_CLIENT_SECRET")
|
|
if clientSecret == "" {
|
|
return fmt.Errorf("universal_auth.client_secret config variable or KMS_UNIVERSAL_AUTH_CLIENT_SECRET env variable required")
|
|
}
|
|
d.config.UniversalAuth.ClientSecret = clientSecret
|
|
}
|
|
|
|
clientCfg := kms.Config{
|
|
HostURL: d.config.Host,
|
|
ClientId: d.config.UniversalAuth.ClientID,
|
|
ClientSecret: d.config.UniversalAuth.ClientSecret,
|
|
}
|
|
|
|
client, client_err := kms.NewClient(clientCfg)
|
|
if client_err != nil {
|
|
return fmt.Errorf("failed to initialize Hanzo KMS client using Universal Authentication: %w", client_err)
|
|
}
|
|
|
|
d.client = client
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *Datasource) OutputSpec() hcldec.ObjectSpec {
|
|
return (&DatasourceOutput{}).FlatMapstructure().HCL2Spec()
|
|
}
|
|
|
|
func (d *Datasource) Execute() (cty.Value, error) {
|
|
secrets, err := d.client.GetRawSecrets(d.config.FolderPath, d.config.EnvSlug, d.config.ProjectId)
|
|
if err != nil {
|
|
outputSchemaType := hcldec.ImpliedType(d.OutputSpec())
|
|
return cty.NullVal(outputSchemaType), fmt.Errorf("failed to retrieve secrets from Hanzo KMS API (folder: '%s', environment: '%s'): %w", d.config.FolderPath, d.config.EnvSlug, err)
|
|
}
|
|
|
|
ctySecretsMap := make(map[string]cty.Value)
|
|
for _, s := range secrets {
|
|
secretVal := cty.ObjectVal(map[string]cty.Value{
|
|
"version": cty.NumberIntVal(int64(s.Version)),
|
|
"workspace": cty.StringVal(s.Workspace),
|
|
"type": cty.StringVal(s.Type),
|
|
"environment": cty.StringVal(s.Environment),
|
|
"secret_key": cty.StringVal(s.SecretKey),
|
|
"secret_value": cty.StringVal(s.SecretValue),
|
|
"secret_comment": cty.StringVal(s.SecretComment),
|
|
})
|
|
ctySecretsMap[s.SecretKey] = secretVal
|
|
}
|
|
|
|
outputVal := cty.ObjectVal(map[string]cty.Value{
|
|
"secrets": cty.MapVal(ctySecretsMap),
|
|
})
|
|
|
|
return outputVal, nil
|
|
}
|