Skip to content

Commit

Permalink
fix(internal/config): properly use a flat data structure for reading …
Browse files Browse the repository at this point in the history
…and storing driver config.

Convert it in `config.Driverer` to the exposed structure with driver.Type resolved to its interface.

Signed-off-by: Federico Di Pierro <[email protected]>
  • Loading branch information
FedeDP committed Nov 9, 2023
1 parent 9658ac6 commit aa26925
Showing 1 changed file with 29 additions and 46 deletions.
75 changes: 29 additions & 46 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ var (
// DefaultRegistryCredentialConfPath is the default path for the credential store configuration file.
DefaultRegistryCredentialConfPath = filepath.Join(config.Dir(), "config.json")
// DefaultDriver is the default config for the falcosecurity organization.
DefaultDriver Driver
DefaultDriver driver

// Useful regexps for parsing.

Expand Down Expand Up @@ -116,16 +116,6 @@ const (

// DriverKey is the Viper key for driver structure.
DriverKey = "driver"
// DriverTypeKey is the Viper key for the driver type.
DriverTypeKey = "driver.type"
// DriverVersionKey is the Viper key for the driver version.
DriverVersionKey = "driver.version"
// DriverReposKey is the Viper key for the driver repositories.
DriverReposKey = "driver.repos"
// DriverNameKey is the Viper key for the driver name.
DriverNameKey = "driver.name"
// DriverHostRootKey is the Viper key for the driver host root.
DriverHostRootKey = "driver.hostRoot"
)

// Index represents a configured index.
Expand Down Expand Up @@ -175,7 +165,16 @@ type Install struct {
NoVerify bool `mapstructure:"noVerify"`
}

// Driver represents a configured driver.
// driver represents the internal driver configuration (with Type string).
type driver struct {
Type string `mapstructure:"type"`
Name string `mapstructure:"name"`
Repos []string `mapstructure:"repos"`
Version string `mapstructure:"version"`
HostRoot string `mapstructure:"hostRoot"`
}

// Driver represents the resolved driver configuration, exposed to be consumed.
type Driver struct {
Type drivertype.DriverType `mapstructure:"type"`
Name string `mapstructure:"name"`
Expand All @@ -194,9 +193,8 @@ func init() {
Name: "falcosecurity",
URL: "https://falcosecurity.github.io/falcoctl/index.yaml",
}
kmodType, _ := drivertype.Parse(drivertype.TypeKmod)
DefaultDriver = Driver{
Type: kmodType,
DefaultDriver = driver{
Type: drivertype.TypeKmod,
Name: "falco",
Repos: []string{"https://download.falco.org/driver"},
Version: "",
Expand Down Expand Up @@ -492,33 +490,6 @@ func gcpAuthListHookFunc() mapstructure.DecodeHookFuncType {
}
}

// driverHookFunc returns a DecodeHookFunc that converts
// strings to string slices, when the target type is DotSeparatedStringList.
// when passed as env should be in the following format:
// "registry;registry1".
// Moreover, it also converts driver.type string to drivertype.Type.
func driverHookFunc() mapstructure.DecodeHookFuncType {
return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
if f.Kind() != reflect.Struct && f.Kind() != reflect.String {
return data, nil
}

if t != reflect.TypeOf(Driver{}) && t != reflect.TypeOf((*drivertype.DriverType)(nil)).Elem() {
return data, fmt.Errorf("unable to decode data since destination variable is not of type %T nor DriverType", Driver{})
}

// Format/decode/parse the data and return the new value
switch f.Kind() {
case reflect.String:
return drivertype.Parse(data.(string))
case reflect.Struct:
return data, nil
default:
return nil, nil
}
}
}

// Follower retrieves the follower section of the config file.
func Follower() (Follow, error) {
// with Follow we can just use nested keys.
Expand Down Expand Up @@ -565,10 +536,13 @@ func Installer() (Install, error) {

// Driverer retrieves the driver section of the config file.
func Driverer() (Driver, error) {
var drvCfg Driver
var (
drvCfg driver
resolvedDrvCfg Driver
)

if err := viper.UnmarshalKey(DriverKey, &drvCfg, viper.DecodeHook(driverHookFunc())); err != nil {
return drvCfg, fmt.Errorf("unable to get driver: %w", err)
if err := viper.UnmarshalKey(DriverKey, &drvCfg); err != nil {
return resolvedDrvCfg, fmt.Errorf("unable to get driver: %w", err)
}

// Try to load it automatically from /usr/src sub folders,
Expand All @@ -593,7 +567,16 @@ func Driverer() (Driver, error) {
}
}

return drvCfg, nil
drvType, err := drivertype.Parse(drvCfg.Type)
if err != nil {
return resolvedDrvCfg, err
}
resolvedDrvCfg.Type = drvType
resolvedDrvCfg.Name = drvCfg.Name
resolvedDrvCfg.HostRoot = drvCfg.HostRoot
resolvedDrvCfg.Version = drvCfg.Version
resolvedDrvCfg.Repos = drvCfg.Repos
return resolvedDrvCfg, nil
}

// StoreDriver stores a driver conf in config file.
Expand Down

0 comments on commit aa26925

Please sign in to comment.