Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set CLI options from VSO_ environment variables #551

Merged
merged 3 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/hashicorp/hcp-sdk-go v0.65.0
github.com/hashicorp/vault/api v1.10.0
github.com/hashicorp/vault/sdk v0.10.2
github.com/kelseyhightower/envconfig v1.4.0
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.30.0
github.com/prometheus/client_golang v1.18.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
Expand Down
39 changes: 39 additions & 0 deletions internal/options/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package options

import (
"time"

"github.com/kelseyhightower/envconfig"
)

// VSOEnvOptions are the supported environment variable options, prefixed with VSO.
// The names of the variables in the struct are split using camel case:
// Specification.ClientCacheSize = VSO_CLIENT_CACHE_SIZE
type VSOEnvOptions struct {
// OutputFormat is the VSO_OUTPUT_FORMAT environment variable option
OutputFormat string `split_words:"true"`

// ClientCacheSize is the VSO_CLIENT_CACHE_SIZE environment variable option
ClientCacheSize *int `split_words:"true"`

// ClientCachePersistenceModel is the VSO_CLIENT_CACHE_PERSISTENCE_MODEL
// environment variable option
ClientCachePersistenceModel string `split_words:"true"`

// MaxConcurrentReconciles is the VSO_MAX_CONCURRENT_RECONCILES environment variable option
MaxConcurrentReconciles *int `split_words:"true"`

// MaxConcurrentReconcilesVDS is the VSO_MAX_CONCURRENT_RECONCILES_VDS environment variable option
MaxConcurrentReconcilesVDS *int `split_words:"true"`
tvoran marked this conversation as resolved.
Show resolved Hide resolved

// MinRefreshAfterHVSA is the VSO_MIN_REFRESH_AFTER_HVSA environment variable option
MinRefreshAfterHVSA time.Duration `envconfig:"min_refresh_after_hvsa"`
tvoran marked this conversation as resolved.
Show resolved Hide resolved
}

// Parse environment variable options, prefixed with "VSO_"
func (c *VSOEnvOptions) Parse() error {
return envconfig.Process("vso", c)
}
64 changes: 64 additions & 0 deletions internal/options/env_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package options

import (
"os"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestParse(t *testing.T) {
tests := map[string]struct {
envs map[string]string
wantOptions VSOEnvOptions
}{
"empty": {
envs: map[string]string{},
wantOptions: VSOEnvOptions{},
},
"set all": {
envs: map[string]string{
"VSO_OUTPUT_FORMAT": "json",
"VSO_CLIENT_CACHE_SIZE": "100",
"VSO_CLIENT_CACHE_PERSISTENCE_MODEL": "memory",
"VSO_MAX_CONCURRENT_RECONCILES": "10",
"VSO_MAX_CONCURRENT_RECONCILES_VDS": "20",
"VSO_MIN_REFRESH_AFTER_HVSA": "1h",
},
wantOptions: VSOEnvOptions{
OutputFormat: "json",
ClientCacheSize: makeInt(t, 100),
ClientCachePersistenceModel: "memory",
MaxConcurrentReconciles: makeInt(t, 10),
MaxConcurrentReconcilesVDS: makeInt(t, 20),
MinRefreshAfterHVSA: 1 * time.Hour,
},
},
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
defer func() {
for env := range tt.envs {
require.NoError(t, os.Unsetenv(env))
}
}()
for env, val := range tt.envs {
require.NoError(t, os.Setenv(env, val))
}

gotOptions := VSOEnvOptions{}
require.NoError(t, gotOptions.Parse())
assert.Equal(t, tt.wantOptions, gotOptions)
})
}
}

func makeInt(t *testing.T, i int) *int {
t.Helper()
return &i
}
30 changes: 29 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/hashicorp/vault-secrets-operator/controllers"
"github.com/hashicorp/vault-secrets-operator/internal/helpers"
"github.com/hashicorp/vault-secrets-operator/internal/metrics"
"github.com/hashicorp/vault-secrets-operator/internal/options"
vclient "github.com/hashicorp/vault-secrets-operator/internal/vault"
"github.com/hashicorp/vault-secrets-operator/internal/version"
//+kubebuilder:scaffold:imports
Expand Down Expand Up @@ -67,6 +68,7 @@ func main() {
cfc := vclient.DefaultCachingClientFactoryConfig()
startTime := time.Now()

var vsoEnvOptions options.VSOEnvOptions
var metricsAddr string
var enableLeaderElection bool
var probeAddr string
Expand Down Expand Up @@ -106,6 +108,32 @@ func main() {
opts.BindFlags(flag.CommandLine)
flag.Parse()

// Parse environment variable options, prefixed with "VSO_"
if err := vsoEnvOptions.Parse(); err != nil {
os.Stderr.WriteString(fmt.Sprintf("Failed to process environment variable options: %q\n", err))
os.Exit(1)
}

// Set options from env if any are set
if vsoEnvOptions.OutputFormat != "" {
tvoran marked this conversation as resolved.
Show resolved Hide resolved
outputFormat = vsoEnvOptions.OutputFormat
}
if vsoEnvOptions.ClientCacheSize != nil {
cfc.ClientCacheSize = *vsoEnvOptions.ClientCacheSize
}
if vsoEnvOptions.ClientCachePersistenceModel != "" {
clientCachePersistenceModel = vsoEnvOptions.ClientCachePersistenceModel
}
if vsoEnvOptions.MaxConcurrentReconciles != nil {
controllerOptions.MaxConcurrentReconciles = *vsoEnvOptions.MaxConcurrentReconciles
}
if vsoEnvOptions.MaxConcurrentReconcilesVDS != nil {
vdsOptions.MaxConcurrentReconciles = *vsoEnvOptions.MaxConcurrentReconcilesVDS
}
if vsoEnvOptions.MinRefreshAfterHVSA != 0 {
minRefreshAfterHVSA = vsoEnvOptions.MinRefreshAfterHVSA
}

// versionInfo is used when setting up the buildInfo metric below
versionInfo := version.Version()
if printVersion {
Expand Down Expand Up @@ -214,7 +242,7 @@ func main() {
cfc.Persist = false
default:
setupLog.Error(errors.New("invalid option"),
fmt.Sprintf("Invalid cache pesistence model %q", clientCachePersistenceModel))
fmt.Sprintf("Invalid cache persistence model %q", clientCachePersistenceModel))
os.Exit(1)
}

Expand Down