// Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: BUSL-1.1 package configvagrant import ( "github.com/hashicorp/go-argmapper" "github.com/hashicorp/go-hclog" sdk "github.com/hashicorp/vagrant-plugin-sdk" "github.com/hashicorp/vagrant-plugin-sdk/component" "github.com/hashicorp/vagrant-plugin-sdk/core" "github.com/hashicorp/vagrant-plugin-sdk/terminal" ) var CommandOptions = []sdk.Option{ sdk.WithComponents( &Config{}, ), sdk.WithComponent(&Command{}, &component.CommandOptions{Primary: false}), sdk.WithName("configvagrant"), } type Vagrant struct { Sensitive []string `hcl:"sensitive,optional" json:",omitempty"` Host *string `hcl:"host,optional" json:"host,omitempty"` FinalizedInfo *string `hcl:"finalized_info,optional" json:"finalized_info,omitempty"` Plugins []Plugin `hcl:"plugins,block" json:"plugins,omitempty"` } type Plugin struct { Name string `hcl:"name,label"` EntryPoint *string `hcl:"entry_point,optional" json:"entry_point,omitempty"` Sources []string `hcl:"sources,optional" json:"source,omitempty"` Version *string `hcl:"version,optional" json:"version,omitempty"` } type Config struct{} func (c *Config) Register() (*component.ConfigRegistration, error) { return &component.ConfigRegistration{ Identifier: "vagrants", }, nil } func (c *Config) InitFunc() any { return c.Init } func (c *Config) Init(in *component.ConfigData) (*component.ConfigData, error) { return in, nil } func (c *Config) StructFunc() interface{} { return c.Struct } func (c *Config) Struct() *Vagrant { return &Vagrant{} } func (c *Config) MergeFunc() interface{} { return c.Merge } func (c *Config) Merge( input struct { argmapper.Struct Base *Vagrant Overlay *Vagrant Log hclog.Logger }, ) (*Vagrant, error) { log := input.Log log.Info("merging config values in vagrants namespace", "base", input.Base, "overlay", input.Overlay) result := input.Base if input.Overlay.Host != nil { result.Host = input.Overlay.Host } for _, s := range input.Overlay.Sensitive { result.Sensitive = append(result.Sensitive, s) } log.Info("merged config value for vagrants namespace", "config", result) return result, nil } func (c *Config) FinalizeFunc() interface{} { return c.Finalize } func (c *Config) Finalize(l hclog.Logger, conf *Vagrant) (*Vagrant, error) { l.Warn("checking current content", "host", conf.Host) if conf.Host != nil { l.Warn("checking current value", "host", *conf.Host) } info := "go plugin finalization test content" conf.FinalizedInfo = &info return conf, nil } type Command struct{} func (c *Command) ExecuteFunc(_ []string) interface{} { return c.Execute } func (c *Command) Execute(ui terminal.UI, p core.Project) int32 { ui.Output("Checking for our defined config...") v, err := p.Vagrantfile() if err != nil { ui.Output("Failed to get Vagrantfile instance: %s", err) return 1 } ui.Output("Our vagrantfile value is: %#v", v) conf, err := v.GetConfig("vagrants") if err != nil { ui.Output("failed to get configuration for 'vagrants' namespace: %q", err) return 1 } ui.Output("We got something here!") ui.Output("Config defined host: %s", conf.Data["host"]) if _, ok := conf.Data["finalized"]; !ok { ui.Output("ERROR: finalized data expected and not found in config!") } if _, ok := conf.Data["merged"]; !ok { ui.Output("ERROR: merged data expected and not found in config!") return 1 } return 0 } func (c *Command) CommandInfoFunc() interface{} { return c.CommandInfo } func (c *Command) CommandInfo() *component.CommandInfo { return &component.CommandInfo{ Name: "configvagrant", Help: "I display config", } }