diff --git a/build b/build index f910b30d..5ec2d4e9 160000 --- a/build +++ b/build @@ -1 +1 @@ -Subproject commit f910b30d0cab58583479ad3a4a6754fb142ebd10 +Subproject commit 5ec2d4e989e04d5a3db0ca5e6db2def0efd254c3 diff --git a/go.mod b/go.mod index beb2186b..cad0b95d 100644 --- a/go.mod +++ b/go.mod @@ -17,11 +17,11 @@ require ( github.com/spectrocloud-labs/prompts-tui v0.1.2 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 - github.com/validator-labs/validator v0.1.9 + github.com/validator-labs/validator v0.1.10 github.com/validator-labs/validator-plugin-aws v0.1.7 github.com/validator-labs/validator-plugin-azure v0.0.20 github.com/validator-labs/validator-plugin-maas v0.0.12 - github.com/validator-labs/validator-plugin-network v0.0.26 + github.com/validator-labs/validator-plugin-network v0.1.0 github.com/validator-labs/validator-plugin-oci v0.3.3 github.com/validator-labs/validator-plugin-vsphere v0.0.34 github.com/vmware/govmomi v0.42.0 diff --git a/go.sum b/go.sum index 03e30d1b..1fa8db3c 100644 --- a/go.sum +++ b/go.sum @@ -862,16 +862,16 @@ github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4= github.com/transparency-dev/merkle v0.0.2/go.mod h1:pqSy+OXefQ1EDUVmAJ8MUhHB9TXGuzVAT58PqBoHz1A= -github.com/validator-labs/validator v0.1.9 h1:jFFp0ovfkdmYBR+FFEQNsc6G7SDj3YMiB/X+nFXPTd0= -github.com/validator-labs/validator v0.1.9/go.mod h1:jErFY8zdH1b1jsRCjpI/RKTDphaE0bXRwKpSqTytz9w= +github.com/validator-labs/validator v0.1.10 h1:0jj6urk4Vp6rNOh3i11qOjoglLmkUvAH3aqDtJ4aFKI= +github.com/validator-labs/validator v0.1.10/go.mod h1:HHozEO20mmN+TtU5zOD9Rw8tVU9pSHXkJrJAs+WH/XQ= github.com/validator-labs/validator-plugin-aws v0.1.7 h1:0/lxM8vhW8+WI4sahc93bSIzXF4rumB4x3VgzegDmgI= github.com/validator-labs/validator-plugin-aws v0.1.7/go.mod h1:UTKVDALO3RupW5XKYWNAf97mN8hlx7qv2iR7rkYCzc8= github.com/validator-labs/validator-plugin-azure v0.0.20 h1:+jbwDSPg0KPmoLkXuQsjf9GEY3Ujz1Lth25ytLJeFWs= github.com/validator-labs/validator-plugin-azure v0.0.20/go.mod h1:l4K344bZG1biNHRHEAMDTKuRFkcRRfrfPXj6pqp4N5c= github.com/validator-labs/validator-plugin-maas v0.0.12 h1:MO6F/uDNryrSV2x6prV+Hp4DFKE6ml8XSicNMmRhSrA= github.com/validator-labs/validator-plugin-maas v0.0.12/go.mod h1:pbwTdZQNlfhoWF4pTucZxoKOflM35pJR3HuIBKNELbE= -github.com/validator-labs/validator-plugin-network v0.0.26 h1:IZKxJsFoAZxrEIrMwGAVt0dCrEJMi9VMRoeAfVRB1mc= -github.com/validator-labs/validator-plugin-network v0.0.26/go.mod h1:dCaAADawusvEWJppwebOzZXcH5vmF/QvysNVo6s7Se8= +github.com/validator-labs/validator-plugin-network v0.1.0 h1:Z/2b/5lMRxssRWHAUHPJi6bfmsTzfJpi+tpXEgrOVJ0= +github.com/validator-labs/validator-plugin-network v0.1.0/go.mod h1:AddRLweCYC+MkLu70P0H2+th+wdZjtEZKhkINSy7Wdw= github.com/validator-labs/validator-plugin-oci v0.3.3 h1:O7pkKjYc78UX9ffjo+qMRZGWaYuSXPVjmfRvvNtpC50= github.com/validator-labs/validator-plugin-oci v0.3.3/go.mod h1:ZhN/Jsc2KP0zSQBfj5yHmj1xPCt3/ulo5ab6O3GnJZw= github.com/validator-labs/validator-plugin-vsphere v0.0.34 h1:AAujEYmGtnHcwLIff15IzC6tcXkaCc9HyCoGdG2Ofis= diff --git a/pkg/cmd/validator/validator.go b/pkg/cmd/validator/validator.go index 9da5e049..46acad70 100644 --- a/pkg/cmd/validator/validator.go +++ b/pkg/cmd/validator/validator.go @@ -25,21 +25,29 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" awsapi "github.com/validator-labs/validator-plugin-aws/api/v1alpha1" + awsconst "github.com/validator-labs/validator-plugin-aws/pkg/constants" awsval "github.com/validator-labs/validator-plugin-aws/pkg/validate" azureapi "github.com/validator-labs/validator-plugin-azure/api/v1alpha1" + azureconst "github.com/validator-labs/validator-plugin-azure/pkg/constants" azureval "github.com/validator-labs/validator-plugin-azure/pkg/validate" maasapi "github.com/validator-labs/validator-plugin-maas/api/v1alpha1" + maasconst "github.com/validator-labs/validator-plugin-maas/pkg/constants" maasval "github.com/validator-labs/validator-plugin-maas/pkg/validate" + netapi "github.com/validator-labs/validator-plugin-network/api/v1alpha1" + netconst "github.com/validator-labs/validator-plugin-network/pkg/constants" netval "github.com/validator-labs/validator-plugin-network/pkg/validate" ociapi "github.com/validator-labs/validator-plugin-oci/api/v1alpha1" ociauth "github.com/validator-labs/validator-plugin-oci/pkg/auth" + ociconst "github.com/validator-labs/validator-plugin-oci/pkg/constants" ocic "github.com/validator-labs/validator-plugin-oci/pkg/ociclient" ocival "github.com/validator-labs/validator-plugin-oci/pkg/validate" vsphereapi "github.com/validator-labs/validator-plugin-vsphere/api/v1alpha1" + vsphereconst "github.com/validator-labs/validator-plugin-vsphere/pkg/constants" vsphereval "github.com/validator-labs/validator-plugin-vsphere/pkg/validate" vapi "github.com/validator-labs/validator/api/v1alpha1" "github.com/validator-labs/validator/pkg/helm" + "github.com/validator-labs/validator/pkg/plugins" "github.com/validator-labs/validator/pkg/sinks" "github.com/validator-labs/validator/pkg/types" vres "github.com/validator-labs/validator/pkg/validationresult" @@ -241,7 +249,7 @@ func ConfigureOrCheckCommand(c *cfg.Config, tc *cfg.TaskConfig) error { } if tc.Direct { - return executePlugins(c, vc) + return executePlugins(c, pluginSpecs(vc), vc.SinkConfig) } // upgrade the validator helm release so that plugin rule secrets @@ -260,6 +268,29 @@ func ConfigureOrCheckCommand(c *cfg.Config, tc *cfg.TaskConfig) error { return nil } +func pluginSpecs(vc *components.ValidatorConfig) []plugins.PluginSpec { + pluginSpecs := make([]plugins.PluginSpec, 0) + if vc.AWSPlugin != nil && vc.AWSPlugin.Enabled { + pluginSpecs = append(pluginSpecs, vc.AWSPlugin.Validator) + } + if vc.AzurePlugin != nil && vc.AzurePlugin.Enabled { + pluginSpecs = append(pluginSpecs, vc.AzurePlugin.Validator) + } + if vc.MaasPlugin != nil && vc.MaasPlugin.Enabled { + pluginSpecs = append(pluginSpecs, vc.MaasPlugin.Validator) + } + if vc.NetworkPlugin != nil && vc.NetworkPlugin.Enabled { + pluginSpecs = append(pluginSpecs, vc.NetworkPlugin.Validator) + } + if vc.OCIPlugin != nil && vc.OCIPlugin.Enabled { + pluginSpecs = append(pluginSpecs, vc.OCIPlugin.Validator) + } + if vc.VspherePlugin != nil && vc.VspherePlugin.Enabled { + pluginSpecs = append(pluginSpecs, vc.VspherePlugin.Validator) + } + return pluginSpecs +} + // UpgradeValidatorCommand upgrades validator and its plugins func UpgradeValidatorCommand(c *cfg.Config, tc *cfg.TaskConfig) error { vc, err := components.NewValidatorFromConfig(tc) @@ -420,7 +451,7 @@ func printValidationResults(validationResults []unstructured.Unstructured) error if err != nil { return err } - log.InfoCLI(vrStr) + log.InfoCLI("%s", vrStr) } return nil } @@ -516,7 +547,7 @@ func configurePlugins(c *cfg.Config, vc *components.ValidatorConfig, tc *cfg.Tas } // nolint:gocyclo -func executePlugins(c *cfg.Config, vc *components.ValidatorConfig) error { +func executePlugins(c *cfg.Config, pluginSpecs []plugins.PluginSpec, sc *components.SinkConfig) error { log.Header("Executing validator plugin(s)") // Initialize a new logr.Logger that writes to the same @@ -526,129 +557,143 @@ func executePlugins(c *cfg.Config, vc *components.ValidatorConfig) error { ok := true results := make([]*vapi.ValidationResult, 0) - if vc.AWSPlugin != nil && vc.AWSPlugin.Enabled { - v := &awsapi.AwsValidator{ - ObjectMeta: metav1.ObjectMeta{ - Name: "aws-validator", - Namespace: "N/A", - }, - Spec: *vc.AWSPlugin.Validator, - } - vr := vres.Build(v) - vrr := awsval.Validate(*vc.AWSPlugin.Validator, l) - if err := vres.Finalize(vr, vrr, l); err != nil { - return err - } - if vrOk := validationResponseOk(vc.AWSPlugin.Validator.ResultCount(), vrr, l); !vrOk { - ok = false - } - results = append(results, vr) - } + for _, ps := range pluginSpecs { - if vc.AzurePlugin != nil && vc.AzurePlugin.Enabled { - v := &azureapi.AzureValidator{ - ObjectMeta: metav1.ObjectMeta{ - Name: "azure-validator", - Namespace: "N/A", - }, - Spec: *vc.AzurePlugin.Validator, - } - vr := vres.Build(v) - vrr := azureval.Validate(context.Background(), *vc.AzurePlugin.Validator, l) - if err := vres.Finalize(vr, vrr, l); err != nil { - return err - } - if vrOk := validationResponseOk(vc.AzurePlugin.Validator.ResultCount(), vrr, l); !vrOk { - ok = false - } - results = append(results, vr) - } + switch ps.PluginCode() { + case awsconst.PluginCode: + s := ps.(*awsapi.AwsValidatorSpec) - if vc.MaasPlugin != nil && vc.MaasPlugin.Enabled { - v := &maasapi.MaasValidator{ - ObjectMeta: metav1.ObjectMeta{ - Name: "maas-validator", - Namespace: "N/A", - }, - Spec: *vc.MaasPlugin.Validator, - } - vr := vres.Build(v) - vrr := maasval.Validate(*vc.MaasPlugin.Validator, l) - if err := vres.Finalize(vr, vrr, l); err != nil { - return err - } - if vrOk := validationResponseOk(vc.MaasPlugin.Validator.ResultCount(), vrr, l); !vrOk { - ok = false - } - results = append(results, vr) - } + v := &awsapi.AwsValidator{ + ObjectMeta: metav1.ObjectMeta{ + Name: "aws-validator", + Namespace: "N/A", + }, + Spec: *s, + } - if vc.NetworkPlugin != nil && vc.NetworkPlugin.Enabled { - v := &netapi.NetworkValidator{ - ObjectMeta: metav1.ObjectMeta{ - Name: "network-validator", - Namespace: "N/A", - }, - Spec: *vc.NetworkPlugin.Validator, - } - vr := vres.Build(v) - vrr := netval.Validate(*vc.NetworkPlugin.Validator, - vc.NetworkPlugin.Validator.CACerts.RawCerts(), - vc.NetworkPlugin.HTTPFileAuthBytes(), l, - ) - if err := vres.Finalize(vr, vrr, l); err != nil { - return err - } - if vrOk := validationResponseOk(vc.NetworkPlugin.Validator.ResultCount(), vrr, l); !vrOk { - ok = false - } - results = append(results, vr) - } + vr := vres.Build(v) + vrr := awsval.Validate(*s, l) + if err := vres.Finalize(vr, vrr, l); err != nil { + return err + } + if vrOk := validationResponseOk(s.ResultCount(), vrr, l); !vrOk { + ok = false + } + results = append(results, vr) - if vc.OCIPlugin != nil && vc.OCIPlugin.Enabled { - v := &ociapi.OciValidator{ - ObjectMeta: metav1.ObjectMeta{ - Name: "oci-validator", - Namespace: "N/A", - }, - Spec: *vc.OCIPlugin.Validator, - } - vr := vres.Build(v) - vrr := ocival.Validate(*vc.OCIPlugin.Validator, - vc.OCIPlugin.BasicAuths(), - vc.OCIPlugin.AllPubKeys(), l, - ) - if err := vres.Finalize(vr, vrr, l); err != nil { - return err - } - if vrOk := validationResponseOk(vc.OCIPlugin.Validator.ResultCount(), vrr, l); !vrOk { - ok = false - } - results = append(results, vr) - } + case azureconst.PluginCode: + s := ps.(*azureapi.AzureValidatorSpec) - if vc.VspherePlugin != nil && vc.VspherePlugin.Enabled { - v := &vsphereapi.VsphereValidator{ - ObjectMeta: metav1.ObjectMeta{ - Name: "vsphere-validator", - Namespace: "N/A", - }, - Spec: *vc.VspherePlugin.Validator, - } - vr := vres.Build(v) - vrr := vsphereval.Validate(context.Background(), *vc.VspherePlugin.Validator, vc.VspherePlugin.Validator.Auth.CloudAccount, l) - if err := vres.Finalize(vr, vrr, l); err != nil { - return err - } - if vrOk := validationResponseOk(vc.VspherePlugin.Validator.ResultCount(), vrr, l); !vrOk { - ok = false + v := &azureapi.AzureValidator{ + ObjectMeta: metav1.ObjectMeta{ + Name: "azure-validator", + Namespace: "N/A", + }, + Spec: *s, + } + vr := vres.Build(v) + vrr := azureval.Validate(context.Background(), *s, l) + if err := vres.Finalize(vr, vrr, l); err != nil { + return err + } + if vrOk := validationResponseOk(s.ResultCount(), vrr, l); !vrOk { + ok = false + } + results = append(results, vr) + + case maasconst.PluginCode: + s := ps.(*maasapi.MaasValidatorSpec) + + v := &maasapi.MaasValidator{ + ObjectMeta: metav1.ObjectMeta{ + Name: "maas-validator", + Namespace: "N/A", + }, + Spec: *s, + } + vr := vres.Build(v) + vrr := maasval.Validate(*s, l) + if err := vres.Finalize(vr, vrr, l); err != nil { + return err + } + if vrOk := validationResponseOk(s.ResultCount(), vrr, l); !vrOk { + ok = false + } + results = append(results, vr) + + case netconst.PluginCode: + s := ps.(*netapi.NetworkValidatorSpec) + + v := &netapi.NetworkValidator{ + ObjectMeta: metav1.ObjectMeta{ + Name: "network-validator", + Namespace: "N/A", + }, + Spec: *s, + } + vr := vres.Build(v) + vrr := netval.Validate(*s, + s.CACerts.RawCerts(), + s.HTTPFileAuthBytesDirect(), + l, + ) + if err := vres.Finalize(vr, vrr, l); err != nil { + return err + } + if vrOk := validationResponseOk(s.ResultCount(), vrr, l); !vrOk { + ok = false + } + results = append(results, vr) + + case ociconst.PluginCode: + s := ps.(*ociapi.OciValidatorSpec) + + v := &ociapi.OciValidator{ + ObjectMeta: metav1.ObjectMeta{ + Name: "oci-validator", + Namespace: "N/A", + }, + Spec: *s, + } + vr := vres.Build(v) + vrr := ocival.Validate(*s, + s.DeepCopy().BasicAuthsDirect(), + s.DeepCopy().AllPubKeysDirect(), + l, + ) + if err := vres.Finalize(vr, vrr, l); err != nil { + return err + } + if vrOk := validationResponseOk(s.ResultCount(), vrr, l); !vrOk { + ok = false + } + results = append(results, vr) + + case vsphereconst.PluginCode: + s := ps.(*vsphereapi.VsphereValidatorSpec) + + v := &vsphereapi.VsphereValidator{ + ObjectMeta: metav1.ObjectMeta{ + Name: "vsphere-validator", + Namespace: "N/A", + }, + Spec: *s, + } + vr := vres.Build(v) + vrr := vsphereval.Validate(context.Background(), *s, s.Auth.CloudAccount, l) + if err := vres.Finalize(vr, vrr, l); err != nil { + return err + } + if vrOk := validationResponseOk(s.ResultCount(), vrr, l); !vrOk { + ok = false + } + results = append(results, vr) } - results = append(results, vr) } // Optionally emit results to a sink - if vc.SinkConfig.Enabled { - if err := emitToSink(vc, results, l); err != nil { + if sc != nil && sc.Enabled { + if err := emitToSink(sc, results, l); err != nil { return err } } @@ -719,11 +764,11 @@ func validationResponseOk(expected int, vr types.ValidationResponse, log logr.Lo return true } -func emitToSink(vc *components.ValidatorConfig, results []*vapi.ValidationResult, log logr.Logger) error { - sink := sinks.NewSink(types.SinkType(vc.SinkConfig.Type), log) +func emitToSink(sc *components.SinkConfig, results []*vapi.ValidationResult, log logr.Logger) error { + sink := sinks.NewSink(types.SinkType(sc.Type), log) - sinkConfig := make(map[string][]byte, len(vc.SinkConfig.Values)) - for k, v := range vc.SinkConfig.Values { + sinkConfig := make(map[string][]byte, len(sc.Values)) + for k, v := range sc.Values { sinkConfig[k] = []byte(v) } @@ -902,7 +947,7 @@ func applyValidator(c *cfg.Config, vc *components.ValidatorConfig) error { values = append(values, pluginValues...) finalValues := string(values) log.Debug("applying validator helm chart with values:") - log.Debug(finalValues) + log.Debug("%s", finalValues) // install validator helm chart @@ -917,7 +962,7 @@ func applyValidator(c *cfg.Config, vc *components.ValidatorConfig) error { if !strings.HasSuffix(strings.TrimSpace(stderr), "already exists") { return errors.Wrap(err, stderr) } - log.Debug(stderr) + log.Debug("%s", stderr) } } } diff --git a/pkg/components/validator.go b/pkg/components/validator.go index 4855f728..a1600198 100644 --- a/pkg/components/validator.go +++ b/pkg/components/validator.go @@ -443,22 +443,6 @@ func (c *NetworkPluginConfig) AddDummyHTTPFileAuth() { c.HTTPFileAuths = append(c.HTTPFileAuths, []string{"", ""}) } -// HTTPFileAuthBytes converts a slice of basic authentication details from -// a [][]string to a [][][]byte. The former is required for YAML marshalling, -// encryption, and decryption, while the latter is required by the plugin's -// Validate method. -// TODO: refactor Network plugin to use [][]string. -func (c *NetworkPluginConfig) HTTPFileAuthBytes() [][][]byte { - auths := make([][][]byte, len(c.HTTPFileAuths)) - for i, auth := range c.HTTPFileAuths { - auths[i] = [][]byte{ - []byte(auth[0]), - []byte(auth[1]), - } - } - return auths -} - func (c *NetworkPluginConfig) encrypt() error { if c.HTTPFileAuths == nil { return nil @@ -501,47 +485,6 @@ type OCIPluginConfig struct { Validator *oci.OciValidatorSpec `yaml:"validator"` } -// BasicAuths returns a slice of basic authentication details for each rule. -func (c *OCIPluginConfig) BasicAuths() map[string][]string { - auths := make(map[string][]string, 0) - - for _, r := range c.Validator.OciRegistryRules { - if r.Auth.SecretName != nil { - for _, s := range c.Secrets { - if s.Name != *r.Auth.SecretName { - continue - } - - if s.BasicAuth != nil { - auths[r.Name()] = []string{s.BasicAuth.Username, s.BasicAuth.Password} - } - } - continue - } - - if r.Auth.Basic != nil { - auths[r.Name()] = []string{r.Auth.Basic.Username, r.Auth.Basic.Password} - continue - } - } - - return auths -} - -// AllPubKeys returns a slice of public keys for each public key secret. -func (c *OCIPluginConfig) AllPubKeys() map[string][][]byte { - pubKeys := make(map[string][][]byte, len(c.PublicKeySecrets)) - for _, s := range c.PublicKeySecrets { - s := s - keys := make([][]byte, len(s.Keys)) - for i, k := range s.Keys { - keys[i] = []byte(k) - } - pubKeys[s.Name] = keys - } - return pubKeys -} - func (c *OCIPluginConfig) encrypt() error { for _, s := range c.Secrets { if s != nil { diff --git a/pkg/services/env_service.go b/pkg/services/env_service.go index e22bae00..24898baf 100644 --- a/pkg/services/env_service.go +++ b/pkg/services/env_service.go @@ -258,7 +258,7 @@ func ensureDockerCACertDir(path string) error { cmd := exec.Command("sudo", "rm", "-f", path) //#nosec G204 _, stderr, err := exec_utils.Execute(true, cmd) if err != nil { - return errors.Wrapf(err, stderr) + return errors.Wrap(err, stderr) } return createDockerCACertDir(path) } @@ -269,7 +269,7 @@ func createDockerCACertDir(path string) error { cmd := exec.Command("sudo", "mkdir", "-p", path) //#nosec G204 _, stderr, err := exec_utils.Execute(true, cmd) if err != nil { - return errors.Wrapf(err, stderr) + return errors.Wrap(err, stderr) } log.InfoCLI("Created Docker OCI CA certificate directory: %s", path) return nil diff --git a/pkg/services/validator/network.go b/pkg/services/validator/network.go index ca99c31f..918b3a94 100644 --- a/pkg/services/validator/network.go +++ b/pkg/services/validator/network.go @@ -550,8 +550,14 @@ func readHTTPFileRule(c *components.NetworkPluginConfig, tc *cfg.TaskConfig, r * return err } if configureAuth { - if err := readHTTPFileRuleCredentials(c, tc, r, idx, kClient); err != nil { - return err + if tc.Direct { + if err := readHTTPFileRuleCredentialsInline(r); err != nil { + return err + } + } else { + if err := readHTTPFileRuleCredentialsSecret(c, r, idx, kClient); err != nil { + return err + } } } else { c.AddDummyHTTPFileAuth() @@ -568,13 +574,15 @@ func readHTTPFileRule(c *components.NetworkPluginConfig, tc *cfg.TaskConfig, r * return nil } -func readHTTPFileRuleCredentials(c *components.NetworkPluginConfig, tc *cfg.TaskConfig, r *network.HTTPFileRule, idx int, kClient kubernetes.Interface) error { +// readHTTPFileRuleCredentialsSecret prompts the user to configure secrets containing their authentication details. +func readHTTPFileRuleCredentialsSecret(c *components.NetworkPluginConfig, r *network.HTTPFileRule, idx int, kClient kubernetes.Interface) error { var err error var username, password string createSecret := true - if r.AuthSecretRef == nil { - r.AuthSecretRef = &network.BasicAuthSecretReference{} + r.Auth.Basic = nil + if r.Auth.SecretRef == nil { + r.Auth.SecretRef = &network.BasicAuthSecretReference{} } if idx == -1 { // preallocate space if appending a new rule @@ -600,14 +608,12 @@ func readHTTPFileRuleCredentials(c *components.NetworkPluginConfig, tc *cfg.Task } if createSecret { - if !tc.Direct { - r.AuthSecretRef.Name, err = prompts.ReadK8sName("Secret name for basic authentication", r.AuthSecretRef.Name, false) - if err != nil { - return err - } + r.Auth.SecretRef.Name, err = prompts.ReadK8sName("Secret name for basic authentication", r.Auth.SecretRef.Name, false) + if err != nil { + return err } - r.AuthSecretRef.UsernameKey = "username" - r.AuthSecretRef.PasswordKey = "password" + r.Auth.SecretRef.UsernameKey = "username" + r.Auth.SecretRef.PasswordKey = "password" username, password, err = prompts.ReadBasicCreds("Username", "Password", username, password, false, false) if err != nil { @@ -615,11 +621,11 @@ func readHTTPFileRuleCredentials(c *components.NetworkPluginConfig, tc *cfg.Task } c.HTTPFileAuths[idx] = []string{username, password} } else { - usernameKey, err := prompts.ReadText("Key for username in secret", r.AuthSecretRef.UsernameKey, false, -1) + usernameKey, err := prompts.ReadText("Key for username in secret", r.Auth.SecretRef.UsernameKey, false, -1) if err != nil { return err } - passwordKey, err := prompts.ReadText("Key for password in secret", r.AuthSecretRef.PasswordKey, false, -1) + passwordKey, err := prompts.ReadText("Key for password in secret", r.Auth.SecretRef.PasswordKey, false, -1) if err != nil { return err } @@ -627,9 +633,25 @@ func readHTTPFileRuleCredentials(c *components.NetworkPluginConfig, tc *cfg.Task if err != nil { return err } - r.AuthSecretRef.Name = secret.Name - r.AuthSecretRef.UsernameKey = usernameKey - r.AuthSecretRef.PasswordKey = passwordKey + r.Auth.SecretRef.Name = secret.Name + r.Auth.SecretRef.UsernameKey = usernameKey + r.Auth.SecretRef.PasswordKey = passwordKey + } + + return nil +} + +// readHTTPFileRuleCredentialsInline prompts the user to configure their authentication details. +func readHTTPFileRuleCredentialsInline(r *network.HTTPFileRule) error { + r.Auth.SecretRef = nil + if r.Auth.Basic == nil { + r.Auth.Basic = &network.BasicAuth{} + } + + var err error + r.Auth.Basic.Username, r.Auth.Basic.Password, err = prompts.ReadBasicCreds("Username", "Password", r.Auth.Basic.Username, r.Auth.Basic.Password, false, false) + if err != nil { + return err } return nil diff --git a/pkg/services/validator/oci.go b/pkg/services/validator/oci.go index 4de95e8f..12c99621 100644 --- a/pkg/services/validator/oci.go +++ b/pkg/services/validator/oci.go @@ -52,8 +52,8 @@ func readOciPluginRules(vc *components.ValidatorConfig, tc *cfg.TaskConfig, kCli return nil } -// configureAuth prompts the user to configure their OCI registry authentication details. -func configureAuth(r *plug.OciRegistryRule) error { +// configureAuthInline prompts the user to configure their OCI registry authentication details. +func configureAuthInline(r *plug.OciRegistryRule) error { r.Auth.SecretName = nil authType, err := prompts.Select("Authentication type", []string{basicAuth, ecrAuth}) @@ -124,6 +124,19 @@ func configureAuthSecrets(c *components.OCIPluginConfig, r *plug.OciRegistryRule return nil } +// configureSigVerification prompts the user to configure their public keys for signature verification. +func configureSigVerification(r *plug.OciRegistryRule) error { + r.SignatureVerification.SecretName = "" + + pubKeys, err := configurePublicKeys() + if err != nil { + return err + } + + r.SignatureVerification.PublicKeys = pubKeys + return nil +} + // configureSigVerificationSecrets prompts the user to configure secrets containing public keys for use in signature verification. func configureSigVerificationSecrets(c *components.OCIPluginConfig, r *plug.OciRegistryRule, kClient kubernetes.Interface, sigSecretNames *[]string) error { allSecretNames := []string{cfg.OciCreateNewSigSecPrompt} // provide the option to create a new secret @@ -175,28 +188,38 @@ func readPublicKeySecret(secret *components.PublicKeySecret) error { log.InfoCLI("Reconfiguring secret: %s", secret.Name) } + pubKeys, err := configurePublicKeys() + if err != nil { + return err + } + + secret.Keys = pubKeys + return nil +} + +// configurePublicKeys prompts the user to configure a list of public keys. +func configurePublicKeys() ([]string, error) { pubKeys := make([]string, 0) for { pubKeyPath, err := prompts.ReadFilePath("Public Key file", "", "Invalid public key path", false) if err != nil { - return err + return nil, err } pubKeyBytes, err := os.ReadFile(pubKeyPath) //#nosec if err != nil { - return err + return nil, err } pubKeys = append(pubKeys, string(pubKeyBytes)) - add, err := prompts.ReadBool("Add another public key to this secret", false) + add, err := prompts.ReadBool("Add another public key", false) if err != nil { - return err + return nil, err } if !add { break } } - secret.Keys = pubKeys - return nil + return pubKeys, nil } func configureOciRegistryRules(c *components.OCIPluginConfig, ruleNames, authSecretNames, sigSecretNames *[]string, kClient kubernetes.Interface, direct bool) error { @@ -243,8 +266,7 @@ func configureOciRegistryRules(c *components.OCIPluginConfig, ruleNames, authSec } func readOciRegistryRule(c *components.OCIPluginConfig, r *plug.OciRegistryRule, idx int, ruleNames, authSecretNames, sigSecretNames *[]string, kClient kubernetes.Interface, direct bool) error { - err := initRule(r, "OCI", "", ruleNames) - if err != nil { + if err := initRule(r, "OCI", "", ruleNames); err != nil { return err } @@ -261,13 +283,11 @@ func readOciRegistryRule(c *components.OCIPluginConfig, r *plug.OciRegistryRule, } if shouldConfigureAuth { if direct { - err := configureAuth(r) - if err != nil { + if err := configureAuthInline(r); err != nil { return err } } else { - err := configureAuthSecrets(c, r, kClient, authSecretNames) - if err != nil { + if err := configureAuthSecrets(c, r, kClient, authSecretNames); err != nil { return err } } @@ -291,20 +311,22 @@ func readOciRegistryRule(c *components.OCIPluginConfig, r *plug.OciRegistryRule, } r.ValidationType = plug.ValidationType(vType) - // TODO: Add support for signature verification without a secret for use in direct mode - if !direct { - shouldConfigureSigVerification, err := prompts.ReadBool("Configure signature verification", r.SignatureVerification.SecretName != "") - if err != nil { - return err - } - if shouldConfigureSigVerification { - err := configureSigVerificationSecrets(c, r, kClient, sigSecretNames) - if err != nil { + shouldConfigureSigVerification, err := prompts.ReadBool("Configure signature verification", r.SignatureVerification.SecretName != "") + if err != nil { + return err + } + if shouldConfigureSigVerification { + if direct { + if err := configureSigVerification(r); err != nil { return err } } else { - r.SignatureVerification = plug.SignatureVerification{} + if err := configureSigVerificationSecrets(c, r, kClient, sigSecretNames); err != nil { + return err + } } + } else { + r.SignatureVerification = plug.SignatureVerification{} } if c.CaCertPaths == nil { diff --git a/pkg/services/validator/rule_names.go b/pkg/services/validator/rule_names.go index 6416fde4..e7cac2c1 100644 --- a/pkg/services/validator/rule_names.go +++ b/pkg/services/validator/rule_names.go @@ -15,7 +15,7 @@ func initRule(rule validationrule.Interface, ruleType, message string, ruleNames if name != "" { log.InfoCLI("\nReconfiguring %s rule: %s", ruleType, name) if message != "" { - log.InfoCLI(message) + log.InfoCLI("%s", message) } *ruleNames = append(*ruleNames, name) diff --git a/pkg/utils/exec/exec.go b/pkg/utils/exec/exec.go index 32f57882..cd933356 100644 --- a/pkg/utils/exec/exec.go +++ b/pkg/utils/exec/exec.go @@ -84,7 +84,7 @@ type logWriter struct { } func (l *logWriter) Write(p []byte) (n int, err error) { - log.InfoCLI(string(p)) + log.InfoCLI("%s", string(p)) return l.buffer.Write(p) } diff --git a/pkg/utils/kube/kube.go b/pkg/utils/kube/kube.go index 601b8c3c..e6a49fa6 100644 --- a/pkg/utils/kube/kube.go +++ b/pkg/utils/kube/kube.go @@ -39,7 +39,7 @@ func KubectlCommand(params []string, kConfig string) (out, stderr string, err er log.InfoCLI("\n==== Kubectl Command ==== Create Secret") } else { log.InfoCLI("\n==== Kubectl Command ====") - log.InfoCLI(cmd.String()) + log.InfoCLI("%s", cmd.String()) } out, stderr, err = exec_utils.Execute(true, cmd) diff --git a/tests/integration/_validator/testcases/test_validator.go b/tests/integration/_validator/testcases/test_validator.go index 39f5ba39..f4f72e0d 100644 --- a/tests/integration/_validator/testcases/test_validator.go +++ b/tests/integration/_validator/testcases/test_validator.go @@ -214,7 +214,7 @@ func (t *ValidatorTest) awsPluginInstallValues(ctx *test.TestContext, vals []str "y", // enable AWS plugin "n", // use implicit auth "aws-creds", // AWS secret name - "secretkey", // AWS Secret Key ID + "accesskey", // AWS Access Key ID "secretaccesskey", // AWS Secret Access Key "", // AWS Session Token "y", // Configure STS