Skip to content

Commit

Permalink
Intentions module input configuration added
Browse files Browse the repository at this point in the history
  • Loading branch information
noejbrown committed Jul 8, 2022
1 parent 86e55d5 commit d45e5f1
Show file tree
Hide file tree
Showing 7 changed files with 1,280 additions and 4 deletions.
130 changes: 130 additions & 0 deletions config/intentions_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package config

import (
"fmt"
"regexp"
)

// IntentionsServicesConfig configures regexp/list of names of services.
type IntentionsServicesConfig struct {
// Regexp configures the source services to monitor by matching on the service name.
// Either Regexp or Names must be configured, not both.
Regexp *string `mapstructure:"regexp"`

// Names configures the services to monitor by listing the service name.
// Either Regexp or Names must be configured, not both.
Names []string `mapstructure:"names"`
}

// Copy returns a deep copy of IntentionsServicesConfig
func (c *IntentionsServicesConfig) Copy() *IntentionsServicesConfig {
if c == nil {
return nil
}

var o IntentionsServicesConfig
o.Regexp = StringCopy(c.Regexp)

if c.Names != nil {
o.Names = make([]string, 0, len(c.Names))
o.Names = append(o.Names, c.Names...)
}
return &o
}

// Merge combines all values in this IntentionsServicesConfig with the values in the other
// configuration, with values in the other configuration taking precedence.
// Maps and slices are merged, most other values are overwritten. Complex
// structs define their own merge functionality.
func (c *IntentionsServicesConfig) Merge(o *IntentionsServicesConfig) *IntentionsServicesConfig {
if c == nil {
if o == nil {
return nil
}
return o.Copy()
}

if o == nil {
return c.Copy()
}

r := c.Copy()

if o.Regexp != nil {
r.Regexp = StringCopy(o.Regexp)
}

r.Names = mergeSlices(c.Names, o.Names)

return r
}

// Finalize ensures there no nil pointers.
// Exception: `Regexp` is never finalized and can potentially be nil.
func (c *IntentionsServicesConfig) Finalize() {
if c == nil { // config not required, return early
return
}

if c.Names == nil {
c.Names = []string{}
}
}

func (c *IntentionsServicesConfig) Validate() error {
if c == nil { // config not required, return early
return nil
}

// Check that either regex or names is configured but not both
namesConfigured := c.Names != nil && len(c.Names) > 0
regexConfigured := c.Regexp != nil

if namesConfigured && regexConfigured {
return fmt.Errorf("regexp and names fields cannot both be " +
"configured. If both are needed, consider including the list of " +
"names as part of the regex or creating separate tasks")
}
if !namesConfigured && !regexConfigured {
return fmt.Errorf("either the regexp or names field must be configured")
}

// Validate regex
if regexConfigured {
if _, err := regexp.Compile(StringVal(c.Regexp)); err != nil {
return fmt.Errorf("unable to compile intentions service regexp: %s", err)
}
}

// Check that names does not contain empty strings
if namesConfigured {
for _, name := range c.Names {
if name == "" {
return fmt.Errorf("names field includes empty string(s). " +
"intentions service names cannot be empty")
}
}
}

return nil
}

func (c *IntentionsServicesConfig) GoString() string {
if c == nil {
return ": (*IntentionsServicesConfig)(nil)"
}

if len(c.Names) > 0 {
return fmt.Sprintf(
"Names:%s",
c.Names,
)

} else {
return fmt.Sprintf(
"Regexp:%s",
StringVal(c.Regexp),
)

}
}
5 changes: 5 additions & 0 deletions config/module_input.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ func moduleInputToTypeFunc() mapstructure.DecodeHookFunc {
return decodeModuleInputToType(c, &config)
}

if c, ok := moduleInputs[intentionsType]; ok {
var config IntentionsModuleInputConfig
return decodeModuleInputToType(c, &config)
}

return nil, fmt.Errorf("unsupported module_input type: %v", data)
}
}
Expand Down
93 changes: 93 additions & 0 deletions config/module_input_intentions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package config

import (
"fmt"
)

var _ ModuleInputConfig = (*IntentionsModuleInputConfig)(nil)

// IntentionsModuleInputConfig configures a module_input configuration block of
// type 'intentions'. Data about the intentions monitored will be used as input
// for the module variables.
type IntentionsModuleInputConfig struct {
IntentionsMonitorConfig `mapstructure:",squash"`
}

// Copy returns a deep copy of this configuration.
func (c *IntentionsModuleInputConfig) Copy() MonitorConfig {
if c == nil {
return nil
}

conf, ok := c.IntentionsMonitorConfig.Copy().(*IntentionsMonitorConfig)
if !ok {
return nil
}
return &IntentionsModuleInputConfig{
IntentionsMonitorConfig: *conf,
}
}

// Merge combines all values in this configuration `c` with the values in the other
// configuration `o`, with values in the other configuration taking precedence.
// Maps and slices are merged, most other values are overwritten. Complex
// structs define their own merge functionality.
func (c *IntentionsModuleInputConfig) Merge(o MonitorConfig) MonitorConfig {
if c == nil {
if isModuleInputNil(o) { // o is interface, use isConditionNil()
return nil
}
return o.Copy()
}

if isModuleInputNil(o) {
return c.Copy()
}

o2, ok := o.(*IntentionsModuleInputConfig)
if !ok {
return nil
}

merged, ok := c.IntentionsMonitorConfig.Merge(&o2.IntentionsMonitorConfig).(*IntentionsMonitorConfig)
if !ok {
return nil
}

return &IntentionsModuleInputConfig{
IntentionsMonitorConfig: *merged,
}
}

// Finalize ensures there are no nil pointers.
func (c *IntentionsModuleInputConfig) Finalize() {
if c == nil { // config not required, return early
return
}
c.IntentionsMonitorConfig.Finalize()
}

// Validate validates the values and required options. This method is recommended
// to run after Finalize() to ensure the configuration is safe to proceed.
func (c *IntentionsModuleInputConfig) Validate() error {
if c == nil { // config not required, return early
return nil
}
if err := c.IntentionsMonitorConfig.Validate(); err != nil {
return fmt.Errorf("error validating `module_input \"intentions\"`: %s", err)
}
return nil
}

// GoString defines the printable version of this struct.
func (c *IntentionsModuleInputConfig) GoString() string {
if c == nil {
return "(*IntentionsModuleInputConfig)(nil)"
}

return fmt.Sprintf("&IntentionsModuleInputConfig{"+
"%s"+
"}",
c.IntentionsMonitorConfig.GoString(),
)
}
Loading

0 comments on commit d45e5f1

Please sign in to comment.