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

feat: on validate command, validate that all secrets are tagged #695

Merged
merged 1 commit into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
30 changes: 29 additions & 1 deletion cloudconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cloudconfig
import (
"fmt"
"io"
"os"
"text/tabwriter"
)

Expand Down Expand Up @@ -49,9 +50,18 @@ type configSpec struct {
// Load values into the config.
func (c *Config) Load() error {
if c.yamlServiceSpecificationFilename != "" {
if err := setEnvFromYAMLServiceSpecificationFile(c.yamlServiceSpecificationFilename); err != nil {
envs, err := getEnvFromYAMLServiceSpecificationFile(c.yamlServiceSpecificationFilename)
if err != nil {
return err
}
if err := validateEnvSecretTags(envs, c.configSpecs); err != nil {
return err
}
for _, e := range envs {
if err := os.Setenv(e.Name, e.Value); err != nil {
return err
}
}
}
for _, cs := range c.configSpecs {
if err := c.process(cs.fieldSpecs); err != nil {
Expand All @@ -61,6 +71,24 @@ func (c *Config) Load() error {
return nil
}

func validateEnvSecretTags(envs []env, configSpecs []*configSpec) error {
for _, env := range envs {
if env.ValueFrom.SecretKeyRef.Key == "" && env.ValueFrom.SecretKeyRef.Name == "" {
continue
}
for _, spec := range configSpecs {
for _, f := range spec.fieldSpecs {
if f.Key == env.Name {
if !f.Secret {
return fmt.Errorf("field %s does not have the correct secret tag", f.Name)
}
}
}
}
}
return nil
}

// PrintUsage prints usage of the config to the provided io.Writer.
func (c *Config) PrintUsage(w io.Writer) {
tabs := tabwriter.NewWriter(w, 1, 0, 4, ' ', 0)
Expand Down
42 changes: 24 additions & 18 deletions cloudconfig/yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,18 @@ import (
"gopkg.in/yaml.v3"
)

func setEnvFromYAMLServiceSpecificationFile(name string) (err error) {
type env struct {
Name string
Value string
ValueFrom struct {
SecretKeyRef struct {
Key string
Name string
} `yaml:"secretKeyRef"`
} `yaml:"valueFrom"`
}

func getEnvFromYAMLServiceSpecificationFile(name string) (envValues []env, err error) {
defer func() {
if err != nil {
err = fmt.Errorf("set env from YAML service/job specification file %s: %w", name, err)
Expand All @@ -17,16 +28,12 @@ func setEnvFromYAMLServiceSpecificationFile(name string) (err error) {
var kind struct {
Kind string
}
type env struct {
Name string
Value string
}
data, err := os.ReadFile(name)
if err != nil {
return err
return nil, err
}
if err := yaml.NewDecoder(bytes.NewReader(data)).Decode(&kind); err != nil {
return err
return nil, err
}
var envs []env
switch kind.Kind {
Expand All @@ -46,15 +53,15 @@ func setEnvFromYAMLServiceSpecificationFile(name string) (err error) {
}
}
if err := yaml.NewDecoder(bytes.NewReader(data)).Decode(&config); err != nil {
return err
return nil, err
}
containers := config.Spec.Template.Spec.Containers
if len(containers) == 0 || len(containers) > 10 {
return fmt.Errorf("unexpected number of containers: %d", len(containers))
return nil, fmt.Errorf("unexpected number of containers: %d", len(containers))
}
if config.Metadata.Name != "" {
if err := os.Setenv("K_SERVICE", config.Metadata.Name); err != nil {
return err
return nil, err
}
}
envs = containers[0].Env
Expand All @@ -78,28 +85,27 @@ func setEnvFromYAMLServiceSpecificationFile(name string) (err error) {
}
}
if err := yaml.NewDecoder(bytes.NewReader(data)).Decode(&config); err != nil {
return err
return nil, err
}
containers := config.Spec.Template.Spec.Template.Spec.Containers
if len(containers) == 0 || len(containers) > 10 {
return fmt.Errorf("unexpected number of containers: %d", len(containers))
return nil, fmt.Errorf("unexpected number of containers: %d", len(containers))
}
if config.Metadata.Name != "" {
if err := os.Setenv("K_SERVICE", config.Metadata.Name); err != nil {
return err
return nil, err
}
}
envs = containers[0].Env
default:
return fmt.Errorf("unknown config kind: %s", kind.Kind)
return nil, fmt.Errorf("unknown config kind: %s", kind.Kind)
}
envValues = make([]env, 0, len(envs))
for _, env := range envs {
// Prefer variables from local environment.
if _, ok := os.LookupEnv(env.Name); !ok {
if err := os.Setenv(env.Name, env.Value); err != nil {
return err
}
envValues = append(envValues, env)
}
}
return nil
return envValues, nil
}
5 changes: 4 additions & 1 deletion run.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ func Run(fn func(context.Context) error, options ...Option) (err error) {
)
}
if *validate {
run.configOptions = append(run.configOptions, cloudconfig.WithOptionalSecrets())
run.configOptions = append(
run.configOptions,
cloudconfig.WithOptionalSecrets(),
)
}
config, err := cloudconfig.New("cloudrunner", &run.config, run.configOptions...)
if err != nil {
Expand Down