Skip to content

Commit

Permalink
feat(logger): moved to own package
Browse files Browse the repository at this point in the history
  • Loading branch information
StanGirard committed Apr 9, 2023
1 parent 3ccfcac commit 75cdb23
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 107 deletions.
16 changes: 0 additions & 16 deletions plugins/commons/check.go

This file was deleted.

7 changes: 0 additions & 7 deletions plugins/commons/checkConfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@ import (
"sync"
)

// CheckConfig is a struct that contains all the information needed to run a check.
type CheckConfig struct {
Wg *sync.WaitGroup // Wait group to wait for all the checks to be done
Queue chan Check // Queue to add the results to
ConfigYatas *Config // Yatas config
}

// Init the check config struct. Particularly useful in the categories. It allows to pass the config to the checks and allows
// them to be run in parallel by adding the results to the queue.
func (c *CheckConfig) Init(config *Config) {
Expand Down
7 changes: 0 additions & 7 deletions plugins/commons/checkIgnore.go

This file was deleted.

30 changes: 0 additions & 30 deletions plugins/commons/commons.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@ import (
"github.com/hashicorp/go-plugin"
)

// Yatas is the interface that we're exposing as a plugin.
type Yatas interface {
Run(c *Config) []Tests
}

// Here is an implementation that talks over RPC
type YatasRPC struct{ client *rpc.Client }

func (g *YatasRPC) Run(c *Config) []Tests {
var resp []Tests
err := g.client.Call("Plugin.Run", c, &resp)
Expand All @@ -26,33 +18,11 @@ func (g *YatasRPC) Run(c *Config) []Tests {
return resp
}

// Here is the RPC server that YatasRPC talks to, conforming to
// the requirements of net/rpc
type YatasRPCServer struct {
// This is the real implementation
Impl Yatas
}

func (s *YatasRPCServer) Run(c *Config, resp *[]Tests) error {
*resp = s.Impl.Run(c)
return nil
}

// This is the implementation of plugin.Plugin so we can serve/consume this
//
// This has two methods: Server must return an RPC server for this plugin
// type. We construct a YatasRPCServer for this.
//
// Client must return an implementation of our interface that communicates
// over an RPC client. We return YatasRPC for this.
//
// Ignore MuxBroker. That is used to create more multiplexed streams on our
// plugin connection and is a more advanced use case.
type YatasPlugin struct {
// Impl Injection
Impl Yatas
}

func (p *YatasPlugin) Server(*plugin.MuxBroker) (interface{}, error) {
return &YatasRPCServer{Impl: p.Impl}, nil
}
Expand Down
7 changes: 0 additions & 7 deletions plugins/commons/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,6 @@ import (
"gopkg.in/yaml.v3"
)

type Config struct {
Plugins []Plugin `yaml:"plugins"`
Ignore []Ignore `yaml:"ignore"`
PluginConfig []map[string]interface{} `yaml:"pluginsConfiguration"`
Tests []Tests `yaml:"tests"`
}

func ParseConfig(configFile string) (*Config, error) {
// Read the file .yatas.yml
// File to array of bytes
Expand Down
19 changes: 0 additions & 19 deletions plugins/commons/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,6 @@ import (
"github.com/mitchellh/go-homedir"
)

type Plugin struct {
Name string `yaml:"name"`
Enabled bool `yaml:"enabled"`
Source string `yaml:"source"`
Type string `default:"checks" yaml:"type" `
Version string `yaml:"version"`
Description string `yaml:"description"`
Exclude []string `yaml:"exclude"`
Include []string `yaml:"include"`
Command string `yaml:"command"`
Args []string `yaml:"args"`
ExpectedOutput string `yaml:"expected_output"`
ExpectedStatus int `yaml:"expected_status"`

// Parsed source attributes
SourceOwner string
SourceRepo string
}

// InstallPath returns an installation path from the plugin directory.
func (c *Plugin) InstallPath() string {
return filepath.Join(c.Source, c.Version, fmt.Sprintf("yatas-%s", c.Name))
Expand Down
94 changes: 94 additions & 0 deletions plugins/commons/result.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,101 @@
package commons

import (
"net/rpc"
"sync"
"time"
)

// Wrapper struct that holds all the results of the checks for each account
type Tests struct {
Account string `yaml:"account"` // Account name
Checks []Check `yaml:"checks"` // Checks
}

// A check is a test that is run on a resource
type Check struct {
Name string `yaml:"name"` // Name of the check
Description string `yaml:"description"` // Description of the check
Status string `yaml:"status"` // Status of the check - OK, FAIL
Id string `yaml:"id"` // ID of the check - unique identifier for the check - AWS_IAM_001
Categories []string `yaml:"categories"` // Category of the check - Security, Cost, Performance, Fault Tolerance, Operational Excellence, etc ...
Results []Result `yaml:"results"` // Results of the check
Duration time.Duration `yaml:"duration"` // Duration of the check
StartTime time.Time
EndTime time.Time
}

type Result struct {
Message string `yaml:"message"` // Message to display
Status string `yaml:"status"` // Status of the check
ResourceID string `yaml:"resource_arn"` // Resource ID - unique identifier for the resource
}

type Config struct {
Plugins []Plugin `yaml:"plugins"`
Ignore []Ignore `yaml:"ignore"`
PluginConfig []map[string]interface{} `yaml:"pluginsConfiguration"`
Tests []Tests `yaml:"tests"`
}

// CheckConfig is a struct that contains all the information needed to run a check.
type CheckConfig struct {
Wg *sync.WaitGroup // Wait group to wait for all the checks to be done
Queue chan Check // Queue to add the results to
ConfigYatas *Config // Yatas config
}

type Ignore struct {
ID string `yaml:"id"`
Regex bool `yaml:"regex"`
Values []string `yaml:"values"`
}

// Yatas is the interface that we're exposing as a plugin.
type Yatas interface {
Run(c *Config) []Tests
}

// Here is an implementation that talks over RPC
type YatasRPC struct{ client *rpc.Client }

// This is the implementation of plugin.Plugin so we can serve/consume this
//
// This has two methods: Server must return an RPC server for this plugin
// type. We construct a YatasRPCServer for this.
//
// Client must return an implementation of our interface that communicates
// over an RPC client. We return YatasRPC for this.
//
// Ignore MuxBroker. That is used to create more multiplexed streams on our
// plugin connection and is a more advanced use case.
type YatasPlugin struct {
// Impl Injection
Impl Yatas
}

// Here is the RPC server that YatasRPC talks to, conforming to
// the requirements of net/rpc
type YatasRPCServer struct {
// This is the real implementation
Impl Yatas
}

type Plugin struct {
Name string `yaml:"name"`
Enabled bool `yaml:"enabled"`
Source string `yaml:"source"`
Type string `default:"checks" yaml:"type" `
Version string `yaml:"version"`
Description string `yaml:"description"`
Exclude []string `yaml:"exclude"`
Include []string `yaml:"include"`
Command string `yaml:"command"`
Args []string `yaml:"args"`
ExpectedOutput string `yaml:"expected_output"`
ExpectedStatus int `yaml:"expected_status"`

// Parsed source attributes
SourceOwner string
SourceRepo string
}
7 changes: 0 additions & 7 deletions plugins/commons/tests.go

This file was deleted.

5 changes: 5 additions & 0 deletions internal/logger/logger.go → plugins/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,8 @@ func Error(msg string, args ...interface{}) {
}
logger.Error(msg, args...)
}

// SetLogger sets the global logger to the provided logger
func SetLogger(l hclog.Logger) {
logger = l
}
67 changes: 67 additions & 0 deletions plugins/logger/logger_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package logger

import (
"bytes"
"os"
"strings"
"testing"

"github.com/hashicorp/go-hclog"
)

func TestLogger(t *testing.T) {
logger := Logger()
if logger == nil {
t.Errorf("logger is nil, expected a non-nil logger")
}
}

func TestLogLevels(t *testing.T) {
tests := []struct {
name string
logFn func(string, ...interface{})
level hclog.Level
}{
{"Trace", Trace, hclog.Trace},
{"Debug", Debug, hclog.Debug},
{"Info", Info, hclog.Info},
{"Warn", Warn, hclog.Warn},
{"Error", Error, hclog.Error},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
os.Setenv("YATAS_LOG", "")
}()

os.Setenv("YATAS_LOG", strings.ToLower(tt.name))

var buf bytes.Buffer

logger := hclog.New(&hclog.LoggerOptions{
Level: hclog.LevelFromString(strings.ToLower(tt.name)),
Output: &buf,
TimeFormat: "15:04:05",
IncludeLocation: true,
AdditionalLocationOffset: 1,
Color: hclog.AutoColor,
ColorHeaderOnly: true,
})
SetLogger(logger)

message := "test message"
tt.logFn(message)

logOutput := buf.String()
if !strings.Contains(logOutput, message) {
t.Errorf("Expected log message '%s' in output: %s", message, logOutput)
}

// tt.name but uppercased
if !strings.Contains(logOutput, strings.ToUpper(tt.name)) {
t.Errorf("Expected log level '%s' in output: %s", tt.name, logOutput)
}
})
}
}
16 changes: 2 additions & 14 deletions plugins/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import (
"encoding/gob"
"fmt"
"log"
"os"
"os/exec"
"strings"

hclog "github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-plugin"
"github.com/mitchellh/go-homedir"
"github.com/padok-team/yatas/plugins/commons"
"github.com/padok-team/yatas/plugins/logger"
)

func RunPlugin(pluginInput commons.Plugin, c *commons.Config) []commons.Tests {
Expand All @@ -23,25 +22,14 @@ func RunPlugin(pluginInput commons.Plugin, c *commons.Config) []commons.Tests {
for _, plugin := range c.Plugins {
pluginMap[strings.ToLower(plugin.Name)] = &commons.YatasPlugin{}
}
// Check env variable yatas-log-level
logLevel := os.Getenv("YATAS_LOG_LEVEL")
if logLevel == "" {
logLevel = "OFF"
}

logger := hclog.New(&hclog.LoggerOptions{
Name: "plugin",
Output: os.Stdout,
Level: hclog.LevelFromString(logLevel),
})

// We're a host! Start by launching the plugin process.
homeDir, _ := homedir.Expand("~/.yatas.d/plugins/")
client := plugin.NewClient(&plugin.ClientConfig{
HandshakeConfig: handshakeConfig,
Plugins: pluginMap,
Cmd: exec.Command(homeDir + "/" + pluginInput.Source + "/" + pluginInput.Version + "/yatas-" + pluginInput.Name),
Logger: logger,
Logger: logger.Logger(),
})
defer client.Kill()

Expand Down

0 comments on commit 75cdb23

Please sign in to comment.