From 1b5ce091850e689dc8794413ce5a9b673dd07990 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 30 Nov 2023 15:34:26 +0100 Subject: [PATCH] new(cmd/driver,pkg/options,internal/config): added `driver config` command tests. Signed-off-by: Federico Di Pierro --- cmd/driver/config/config.go | 5 +- cmd/driver/config/config_suite_test.go | 69 ++++++++++++++++++++++ cmd/driver/config/config_test.go | 82 ++++++++++++++++++++++++++ cmd/driver/printenv/printenv.go | 5 +- internal/config/config.go | 8 ++- pkg/options/driver.go | 6 +- 6 files changed, 170 insertions(+), 5 deletions(-) create mode 100644 cmd/driver/config/config_suite_test.go create mode 100644 cmd/driver/config/config_test.go diff --git a/cmd/driver/config/config.go b/cmd/driver/config/config.go index e0068dd6..818bc3a6 100644 --- a/cmd/driver/config/config.go +++ b/cmd/driver/config/config.go @@ -158,7 +158,10 @@ func (o *driverConfigOptions) RunDriverConfig(ctx context.Context, cmd *cobra.Co d, err := driverdistro.Discover(info, driverCfg.HostRoot) if err != nil { - return err + if !errors.Is(err, driverdistro.ErrUnsupported) { + return err + } + o.Printer.Logger.Info("Detected an unsupported target system; falling back at generic logic.") } o.Printer.Logger.Debug("Discovered distro", o.Printer.Logger.Args("target", d)) diff --git a/cmd/driver/config/config_suite_test.go b/cmd/driver/config/config_suite_test.go new file mode 100644 index 00000000..ce2e80c3 --- /dev/null +++ b/cmd/driver/config/config_suite_test.go @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (C) 2023 The Falco Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package driverconfig_test + +import ( + "context" + "os" + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/gbytes" + "github.com/spf13/cobra" + + "github.com/falcosecurity/falcoctl/cmd" + commonoptions "github.com/falcosecurity/falcoctl/pkg/options" + testutils "github.com/falcosecurity/falcoctl/pkg/test" +) + +var ( + ctx = context.Background() + output = gbytes.NewBuffer() + rootCmd *cobra.Command + opt *commonoptions.Common + configFile string + err error + args []string +) + +func TestConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Config Suite") +} + +var _ = BeforeSuite(func() { + + // Create and configure the common options. + opt = commonoptions.NewOptions() + opt.Initialize(commonoptions.WithWriter(output)) + + // Create temporary directory used to save the configuration file. + configFile, err = testutils.CreateEmptyFile("falcoctl.yaml") + Expect(err).Should(Succeed()) +}) + +var _ = AfterSuite(func() { + configDir := filepath.Dir(configFile) + Expect(os.RemoveAll(configDir)).Should(Succeed()) +}) + +func executeRoot(args []string) error { + rootCmd.SetArgs(args) + rootCmd.SetOut(output) + return cmd.Execute(rootCmd, opt) +} diff --git a/cmd/driver/config/config_test.go b/cmd/driver/config/config_test.go new file mode 100644 index 00000000..4edf09bc --- /dev/null +++ b/cmd/driver/config/config_test.go @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (C) 2023 The Falco Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package driverconfig_test + +import ( + "regexp" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/gbytes" + + "github.com/falcosecurity/falcoctl/cmd" +) + +var driverConfigHelp = `Configure a driver for future usages with other driver subcommands.` + +var addAssertFailedBehavior = func(specificError string) { + It("check that fails and the usage is not printed", func() { + Expect(err).To(HaveOccurred()) + Expect(output).Should(gbytes.Say(regexp.QuoteMeta(specificError))) + }) +} + +var _ = Describe("config", func() { + + var ( + driverCmd = "driver" + configCmd = "config" + ) + + // Each test gets its own root command and runs it. + // The err variable is asserted by each test. + JustBeforeEach(func() { + rootCmd = cmd.New(ctx, opt) + err = executeRoot(args) + }) + + JustAfterEach(func() { + Expect(output.Clear()).ShouldNot(HaveOccurred()) + }) + + Context("help message", func() { + BeforeEach(func() { + args = []string{driverCmd, configCmd, "--help"} + }) + + It("should match the saved one", func() { + Expect(output).Should(gbytes.Say(driverConfigHelp)) + }) + }) + + // Here we are testing failure cases for configuring a driver. + Context("failure", func() { + When("with non absolute host-root", func() { + BeforeEach(func() { + args = []string{driverCmd, configCmd, "--config", configFile, "--host-root", "foo/"} + }) + addAssertFailedBehavior("ERROR host-root must be an absolute path: foo/") + }) + + When("with invalid driver type", func() { + BeforeEach(func() { + args = []string{driverCmd, configCmd, "--config", configFile, "--type", "foo"} + }) + addAssertFailedBehavior(`ERROR invalid argument "foo" for "--type" flag: invalid argument "foo",` + + ` please provide one of (auto, ebpf, kmod, modern_ebpf)`) + }) + }) +}) diff --git a/cmd/driver/printenv/printenv.go b/cmd/driver/printenv/printenv.go index 2bfef489..df7ef81e 100644 --- a/cmd/driver/printenv/printenv.go +++ b/cmd/driver/printenv/printenv.go @@ -16,6 +16,7 @@ package driverprintenv import ( + "errors" "strings" "github.com/spf13/cobra" @@ -67,7 +68,9 @@ func (o *driverPrintenvOptions) RunDriverPrintenv(_ context.Context) error { d, err := driverdistro.Discover(kr, driver.HostRoot) if err != nil { - return err + if !errors.Is(err, driverdistro.ErrUnsupported) { + return err + } } o.Printer.DefaultText.Printf("TARGET_ID=%q\n", d.String()) diff --git a/internal/config/config.go b/internal/config/config.go index d74521f4..8cf67e65 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -231,7 +231,11 @@ func Load(path string) error { // Set default registry auth config path viper.SetDefault(RegistryCredentialConfigKey, DefaultRegistryCredentialConfPath) // Set default driver - viper.SetDefault(DriverKey, DefaultDriver) + viper.SetDefault(DriverTypeKey, DefaultDriver.Type) + viper.SetDefault(DriverHostRootKey, DefaultDriver.HostRoot) + viper.SetDefault(DriverNameKey, DefaultDriver.Name) + viper.SetDefault(DriverReposKey, DefaultDriver.Repos) + viper.SetDefault(DriverVersionKey, DefaultDriver.Version) err = viper.ReadInConfig() if errors.As(err, &viper.ConfigFileNotFoundError{}) || os.IsNotExist(err) { @@ -642,7 +646,7 @@ func UpdateConfigFile(key string, value interface{}, path string) error { v.Set(key, value) if err := v.WriteConfig(); err != nil { - return fmt.Errorf("unable to set key %q to config file: %w", IndexesKey, err) + return fmt.Errorf("unable to set key %q to config file: %w", key, err) } return nil diff --git a/pkg/options/driver.go b/pkg/options/driver.go index ed058c82..629818d6 100644 --- a/pkg/options/driver.go +++ b/pkg/options/driver.go @@ -16,6 +16,8 @@ package options import ( + "sort" + drivertype "github.com/falcosecurity/falcoctl/pkg/driver/type" ) @@ -26,7 +28,9 @@ type DriverTypes struct { // NewDriverTypes returns a new Enum configured for the driver types. func NewDriverTypes() *DriverTypes { + types := drivertype.GetTypes() + sort.Strings(types) return &DriverTypes{ - Enum: NewEnum(drivertype.GetTypes(), drivertype.TypeKmod), + Enum: NewEnum(types, drivertype.TypeKmod), } }