forked from akvorado/akvorado
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
global: split Akvorado into 3 services
- Loading branch information
1 parent
a336370
commit 1dc2537
Showing
179 changed files
with
1,768 additions
and
1,263 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
/bin/ | ||
/test/ | ||
/flow/decoder/flow*.pb.go | ||
/inlet/flow/decoder/flow*.pb.go | ||
|
||
/web/data/node_modules/ | ||
/web/data/assets/generated/ | ||
/console/data/node_modules/ | ||
/console/data/assets/generated/ |
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,48 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
|
||
"akvorado/common/daemon" | ||
"akvorado/common/reporter" | ||
) | ||
|
||
// StartStopComponents activate/deactivate components in order. | ||
func StartStopComponents(r *reporter.Reporter, daemonComponent daemon.Component, otherComponents []interface{}) error { | ||
components := append([]interface{}{r, daemonComponent}, otherComponents...) | ||
startedComponents := []interface{}{} | ||
defer func() { | ||
for _, cmp := range startedComponents { | ||
if stopperC, ok := cmp.(stopper); ok { | ||
if err := stopperC.Stop(); err != nil { | ||
r.Err(err).Msg("unable to stop component, ignoring") | ||
} | ||
} | ||
} | ||
}() | ||
for _, cmp := range components { | ||
if starterC, ok := cmp.(starter); ok { | ||
if err := starterC.Start(); err != nil { | ||
return fmt.Errorf("unable to start component: %w", err) | ||
} | ||
} | ||
startedComponents = append([]interface{}{cmp}, startedComponents...) | ||
} | ||
|
||
r.Info(). | ||
Str("version", Version).Str("build-date", BuildDate). | ||
Msg("akvorado has started") | ||
|
||
select { | ||
case <-daemonComponent.Terminated(): | ||
r.Info().Msg("stopping all components") | ||
} | ||
return nil | ||
} | ||
|
||
type starter interface { | ||
Start() error | ||
} | ||
type stopper interface { | ||
Stop() error | ||
} |
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,81 @@ | ||
package cmd_test | ||
|
||
import ( | ||
"errors" | ||
"testing" | ||
|
||
"akvorado/cmd" | ||
"akvorado/common/daemon" | ||
"akvorado/common/helpers" | ||
"akvorado/common/reporter" | ||
) | ||
|
||
type Startable struct { | ||
Started bool | ||
} | ||
type Stopable struct { | ||
Stopped bool | ||
} | ||
|
||
func (c *Startable) Start() error { | ||
c.Started = true | ||
return nil | ||
} | ||
func (c *Stopable) Stop() error { | ||
c.Stopped = true | ||
return nil | ||
} | ||
|
||
type ComponentStartStop struct { | ||
Startable | ||
Stopable | ||
} | ||
type ComponentStop struct { | ||
Stopable | ||
} | ||
type ComponentStart struct { | ||
Startable | ||
} | ||
type ComponentNone struct{} | ||
type ComponentStartError struct { | ||
Stopable | ||
} | ||
|
||
func (c ComponentStartError) Start() error { | ||
return errors.New("nooo") | ||
} | ||
|
||
func TestStartStop(t *testing.T) { | ||
r := reporter.NewMock(t) | ||
daemonComponent := daemon.NewMock(t) | ||
otherComponents := []interface{}{ | ||
&ComponentStartStop{}, | ||
&ComponentStop{}, | ||
&ComponentStart{}, | ||
&ComponentNone{}, | ||
&ComponentStartError{}, | ||
&ComponentStartStop{}, | ||
} | ||
if err := cmd.StartStopComponents(r, daemonComponent, otherComponents); err == nil { | ||
t.Error("StartStopComponents() did not trigger an error") | ||
} | ||
|
||
expected := []interface{}{ | ||
&ComponentStartStop{ | ||
Startable: Startable{Started: true}, | ||
Stopable: Stopable{Stopped: true}, | ||
}, | ||
&ComponentStop{ | ||
Stopable: Stopable{Stopped: true}, | ||
}, | ||
&ComponentStart{ | ||
Startable: Startable{Started: true}, | ||
}, | ||
&ComponentNone{}, | ||
&ComponentStartError{}, | ||
&ComponentStartStop{}, | ||
} | ||
if diff := helpers.Diff(otherComponents, expected); diff != "" { | ||
t.Errorf("StartStopComponents() (-got, +want):\n%s", diff) | ||
} | ||
} |
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,107 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"os" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/mitchellh/mapstructure" | ||
"gopkg.in/yaml.v2" | ||
|
||
"akvorado/inlet/flow" | ||
) | ||
|
||
// ConfigRelatedOptions are command-line options related to handling a | ||
// configuration file. | ||
type ConfigRelatedOptions struct { | ||
Path string | ||
Dump bool | ||
} | ||
|
||
// Parse parses the configuration file (if present) and the | ||
// environment variables into the provided configuration. | ||
func (c ConfigRelatedOptions) Parse(out io.Writer, component string, config interface{}) error { | ||
var rawConfig map[string]interface{} | ||
if cfgFile := c.Path; cfgFile != "" { | ||
input, err := ioutil.ReadFile(cfgFile) | ||
if err != nil { | ||
return fmt.Errorf("unable to read configuration file: %w", err) | ||
} | ||
if err := yaml.Unmarshal(input, &rawConfig); err != nil { | ||
return fmt.Errorf("unable to parse configuration file: %w", err) | ||
} | ||
} | ||
|
||
// Parse provided configuration | ||
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ | ||
Result: &config, | ||
ErrorUnused: true, | ||
Metadata: nil, | ||
WeaklyTypedInput: true, | ||
MatchName: func(mapKey, fieldName string) bool { | ||
key := strings.ToLower(strings.ReplaceAll(mapKey, "-", "")) | ||
field := strings.ToLower(fieldName) | ||
return key == field | ||
}, | ||
DecodeHook: mapstructure.ComposeDecodeHookFunc( | ||
flow.ConfigurationUnmarshalerHook(), | ||
mapstructure.TextUnmarshallerHookFunc(), | ||
mapstructure.StringToTimeDurationHookFunc(), | ||
mapstructure.StringToSliceHookFunc(","), | ||
), | ||
}) | ||
if err != nil { | ||
return fmt.Errorf("unable to create configuration decoder: %w", err) | ||
} | ||
if err := decoder.Decode(rawConfig); err != nil { | ||
return fmt.Errorf("unable to parse configuration: %w", err) | ||
} | ||
|
||
// Override with environment variables | ||
for _, keyval := range os.Environ() { | ||
kv := strings.SplitN(keyval, "=", 2) | ||
if len(kv) != 2 { | ||
continue | ||
} | ||
kk := strings.Split(kv[0], "_") | ||
if len(kk) < 3 || kk[0] != "AKVORADO" || kk[1] != strings.ToUpper(component) { | ||
continue | ||
} | ||
// From AKVORADO_CMP_SQUID_PURPLE_QUIRK=47, we | ||
// build a map "squid -> purple -> quirk -> | ||
// 47". From AKVORADO_CMP_SQUID_3_PURPLE=47, we | ||
// build "squid[3] -> purple -> 47" | ||
var rawConfig interface{} | ||
rawConfig = kv[1] | ||
for i := len(kk) - 1; i > 1; i-- { | ||
if index, err := strconv.Atoi(kk[i]); err == nil { | ||
newRawConfig := make([]interface{}, index+1) | ||
newRawConfig[index] = rawConfig | ||
rawConfig = newRawConfig | ||
} else { | ||
rawConfig = map[string]interface{}{ | ||
kk[i]: rawConfig, | ||
} | ||
} | ||
} | ||
if err := decoder.Decode(rawConfig); err != nil { | ||
return fmt.Errorf("unable to parse override %q: %w", kv[0], err) | ||
} | ||
} | ||
|
||
// Dump configuration if requested | ||
if c.Dump { | ||
output, err := yaml.Marshal(config) | ||
if err != nil { | ||
return fmt.Errorf("unable to dump configuration: %w", err) | ||
} | ||
out.Write([]byte("---\n")) | ||
out.Write(output) | ||
out.Write([]byte("\n")) | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.