-
-
Notifications
You must be signed in to change notification settings - Fork 170
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #88 from AnalogJ/detect_config
- Loading branch information
Showing
35 changed files
with
866 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package config | ||
|
||
import ( | ||
"github.com/analogj/go-util/utils" | ||
"github.com/analogj/scrutiny/collector/pkg/errors" | ||
"github.com/analogj/scrutiny/collector/pkg/models" | ||
"github.com/mitchellh/mapstructure" | ||
"github.com/spf13/viper" | ||
"log" | ||
"os" | ||
) | ||
|
||
// When initializing this class the following methods must be called: | ||
// Config.New | ||
// Config.Init | ||
// This is done automatically when created via the Factory. | ||
type configuration struct { | ||
*viper.Viper | ||
} | ||
|
||
//Viper uses the following precedence order. Each item takes precedence over the item below it: | ||
// explicit call to Set | ||
// flag | ||
// env | ||
// config | ||
// key/value store | ||
// default | ||
|
||
func (c *configuration) Init() error { | ||
c.Viper = viper.New() | ||
//set defaults | ||
c.SetDefault("host.id", "") | ||
|
||
c.SetDefault("devices", []string{}) | ||
|
||
//c.SetDefault("collect.short.command", "-a -o on -S on") | ||
|
||
//if you want to load a non-standard location system config file (~/drawbridge.yml), use ReadConfig | ||
c.SetConfigType("yaml") | ||
//c.SetConfigName("drawbridge") | ||
//c.AddConfigPath("$HOME/") | ||
|
||
//CLI options will be added via the `Set()` function | ||
return nil | ||
} | ||
|
||
func (c *configuration) ReadConfig(configFilePath string) error { | ||
configFilePath, err := utils.ExpandPath(configFilePath) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if !utils.FileExists(configFilePath) { | ||
log.Printf("No configuration file found at %v. Using Defaults.", configFilePath) | ||
return errors.ConfigFileMissingError("The configuration file could not be found.") | ||
} | ||
|
||
//validate config file contents | ||
//err = c.ValidateConfigFile(configFilePath) | ||
//if err != nil { | ||
// log.Printf("Config file at `%v` is invalid: %s", configFilePath, err) | ||
// return err | ||
//} | ||
|
||
log.Printf("Loading configuration file: %s", configFilePath) | ||
|
||
config_data, err := os.Open(configFilePath) | ||
if err != nil { | ||
log.Printf("Error reading configuration file: %s", err) | ||
return err | ||
} | ||
|
||
err = c.MergeConfig(config_data) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return c.ValidateConfig() | ||
} | ||
|
||
// This function ensures that the merged config works correctly. | ||
func (c *configuration) ValidateConfig() error { | ||
|
||
//TODO: | ||
// check that device prefix matches OS | ||
// check that schema of config file is valid | ||
|
||
return nil | ||
} | ||
|
||
func (c *configuration) GetScanOverrides() []models.ScanOverride { | ||
// we have to support 2 types of device types. | ||
// - simple device type (device_type: 'sat') | ||
// and list of device types (type: \n- 3ware,0 \n- 3ware,1 \n- 3ware,2) | ||
// GetString will return "" if this is a list of device types. | ||
|
||
overrides := []models.ScanOverride{} | ||
c.UnmarshalKey("devices", &overrides, func(c *mapstructure.DecoderConfig) { c.WeaklyTypedInput = true }) | ||
return overrides | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package config_test | ||
|
||
import ( | ||
"github.com/analogj/scrutiny/collector/pkg/config" | ||
"github.com/analogj/scrutiny/collector/pkg/models" | ||
"github.com/stretchr/testify/require" | ||
"path" | ||
"testing" | ||
) | ||
|
||
func TestConfiguration_GetScanOverrides_Simple(t *testing.T) { | ||
t.Parallel() | ||
|
||
//setup | ||
testConfig, _ := config.Create() | ||
|
||
//test | ||
err := testConfig.ReadConfig(path.Join("testdata", "simple_device.yaml")) | ||
require.NoError(t, err, "should correctly load simple device config") | ||
scanOverrides := testConfig.GetScanOverrides() | ||
|
||
//assert | ||
require.Equal(t, []models.ScanOverride{{Device: "/dev/sda", DeviceType: []string{"sat"}, Ignore: false}}, scanOverrides) | ||
} | ||
|
||
func TestConfiguration_GetScanOverrides_Ignore(t *testing.T) { | ||
t.Parallel() | ||
|
||
//setup | ||
testConfig, _ := config.Create() | ||
|
||
//test | ||
err := testConfig.ReadConfig(path.Join("testdata", "ignore_device.yaml")) | ||
require.NoError(t, err, "should correctly load ignore device config") | ||
scanOverrides := testConfig.GetScanOverrides() | ||
|
||
//assert | ||
require.Equal(t, []models.ScanOverride{{Device: "/dev/sda", DeviceType: nil, Ignore: true}}, scanOverrides) | ||
} | ||
|
||
func TestConfiguration_GetScanOverrides_Raid(t *testing.T) { | ||
t.Parallel() | ||
|
||
//setup | ||
testConfig, _ := config.Create() | ||
|
||
//test | ||
err := testConfig.ReadConfig(path.Join("testdata", "raid_device.yaml")) | ||
require.NoError(t, err, "should correctly load ignore device config") | ||
scanOverrides := testConfig.GetScanOverrides() | ||
|
||
//assert | ||
require.Equal(t, []models.ScanOverride{ | ||
{ | ||
Device: "/dev/bus/0", | ||
DeviceType: []string{"megaraid,14", "megaraid,15", "megaraid,18", "megaraid,19", "megaraid,20", "megaraid,21"}, | ||
Ignore: false, | ||
}, | ||
{ | ||
Device: "/dev/twa0", | ||
DeviceType: []string{"3ware,0", "3ware,1", "3ware,2", "3ware,3", "3ware,4", "3ware,5"}, | ||
Ignore: false, | ||
}}, scanOverrides) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package config | ||
|
||
func Create() (Interface, error) { | ||
config := new(configuration) | ||
if err := config.Init(); err != nil { | ||
return nil, err | ||
} | ||
return config, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package config | ||
|
||
import ( | ||
"github.com/analogj/scrutiny/collector/pkg/models" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
// Create mock using: | ||
// mockgen -source=collector/pkg/config/interface.go -destination=collector/pkg/config/mock/mock_config.go | ||
type Interface interface { | ||
Init() error | ||
ReadConfig(configFilePath string) error | ||
Set(key string, value interface{}) | ||
SetDefault(key string, value interface{}) | ||
|
||
AllSettings() map[string]interface{} | ||
IsSet(key string) bool | ||
Get(key string) interface{} | ||
GetBool(key string) bool | ||
GetInt(key string) int | ||
GetString(key string) string | ||
GetStringSlice(key string) []string | ||
UnmarshalKey(key string, rawVal interface{}, decoderOpts ...viper.DecoderConfigOption) error | ||
|
||
GetScanOverrides() []models.ScanOverride | ||
} |
Oops, something went wrong.