From 36cd52edc9aa98f43fa1bcefc6b005c7b2cb2344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Fri, 8 Sep 2023 15:05:50 +0200 Subject: [PATCH 01/41] - passe en go 1.21 - passe en slog --- config/config.go | 177 ++++++++++++++-------------- config/config_test.go | 7 +- config/test_config.toml | 1 - go.mod | 8 +- go.sum | 8 ++ keycloak_integration_test.go | 10 +- logger/configuration.go | 42 +++++++ logger/formatter.go | 66 ----------- logger/formatters.go | 69 +++++++++++ logger/logData.go | 13 +- logger/logger.go | 183 ++++++++++++++--------------- logger/logger_test.go | 9 ++ structs/structs.go | 1 - test/sample/test_config.toml | 1 - wekanTaskforce_integration_test.go | 26 +--- 15 files changed, 324 insertions(+), 297 deletions(-) create mode 100644 logger/configuration.go delete mode 100644 logger/formatter.go create mode 100644 logger/formatters.go create mode 100644 logger/logger_test.go diff --git a/config/config.go b/config/config.go index 366984b..ddfb76d 100644 --- a/config/config.go +++ b/config/config.go @@ -1,109 +1,112 @@ package config import ( - "github.com/BurntSushi/toml" - "github.com/pkg/errors" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" - "os" - "strings" + "log/slog" + "os" + "strings" + + "github.com/BurntSushi/toml" + "github.com/pkg/errors" + + "github.com/signaux-faibles/keycloakUpdater/v2/logger" + "github.com/signaux-faibles/keycloakUpdater/v2/structs" ) func InitConfig(configFilename string) (structs.Config, error) { - return initConfig(configFilename, false) + return initConfig(configFilename, false) } func OverrideConfig(original structs.Config, overridingFilename string) structs.Config { - if overridingFilename == "" { - logger.Infof("pas de surcharge de configuration") - return original - } - logger.Infof("surcharge de configuration : %s", overridingFilename) - overridingConfig, err := initConfig(overridingFilename, true) - if err != nil { - logger.Errorf( - "erreur pendant la récupération de la surcharge de configuration '%s' : %s", - overridingFilename, - err) - return original - } - return merge(original, overridingConfig) + if overridingFilename == "" { + logger.Infof("pas de surcharge de configuration") + return original + } + logger.Infof("surcharge de configuration : %s", overridingFilename) + overridingConfig, err := initConfig(overridingFilename, true) + if err != nil { + logger.Errorf( + "erreur pendant la récupération de la surcharge de configuration '%s' : %s", + overridingFilename, + err) + return original + } + return merge(original, overridingConfig) } func initConfig(configFilename string, quietly bool) (structs.Config, error) { - var conf structs.Config - //var err error - //var meta toml.MetaData - filenames := getAllConfigFilenames(configFilename) - logger.Infof("config files : %s", filenames) - allConfig := readAllConfigFiles(filenames) - for _, current := range allConfig { - conf = merge(conf, current) - } - if !quietly && conf.Stock == nil { - return structs.Config{}, errors.Errorf("[config] Stock is not configured") - } - return conf, nil + var conf structs.Config + //var err error + //var meta toml.MetaData + filenames := getAllConfigFilenames(configFilename) + logger.Infof("config files : %s", filenames) + allConfig := readAllConfigFiles(filenames) + for _, current := range allConfig { + conf = merge(conf, current) + } + if !quietly && conf.Stock == nil { + return structs.Config{}, errors.Errorf("[config] Stock is not configured") + } + return conf, nil } func readAllConfigFiles(filenames []string) []structs.Config { - var r = make([]structs.Config, 0) - for _, filename := range filenames { - config := extractConfig(filename) - r = append(r, config) - } - return r + var r = make([]structs.Config, 0) + for _, filename := range filenames { + config := extractConfig(filename) + r = append(r, config) + } + return r } func getAllConfigFilenames(filename string) []string { - var r = make([]string, 0) - // checking file exist - var err error - if _, err = os.Open(filename); err != nil { - logger.Panicf("error reading clients config file : %s", err) - } - r = append(r, filename) - var files []os.DirEntry - config := extractConfig(filename) - if config.Stock == nil { - return r - } - folder := config.Stock.ClientsAndRealmFolder - if folder == "" { - logger.Warnf("no configuration folder is defined") - return r - } - stockFilename := config.Stock.UsersAndRolesFilename - if stockFilename != "" { - if _, err = os.ReadFile(stockFilename); err != nil { - logger.Panicf("error reading stock file '%s' : %s", stockFilename, err) - } - } - if files, err = os.ReadDir(folder); err != nil { - logger.Panicf("error reading clients config folder : %s", err) - } - for _, f := range files { - filename := folder + "/" + f.Name() - if !strings.HasSuffix(filename, ".toml") { - logger.Debugf("ignore config file %s", filename) - continue - } - r = append(r, filename) - } - return r + var r = make([]string, 0) + // checking file exist + var err error + if _, err = os.Open(filename); err != nil { + logger.Panicf("error reading clients config file : %s", err) + } + r = append(r, filename) + var files []os.DirEntry + config := extractConfig(filename) + if config.Stock == nil { + return r + } + folder := config.Stock.ClientsAndRealmFolder + if folder == "" { + logger.Warnf("no configuration folder is defined") + return r + } + stockFilename := config.Stock.UsersAndRolesFilename + if stockFilename != "" { + if _, err = os.ReadFile(stockFilename); err != nil { + logger.Panicf("error reading stock file '%s' : %s", stockFilename, err) + } + } + if files, err = os.ReadDir(folder); err != nil { + logger.Panicf("error reading clients config folder : %s", err) + } + for _, f := range files { + filename := folder + "/" + f.Name() + if !strings.HasSuffix(filename, ".toml") { + logger.Debugf("ignore le fichier de configuration", slog.String("configFilename", filename)) + continue + } + r = append(r, filename) + } + return r } func extractConfig(filename string) structs.Config { - var conf structs.Config - var err error - var meta toml.MetaData - if meta, err = toml.DecodeFile(filename, &conf); err != nil { - logger.Panicf("error decoding toml config file '%s': %s", filename, err) - } - if meta.Undecoded() != nil { - for _, key := range meta.Undecoded() { - logger.Warnf("Caution : key '%s' from config file '%s' is not used", key, filename) - } - } - return conf + var conf structs.Config + var err error + var meta toml.MetaData + if meta, err = toml.DecodeFile(filename, &conf); err != nil { + logger.Panicf("error decoding toml config file '%s': %s", filename, err) + } + if meta.Undecoded() != nil { + for _, key := range meta.Undecoded() { + logger.Warnf("Caution : key '%s' from config file '%s' is not used", key, filename) + } + } + return conf } diff --git a/config/config_test.go b/config/config_test.go index 6790024..4cda6d0 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -2,10 +2,12 @@ package config import ( "fmt" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" - "github.com/stretchr/testify/assert" "os" "testing" + + "github.com/stretchr/testify/assert" + + "github.com/signaux-faibles/keycloakUpdater/v2/structs" ) func Test_InitConfig(t *testing.T) { @@ -36,7 +38,6 @@ func Test_InitConfig(t *testing.T) { Filename: "roles-test.log", Level: "TRACE", TimestampFormat: "2006-01-02 15:04:05", - Rotation: false, } ass.Equal(expectedLogger, *config.Logger) diff --git a/config/test_config.toml b/config/test_config.toml index ccf4953..b36a5a5 100644 --- a/config/test_config.toml +++ b/config/test_config.toml @@ -8,7 +8,6 @@ realm = "master" filename = "roles-test.log" level = "TRACE" timestampFormat = "2006-01-02 15:04:05" -#rotation = false [stock] clientsAndRealmFolder = "../test/sample/test_config.d" diff --git a/go.mod b/go.mod index 5d645cb..c7aa651 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/signaux-faibles/keycloakUpdater/v2 -go 1.20 +go 1.21 + +toolchain go1.21.1 // replace github.com/signaux-faibles/libwekan => ../libwekan @@ -11,6 +13,8 @@ require ( github.com/mattn/go-colorable v0.1.13 github.com/ory/dockertest/v3 v3.10.0 github.com/pkg/errors v0.9.1 + github.com/samber/slog-formatter v1.0.0 + github.com/samber/slog-multi v1.0.1 github.com/signaux-faibles/libwekan v0.4.0 github.com/sirupsen/logrus v1.9.3 github.com/snowzach/rotatefilehook v0.0.0-20220211133110-53752135082d @@ -22,6 +26,8 @@ require ( require ( github.com/peterbourgon/diskv/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/samber/lo v1.38.1 // indirect + golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/mod v0.9.0 // indirect golang.org/x/tools v0.7.0 // indirect ) diff --git a/go.sum b/go.sum index b53c5ca..bda99d4 100644 --- a/go.sum +++ b/go.sum @@ -118,6 +118,12 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= +github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samber/slog-formatter v1.0.0 h1:ULxHV+jNqi6aFP8xtzGHl2ejFRMl2+jI2UhCpgoXTDA= +github.com/samber/slog-formatter v1.0.0/go.mod h1:c7pRfwhCfZQNzJz+XirmTveElxXln7M0Y8Pq781uxlo= +github.com/samber/slog-multi v1.0.1 h1:Owf7RnxBZokPuGuuecKH8bEX1iRepjJJgmXd5BTxvl8= +github.com/samber/slog-multi v1.0.1/go.mod h1:uLAvHpGqbYgX4FSL0p1ZwoLuveIAJvBECtE07XmYvFo= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= @@ -174,6 +180,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= diff --git a/keycloak_integration_test.go b/keycloak_integration_test.go index 9a059db..4e7d9b4 100644 --- a/keycloak_integration_test.go +++ b/keycloak_integration_test.go @@ -6,14 +6,16 @@ package main import ( "context" "fmt" + "log" + "os" + "testing" + "github.com/Nerzal/gocloak/v13" + "github.com/stretchr/testify/assert" + "github.com/signaux-faibles/keycloakUpdater/v2/config" "github.com/signaux-faibles/keycloakUpdater/v2/logger" "github.com/signaux-faibles/keycloakUpdater/v2/structs" - "github.com/stretchr/testify/assert" - "log" - "os" - "testing" ) func TestKeycloakConfiguration_access_username_should_be_present_in_stock_file(t *testing.T) { diff --git a/logger/configuration.go b/logger/configuration.go new file mode 100644 index 0000000..1a29b7a --- /dev/null +++ b/logger/configuration.go @@ -0,0 +1,42 @@ +package logger + +import ( + "log/slog" + "os" + + "github.com/samber/slog-formatter" + "github.com/samber/slog-multi" +) + +func configFormatters(timeFormat string) slogmulti.Middleware { + formattingMiddleware := slogformatter.NewFormatterHandler( + timeFormatter(timeFormat), + errorFormatter(), + userFormatter(), + clientFormatter(), + singleRoleFormatter(), + manyRolesFormatter(), + ) + return formattingMiddleware +} + +func configFileHandler(logFilename string) *slog.TextHandler { + var err error + var file *os.File + if file, err = os.OpenFile(logFilename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644); err != nil { + slog.Error("erreur à l'ouverture du fichier de log", slog.String("filename", logFilename), slog.Any("error", err)) + panic(err) + } + return slog.NewTextHandler(file, &slog.HandlerOptions{ + Level: loglevel, + }) +} + +func configLogLevel(configLogLevel string) { + var err error + var level = loglevel.Level() + if level, err = parseLogLevel(configLogLevel); err != nil { + logger.Warn("erreur de configuration sur le log level", slog.String("valeur", configLogLevel)) + } + loglevel.Set(level) +} diff --git a/logger/formatter.go b/logger/formatter.go deleted file mode 100644 index 5c14592..0000000 --- a/logger/formatter.go +++ /dev/null @@ -1,66 +0,0 @@ -package logger - -import ( - "bytes" - "fmt" - "sort" - "strings" - - "github.com/sirupsen/logrus" -) - -type SimpleFormatter struct{} - -func (s *SimpleFormatter) Format(entry *logrus.Entry) ([]byte, error) { - b := &bytes.Buffer{} - concat(b, printTime(entry)) - concat(b, " ") - concat(b, printLevel(entry)) - //concat(b, " ") - //concat(b, printCaller(entry)) - concat(b, "\t") - concat(b, entry.Message) - data := printData(entry) - if len(data) > 0 { - concat(b, "\t- ") - concat(b, data) - } - b.WriteByte('\n') - return b.Bytes(), nil -} - -func concat(b *bytes.Buffer, input string) { - if _, err := fmt.Fprintf(b, input); err != nil { - panic(err) - } -} - -func printData(entry *logrus.Entry) string { - data := entry.Data - if len(data) <= 0 { - return "" - } - // sort data - keys := make([]string, 0, len(data)) - for k := range data { - keys = append(keys, k) - } - sort.Strings(keys) - var s string - for _, k := range keys { - s += k + "=\"" + fmt.Sprintf("%v", data[k]) + "\" " - } - return s -} - -//func printCaller(entry *logrus.Entry) string { -// return entry.Caller.File + ":" + strconv.Itoa(entry.Caller.Line) -//} - -func printLevel(entry *logrus.Entry) string { - return strings.ToUpper("[" + entry.Level.String() + "]") -} - -func printTime(entry *logrus.Entry) string { - return entry.Time.Format("2006-01-02 15:04:05") -} diff --git a/logger/formatters.go b/logger/formatters.go new file mode 100644 index 0000000..b4b9135 --- /dev/null +++ b/logger/formatters.go @@ -0,0 +1,69 @@ +package logger + +import ( + "log/slog" + "strings" + "time" + + "github.com/Nerzal/gocloak/v13" + "github.com/samber/slog-formatter" + slogmulti "github.com/samber/slog-multi" +) + +const defaultTimestampFormat = "2006-01-02 15:04:05" + +func addFormattersToHandler(formatters slogmulti.Middleware, handler slog.Handler) slog.Handler { + return slogmulti.Pipe(formatters).Handler(handler) +} + +func timeFormatter(input string) slogformatter.Formatter { + format := defaultTimestampFormat + if len(input) > 0 { + format = input + } + return slogformatter.TimeFormatter(format, time.UTC) +} + +func errorFormatter() slogformatter.Formatter { + return slogformatter.ErrorFormatter("error") +} + +func clientFormatter() slogformatter.Formatter { + return slogformatter.FormatByType(func(client gocloak.Client) slog.Value { + return slog.StringValue(*client.ClientID) + }) +} + +func userFormatter() slogformatter.Formatter { + return slogformatter.FormatByType(func(user gocloak.User) slog.Value { + return slog.StringValue(*user.Username) + }) +} + +func singleRoleFormatter() slogformatter.Formatter { + return slogformatter.FormatByType(func(role gocloak.Role) slog.Value { + return slog.StringValue(role2string(role)) + }) +} + +func manyRolesFormatter() slogformatter.Formatter { + return slogformatter.FormatByType(func(roles []gocloak.Role) slog.Value { + var val string + if roles == nil { + val = "" + } else { + val = strings.Join(toStrings(roles, role2string), ", ") + } + return slog.StringValue(val) + }) +} + +func toStrings[T any](array []T, toString func(T) string) []string { + y := make([]string, len(array)) + for i, v := range array { + y[i] = toString(v) + } + return y +} + +func role2string(role gocloak.Role) string { return *role.Name } diff --git a/logger/logData.go b/logger/logData.go index 6487255..73c9f8b 100644 --- a/logger/logData.go +++ b/logger/logData.go @@ -1,8 +1,9 @@ package logger import ( - "github.com/Nerzal/gocloak/v13" "strings" + + "github.com/Nerzal/gocloak/v13" ) type Data map[string]interface{} @@ -55,13 +56,3 @@ func (d Data) AddRoles(all []gocloak.Role) { } d["roles"] = val } - -func toStrings[T any](array []T, toString func(T) string) []string { - y := make([]string, len(array)) - for i, v := range array { - y[i] = toString(v) - } - return y -} - -func role2string(role gocloak.Role) string { return *role.Name } diff --git a/logger/logger.go b/logger/logger.go index a720810..3323eed 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -1,154 +1,141 @@ package logger import ( - "github.com/mattn/go-colorable" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" - "github.com/sirupsen/logrus" - "github.com/snowzach/rotatefilehook" + "context" + "log/slog" "os" + "runtime/debug" + "slices" + "strings" + + "github.com/pkg/errors" + slogmulti "github.com/samber/slog-multi" - "github.com/snowzach/writerhook" + "github.com/signaux-faibles/keycloakUpdater/v2/structs" ) -var logger *logrus.Logger +var logger *slog.Logger +var loglevel *slog.LevelVar func init() { - logger = logrus.New() - // formatter - consoleFormatter := &logrus.TextFormatter{ - PadLevelText: true, - ForceColors: true, - FullTimestamp: true, - //TimestampFormat: , - } + loglevel = new(slog.LevelVar) + loglevel.Set(slog.LevelInfo) - logger.SetLevel(logrus.InfoLevel) - logger.SetOutput(colorable.NewColorableStdout()) - logger.SetFormatter(consoleFormatter) + handler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ + Level: loglevel, + }) + parentLogger := slog.New( + handler) + buildInfo, _ := debug.ReadBuildInfo() + sha1 := findBuildSetting(buildInfo.Settings, "vcs.revision") + appLogger := parentLogger.With( + slog.Group("app", slog.String("sha1", sha1)), + ) + slog.SetDefault(appLogger) + logger = appLogger } func ConfigureWith(config structs.LoggerConfig) { - //logger.ReportCaller = true - var err error - - // level - var logLevel logrus.Level - if logLevel, err = logrus.ParseLevel(config.Level); err != nil { - logger.Infof("bad log level '%s' : %s", config.Level, err) - logLevel = logrus.InfoLevel - } - logger.SetLevel(logLevel) - - // console - logger.SetOutput(colorable.NewColorableStdout()) - consoleFormatter := &logrus.TextFormatter{ - PadLevelText: true, - ForceColors: true, - FullTimestamp: true, - TimestampFormat: config.TimestampFormat, - } - logger.SetFormatter(consoleFormatter) - //consoleFormatter := &SimpleFormatter{} - logger.SetFormatter(consoleFormatter) - - // file - fileFormatter := &logrus.TextFormatter{ - DisableColors: true, - TimestampFormat: config.TimestampFormat, - PadLevelText: true, - } - var hook logrus.Hook - if config.Filename != "" { - if config.Rotation { - hook = rotateFileHook(config.Filename, logLevel, fileFormatter) - } else { - hook = simpleFileHook(config.Filename, logLevel, fileFormatter) - } - logger.AddHook(hook) - } + configLogLevel(config.Level) + fileHandler := configFileHandler(config.Filename) + formatters := configFormatters(config.TimestampFormat) + formattedFileHandler := addFormattersToHandler(formatters, fileHandler) + defaultHandler := addFormattersToHandler(formatters, slog.Default().Handler()) + combinedHandlers := slogmulti.Fanout(formattedFileHandler, defaultHandler) + slog.SetDefault(slog.New(combinedHandlers)) + logger.Info("configuration des loggers effectuée", slog.Group( + "config", + slog.String("level", config.Level), + slog.String("filename", config.Filename), + slog.String("timeFormat", config.TimestampFormat), + )) } -func Debugf(msg string, args ...interface{}) { - logger.Debugf(msg, args...) +func Debugf(msg string, args ...any) { + logger.Debug(msg, args...) } func Debug(msg string, data map[string]interface{}) { - logger.WithFields(data).Debug(msg) + logWithContext(slog.LevelDebug, msg, data, nil) } -func Infof(msg string, args ...interface{}) { - logger.Infof(msg, args...) +func Infof(msg string, args ...any) { + logger.Info(msg, args...) } func Info(msg string, data map[string]interface{}) { - logger.WithFields(data).Info(msg) + logWithContext(slog.LevelInfo, msg, data, nil) } func Warnf(msg string, args ...interface{}) { - logger.Warnf(msg, args...) + logger.Warn(msg, args...) } func Warn(msg string, data map[string]interface{}) { - logger.WithFields(data).Warning(msg) + logWithContext(slog.LevelWarn, msg, data, nil) } func WarnE(msg string, data map[string]interface{}, err error) { - context := Data(data) - context.AddError(err) - Warn(msg, data) - context.removeError() + logWithContext(slog.LevelWarn, msg, data, err) } func Error(msg string, data map[string]interface{}) { - logger.WithFields(data).Error(msg) + logWithContext(slog.LevelWarn, msg, data, nil) } func ErrorE(msg string, data map[string]interface{}, err error) { - context := Data(data) - context.AddError(err) - Error(msg, data) - context.removeError() + logWithContext(slog.LevelWarn, msg, data, err) } func Errorf(msg string, args ...interface{}) { - logger.Errorf(msg, args...) + logger.Error(msg, args...) } func Panicf(msg string, args ...interface{}) { - logger.Panicf(msg, args...) + Errorf(msg, args) + panic(msg) } func Panic(err error) { - logger.Panic(err) + Panicf(err.Error()) } -func rotateFileHook(filename string, logLevel logrus.Level, fileFormater logrus.Formatter) logrus.Hook { - - hook, err := rotatefilehook.NewRotateFileHook(rotatefilehook.RotateFileConfig{ - Filename: filename, - MaxSize: 50, // megabytes - MaxBackups: 99, // amouts - MaxAge: 1, //days - Level: logLevel, - Formatter: fileFormater, - }) +func logWithContext(level slog.Level, msg string, data map[string]interface{}, err error) { + var logCtx []any + for k, v := range data { + logCtx = append(logCtx, slog.Any(k, v)) + } if err != nil { - logger.Fatalf("Failed to initialize file rotate hook: %v", err) + logCtx = append(logCtx, slog.String("error", err.Error())) } - return hook + logger.Log(context.Background(), level, msg, logCtx...) } -func simpleFileHook(filename string, logLevel logrus.Level, fileFormater logrus.Formatter) logrus.Hook { - var hook logrus.Hook - var err error - var file *os.File - - if file, err = os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644); err != nil { - logger.Fatalf("Failed to initialize file hook: %v", err) +func findBuildSetting(settings []debug.BuildSetting, search string) string { + retour := "NOT FOUND" + slices.SortFunc(settings, func(s1 debug.BuildSetting, s2 debug.BuildSetting) int { + return strings.Compare(s1.Key, s2.Key) + }) + index, found := slices.BinarySearchFunc(settings, search, func(input debug.BuildSetting, searched string) int { + return strings.Compare(input.Key, searched) + }) + if found { + retour = settings[index].Value } - - if hook, err = writerhook.NewWriterHook(file, logLevel, fileFormater); err != nil { - logger.Fatalf("Failed to initialize file hook: %v", err) + return retour +} + +func parseLogLevel(logLevel string) (slog.Level, error) { + switch strings.ToUpper(logLevel) { + case "DEBUG": + return slog.LevelDebug, nil + case "INFO": + return slog.LevelInfo, nil + case "WARN": + return slog.LevelWarn, nil + case "ERROR": + return slog.LevelError, nil + default: + return slog.LevelInfo, errors.New("log level inconnu : '" + logLevel + "'") } - return hook } diff --git a/logger/logger_test.go b/logger/logger_test.go new file mode 100644 index 0000000..c088bc7 --- /dev/null +++ b/logger/logger_test.go @@ -0,0 +1,9 @@ +package logger + +import ( + "testing" +) + +func Test_merge(t *testing.T) { + logger.Info("coolos moolos") +} diff --git a/structs/structs.go b/structs/structs.go index 33bb465..f2151c2 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -43,7 +43,6 @@ type LoggerConfig struct { Filename string Level string TimestampFormat string - Rotation bool } type WekanBoards []string diff --git a/test/sample/test_config.toml b/test/sample/test_config.toml index 992e7af..1afe2e6 100644 --- a/test/sample/test_config.toml +++ b/test/sample/test_config.toml @@ -8,7 +8,6 @@ realm = "master" filename = "test-initialisation.log" level = "ERROR" timestampFormat = "2006-01-02 15:04:05" -#rotation = false [stock] clientsAndRealmFolder = "test/sample/test_config.d" diff --git a/wekanTaskforce_integration_test.go b/wekanTaskforce_integration_test.go index 4d275f3..e96efa5 100644 --- a/wekanTaskforce_integration_test.go +++ b/wekanTaskforce_integration_test.go @@ -6,12 +6,11 @@ package main import ( - "github.com/signaux-faibles/keycloakUpdater/v2/logger" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" + "testing" + "github.com/signaux-faibles/libwekan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "testing" ) func createBoard(t *testing.T, wekan libwekan.Wekan, suffix string) (libwekan.Board, libwekan.Swimlane, libwekan.List) { @@ -216,9 +215,6 @@ func TestWekanTaskforce_AddMissingRules_whenBoardHasNotLabel(t *testing.T) { func TestWekanTaskforce_RemoveExtraRules_whenUserLosesTaskforce(t *testing.T) { // GIVEN - logger.ConfigureWith(structs.LoggerConfig{ - Level: "ERROR", - }) wekan := restoreMongoDumpInDatabase(mongodb, "", t, "") ass := assert.New(t) @@ -249,10 +245,6 @@ func TestWekanTaskforce_RemoveExtraRules_whenUserLosesTaskforce(t *testing.T) { }, } - logger.ConfigureWith(structs.LoggerConfig{ - Level: "DEBUG", - }) - // WHEN err = pipeline.StopAfter(wekan, users, stageRemoveExtraRulesAndCardMembership) printErrChain(err, 0) @@ -267,9 +259,6 @@ func TestWekanTaskforce_RemoveExtraRules_whenUserLosesTaskforce(t *testing.T) { func TestWekanTaskforce_RemoveExtraRules_whenUserLosesBoard(t *testing.T) { // GIVEN - logger.ConfigureWith(structs.LoggerConfig{ - Level: "ERROR", - }) wekan := restoreMongoDumpInDatabase(mongodb, "", t, "TestWekanTaskforce_RemoveExtraRules_whenUserLosesBoard_Slugboard") ass := assert.New(t) @@ -300,10 +289,6 @@ func TestWekanTaskforce_RemoveExtraRules_whenUserLosesBoard(t *testing.T) { }, } - logger.ConfigureWith(structs.LoggerConfig{ - Level: "INFO", - }) - // WHEN err = pipeline.StopAfter(wekan, users, stageRemoveExtraRulesAndCardMembership) printErrChain(err, 0) @@ -318,9 +303,6 @@ func TestWekanTaskforce_RemoveExtraRules_whenUserLosesBoard(t *testing.T) { func TestWekanTaskforce_RemoveExtraRules_whenUserLosesWekanScope(t *testing.T) { // GIVEN - logger.ConfigureWith(structs.LoggerConfig{ - Level: "INFO", - }) wekan := restoreMongoDumpInDatabase(mongodb, "", t, "") ass := assert.New(t) @@ -351,10 +333,6 @@ func TestWekanTaskforce_RemoveExtraRules_whenUserLosesWekanScope(t *testing.T) { }, } - logger.ConfigureWith(structs.LoggerConfig{ - Level: "INFO", - }) - // WHEN err = pipeline.StopAfter(wekan, users.selectScopeWekan(), stageRemoveExtraRulesAndCardMembership) printErrChain(err, 0) From 92561c2505da1f26eea78970c3fb0deedeb0f08d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Fri, 8 Sep 2023 15:22:06 +0200 Subject: [PATCH 02/41] =?UTF-8?q?retire=20la=20r=C3=A9f=C3=A9rence=20de=20?= =?UTF-8?q?logger=20redondante?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- logger/configuration.go | 4 ++-- logger/logger.go | 15 +++++++-------- logger/logger_test.go | 3 ++- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/logger/configuration.go b/logger/configuration.go index 1a29b7a..88f553d 100644 --- a/logger/configuration.go +++ b/logger/configuration.go @@ -34,9 +34,9 @@ func configFileHandler(logFilename string) *slog.TextHandler { func configLogLevel(configLogLevel string) { var err error - var level = loglevel.Level() + level := loglevel.Level() if level, err = parseLogLevel(configLogLevel); err != nil { - logger.Warn("erreur de configuration sur le log level", slog.String("valeur", configLogLevel)) + slog.Warn("erreur de configuration sur le log level", slog.String("valeur", configLogLevel)) } loglevel.Set(level) } diff --git a/logger/logger.go b/logger/logger.go index 3323eed..5f5c00b 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -14,7 +14,6 @@ import ( "github.com/signaux-faibles/keycloakUpdater/v2/structs" ) -var logger *slog.Logger var loglevel *slog.LevelVar func init() { @@ -32,7 +31,7 @@ func init() { slog.Group("app", slog.String("sha1", sha1)), ) slog.SetDefault(appLogger) - logger = appLogger + //logger = appLogger } func ConfigureWith(config structs.LoggerConfig) { @@ -43,7 +42,7 @@ func ConfigureWith(config structs.LoggerConfig) { defaultHandler := addFormattersToHandler(formatters, slog.Default().Handler()) combinedHandlers := slogmulti.Fanout(formattedFileHandler, defaultHandler) slog.SetDefault(slog.New(combinedHandlers)) - logger.Info("configuration des loggers effectuée", slog.Group( + slog.Info("configuration des loggers effectuée", slog.Group( "config", slog.String("level", config.Level), slog.String("filename", config.Filename), @@ -52,7 +51,7 @@ func ConfigureWith(config structs.LoggerConfig) { } func Debugf(msg string, args ...any) { - logger.Debug(msg, args...) + slog.Debug(msg, args...) } func Debug(msg string, data map[string]interface{}) { @@ -60,7 +59,7 @@ func Debug(msg string, data map[string]interface{}) { } func Infof(msg string, args ...any) { - logger.Info(msg, args...) + slog.Info(msg, args...) } func Info(msg string, data map[string]interface{}) { @@ -68,7 +67,7 @@ func Info(msg string, data map[string]interface{}) { } func Warnf(msg string, args ...interface{}) { - logger.Warn(msg, args...) + slog.Warn(msg, args...) } func Warn(msg string, data map[string]interface{}) { @@ -88,7 +87,7 @@ func ErrorE(msg string, data map[string]interface{}, err error) { } func Errorf(msg string, args ...interface{}) { - logger.Error(msg, args...) + slog.Error(msg, args...) } func Panicf(msg string, args ...interface{}) { @@ -108,7 +107,7 @@ func logWithContext(level slog.Level, msg string, data map[string]interface{}, e if err != nil { logCtx = append(logCtx, slog.String("error", err.Error())) } - logger.Log(context.Background(), level, msg, logCtx...) + slog.Log(context.Background(), level, msg, logCtx...) } func findBuildSetting(settings []debug.BuildSetting, search string) string { diff --git a/logger/logger_test.go b/logger/logger_test.go index c088bc7..24b5db5 100644 --- a/logger/logger_test.go +++ b/logger/logger_test.go @@ -1,9 +1,10 @@ package logger import ( + "log/slog" "testing" ) func Test_merge(t *testing.T) { - logger.Info("coolos moolos") + slog.Info("coolos moolos") } From 92c21f14665919fc8389cb93ebb6df09ebe3f6e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Mon, 11 Sep 2023 16:45:10 +0200 Subject: [PATCH 03/41] =?UTF-8?q?utilise=20le=20nouveau=20system=20de=20lo?= =?UTF-8?q?gger=20de=20go=20(il=20y=20a=20un=20probl=C3=A8me=20sur=20le=20?= =?UTF-8?q?timeformatter=20que=20je=20ne=20m'explique=20pas)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 9 +-- go.sum | 21 +++-- logger/configuration.go | 4 +- logger/formatters.go | 6 +- logger/logger.go | 7 +- logger/logger_test.go | 168 +++++++++++++++++++++++++++++++++++++++- 6 files changed, 186 insertions(+), 29 deletions(-) diff --git a/go.mod b/go.mod index c7aa651..1f2d5c0 100644 --- a/go.mod +++ b/go.mod @@ -10,23 +10,22 @@ require ( github.com/BurntSushi/toml v1.3.2 github.com/Nerzal/gocloak/v13 v13.8.0 github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 - github.com/mattn/go-colorable v0.1.13 github.com/ory/dockertest/v3 v3.10.0 github.com/pkg/errors v0.9.1 github.com/samber/slog-formatter v1.0.0 github.com/samber/slog-multi v1.0.1 github.com/signaux-faibles/libwekan v0.4.0 - github.com/sirupsen/logrus v1.9.3 - github.com/snowzach/rotatefilehook v0.0.0-20220211133110-53752135082d - github.com/snowzach/writerhook v0.0.0-20180327172656-2eef47d6a0bf github.com/stretchr/testify v1.8.4 github.com/tealeg/xlsx/v3 v3.3.0 ) require ( + bou.ke/monkey v1.0.2 // indirect + github.com/jaswdr/faker v1.19.0 // indirect github.com/peterbourgon/diskv/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/samber/lo v1.38.1 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/mod v0.9.0 // indirect golang.org/x/tools v0.7.0 // indirect @@ -55,7 +54,6 @@ require ( github.com/klauspost/compress v1.15.11 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect github.com/mitchellh/mapstructure v1.4.1 // indirect github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect github.com/montanaflynn/stats v0.6.6 // indirect @@ -80,7 +78,6 @@ require ( golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.7.0 // indirect golang.org/x/text v0.8.0 // indirect - gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index bda99d4..ecfa043 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +bou.ke/monkey v1.0.2 h1:kWcnsrCNUatbxncxR/ThdYqbytgOIArtYWqcQLQzKLI= +bou.ke/monkey v1.0.2/go.mod h1:OqickVX3tNx6t33n1xvtTtu85YN5s6cKwVug+oHMaIA= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -41,6 +43,7 @@ github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -65,6 +68,8 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/jaswdr/faker v1.19.0 h1:QUF2faV6vpxQOmrxG+DCPy/fxTomu74jmMNeVbc1LhM= +github.com/jaswdr/faker v1.19.0/go.mod h1:x7ZlyB1AZqwqKZgyQlnqEG8FDptmHlncA5u2zY/yi6w= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= @@ -78,10 +83,7 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2 h1:hRGSmZu7j271trc9sneMrpOW7GN5ngLm8YUZIPzf394= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= @@ -92,6 +94,7 @@ github.com/montanaflynn/stats v0.6.6 h1:Duep6KMIDpY4Yo11iFsvyqJDyfzLF9+sndUKT+v6 github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec= @@ -111,6 +114,7 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.5.0 h1:042Buzk+NhDI+DeSAA62RwJL8VAuZUMQZUjCsRz1Mug= +github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= @@ -135,10 +139,6 @@ github.com/signaux-faibles/libwekan v0.4.0/go.mod h1:CQw3TAfWRiy12eduon5uVEIEwB9 github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/snowzach/rotatefilehook v0.0.0-20220211133110-53752135082d h1:4660u5vJtsyrn3QwJNfESwCws+TM1CMhRn123xjVyQ8= -github.com/snowzach/rotatefilehook v0.0.0-20220211133110-53752135082d/go.mod h1:ZLVe3VfhAuMYLYWliGEydMBoRnfib8EFSqkBYu1ck9E= -github.com/snowzach/writerhook v0.0.0-20180327172656-2eef47d6a0bf h1:77XgkvGrfthe21hzw6tuF6awzp4lgokff0Cs1u3rTm4= -github.com/snowzach/writerhook v0.0.0-20180327172656-2eef47d6a0bf/go.mod h1:xZBBgx0sPyttgxw2yfo1l2FxKZMFCj8XTNSjINpYNtw= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -222,7 +222,6 @@ golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -252,8 +251,7 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= -gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= @@ -262,3 +260,4 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo= +gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= diff --git a/logger/configuration.go b/logger/configuration.go index 88f553d..8d871c5 100644 --- a/logger/configuration.go +++ b/logger/configuration.go @@ -10,8 +10,8 @@ import ( func configFormatters(timeFormat string) slogmulti.Middleware { formattingMiddleware := slogformatter.NewFormatterHandler( - timeFormatter(timeFormat), errorFormatter(), + timeFormatter(timeFormat), userFormatter(), clientFormatter(), singleRoleFormatter(), @@ -34,7 +34,7 @@ func configFileHandler(logFilename string) *slog.TextHandler { func configLogLevel(configLogLevel string) { var err error - level := loglevel.Level() + var level = loglevel.Level() if level, err = parseLogLevel(configLogLevel); err != nil { slog.Warn("erreur de configuration sur le log level", slog.String("valeur", configLogLevel)) } diff --git a/logger/formatters.go b/logger/formatters.go index b4b9135..bd9b983 100644 --- a/logger/formatters.go +++ b/logger/formatters.go @@ -10,18 +10,16 @@ import ( slogmulti "github.com/samber/slog-multi" ) -const defaultTimestampFormat = "2006-01-02 15:04:05" - func addFormattersToHandler(formatters slogmulti.Middleware, handler slog.Handler) slog.Handler { return slogmulti.Pipe(formatters).Handler(handler) } func timeFormatter(input string) slogformatter.Formatter { - format := defaultTimestampFormat + format := time.DateTime if len(input) > 0 { format = input } - return slogformatter.TimeFormatter(format, time.UTC) + return slogformatter.TimeFormatter(format, time.Local) } func errorFormatter() slogformatter.Formatter { diff --git a/logger/logger.go b/logger/logger.go index 5f5c00b..9ae7f5a 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -2,8 +2,8 @@ package logger import ( "context" + "log" "log/slog" - "os" "runtime/debug" "slices" "strings" @@ -20,11 +20,10 @@ func init() { loglevel = new(slog.LevelVar) loglevel.Set(slog.LevelInfo) - handler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ + handler := slog.NewJSONHandler(log.Default().Writer(), &slog.HandlerOptions{ Level: loglevel, }) - parentLogger := slog.New( - handler) + parentLogger := slog.New(handler) buildInfo, _ := debug.ReadBuildInfo() sha1 := findBuildSetting(buildInfo.Settings, "vcs.revision") appLogger := parentLogger.With( diff --git a/logger/logger_test.go b/logger/logger_test.go index 24b5db5..18544f0 100644 --- a/logger/logger_test.go +++ b/logger/logger_test.go @@ -1,10 +1,174 @@ package logger import ( + "fmt" + "io" + "log" "log/slog" + "os" "testing" + "time" + + "bou.ke/monkey" + "github.com/Nerzal/gocloak/v13" + "github.com/jaswdr/faker" + "github.com/stretchr/testify/assert" + + "github.com/signaux-faibles/keycloakUpdater/v2/structs" ) -func Test_merge(t *testing.T) { - slog.Info("coolos moolos") +var fake faker.Faker + +func init() { + fake = faker.New() +} + +func Test_levelConfiguration(t *testing.T) { + ass := assert.New(t) + loggerConfig := structs.LoggerConfig{ + Filename: createTempFilename(t), + Level: "waRN", + TimestampFormat: time.DateTime, + } + ConfigureWith(loggerConfig) + log.Print("message d'info (à l'ancienne)") + slog.Info("message d'info") + slog.Warn("message de warn") + slog.Error("message d'erreur", slog.Any("error", io.EOF)) + + var logsFromFile []byte + var err error + logsFromFile, err = os.ReadFile(loggerConfig.Filename) + ass.NoError(err) + ass.NotContains(string(logsFromFile), "message d'info") + ass.Contains(string(logsFromFile), "message de warn") + ass.Contains(string(logsFromFile), "message d'erreur") +} + +func Test_formatter_User(t *testing.T) { + ass := assert.New(t) + person := fake.Person() + id := person.Contact().Email + username := fake.Internet().User() + firstname := person.FirstName() + lastname := person.LastName() + userToLog := gocloak.User{ + ID: &id, + Username: &username, + FirstName: &firstname, + LastName: &lastname, + } + logger := defaultDebugLogger(t) + ConfigureWith(logger) + key := fake.Lorem().Word() + slog.Info("message d'info", slog.Any(key, userToLog)) + + var logsFromFile []byte + var err error + logsFromFile, err = os.ReadFile(logger.Filename) + ass.NoError(err) + ass.NotContains(string(logsFromFile), id) + ass.NotContains(string(logsFromFile), firstname) + ass.NotContains(string(logsFromFile), lastname) + ass.Contains(string(logsFromFile), key+"="+username) +} + +func Test_formatter_Client(t *testing.T) { + ass := assert.New(t) + id := fake.Person().SSN() + clientId := fake.Person().SSN() + name := fake.Internet().User() + objectToLog := gocloak.Client{ + ClientID: &clientId, + ID: &id, + Name: &name, + } + logger := defaultDebugLogger(t) + ConfigureWith(logger) + key := fake.Lorem().Word() + slog.Info("message d'info", slog.Any(key, objectToLog)) + + var logsFromFile []byte + var err error + logsFromFile, err = os.ReadFile(logger.Filename) + ass.NoError(err) + ass.NotContains(string(logsFromFile), id) + ass.NotContains(string(logsFromFile), name) + ass.Contains(string(logsFromFile), key+"="+clientId) +} + +func Test_formatter_Role(t *testing.T) { + ass := assert.New(t) + id := fake.Person().SSN() + name := fake.Internet().User() + description := fake.Lorem().Text(256) + + objectToLog := gocloak.Role{ + ID: &id, + Name: &name, + Description: &description, + } + logger := defaultDebugLogger(t) + ConfigureWith(logger) + key := fake.Lorem().Word() + slog.Info("message d'info", slog.Any(key, objectToLog)) + + var logsFromFile []byte + var err error + logsFromFile, err = os.ReadFile(logger.Filename) + ass.NoError(err) + ass.NotContains(string(logsFromFile), id) + ass.NotContains(string(logsFromFile), description) + ass.Contains(string(logsFromFile), key+"="+name) +} + +// func Test_formatter_Time(t *testing.T) { +// +// ass := assert.New(t) +// tuTime := time.Date(2023, 9, 11, 15, 47, 32, 99, time.Local) +// FakeTime(t, tuTime) +// t.Cleanup(func() { unfakeTime() }) +// +// timeFormatter := timeFormatter(time.DateTime) +// +// formattingMiddleware := slogformatter.NewFormatterHandler(timeFormatter) +// logFilename := createTempFilename(t) +// logfile, err := os.Create(logFilename) +// ass.NoError(err) +// fileHandler := slog.NewTextHandler(logfile, &slog.HandlerOptions{}) +// +// logger := slog.New(slogmulti.Pipe(formattingMiddleware).Handler(fileHandler)) +// +// logger.Info("message d'info") +// +// var logsFromFile []byte +// logsFromFile, err = os.ReadFile(logFilename) +// ass.NoError(err) +// ass.Contains(string(logsFromFile), "time=2023-09-11 15:47:32") +// } + +func defaultDebugLogger(t *testing.T) structs.LoggerConfig { + loggerConfig := structs.LoggerConfig{ + Filename: createTempFilename(t), + Level: "debug", + TimestampFormat: time.DateTime, + } + return loggerConfig +} + +func createTempFilename(t *testing.T) string { + return fmt.Sprint(t.TempDir(), os.PathSeparator, t.Name()) +} + +// FakeTime méthode qui permet de fausser la méthode `time.Now` en la forçant à toujours retourner +// le paramètre `t` +func FakeTime(test *testing.T, t time.Time) { + monkey.Patch(time.Now, func() time.Time { + return t + }) + test.Cleanup(unfakeTime) +} + +func unfakeTime() { + monkey.Unpatch(time.Now) } From 3770eb9eba337438f28bf4f09166d41ec2817696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Mon, 11 Sep 2023 17:03:15 +0200 Subject: [PATCH 04/41] retire la methode logger.Debugf --- config/config.go | 2 +- go.mod | 2 -- keycloakContext.go | 5 ++++- logger/logger.go | 4 ---- main_integration_test.go | 13 ++++++++----- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/config/config.go b/config/config.go index ddfb76d..e88c93f 100644 --- a/config/config.go +++ b/config/config.go @@ -88,7 +88,7 @@ func getAllConfigFilenames(filename string) []string { for _, f := range files { filename := folder + "/" + f.Name() if !strings.HasSuffix(filename, ".toml") { - logger.Debugf("ignore le fichier de configuration", slog.String("configFilename", filename)) + slog.Debug("ignore le fichier de configuration", slog.String("filename", filename)) continue } r = append(r, filename) diff --git a/go.mod b/go.mod index 1f2d5c0..1acba6f 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,6 @@ go 1.21 toolchain go1.21.1 -// replace github.com/signaux-faibles/libwekan => ../libwekan - require ( github.com/BurntSushi/toml v1.3.2 github.com/Nerzal/gocloak/v13 v13.8.0 diff --git a/keycloakContext.go b/keycloakContext.go index 8a879f6..555410c 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -2,8 +2,11 @@ package main import ( "context" + "log/slog" + "github.com/Nerzal/gocloak/v13" "github.com/pkg/errors" + "github.com/signaux-faibles/keycloakUpdater/v2/logger" "github.com/signaux-faibles/keycloakUpdater/v2/structs" ) @@ -377,7 +380,7 @@ func (kc *KeycloakContext) SaveMasterRealm(input gocloak.RealmRepresentation) { } func (kc *KeycloakContext) refreshRealm(realmName string) { - logger.Debugf("refresh Realm") + slog.Debug("refresh Realm", slog.String("realm", realmName)) realm, err2 := kc.API.GetRealm(context.Background(), kc.JWT.AccessToken, realmName) if err2 != nil { logger.Errorf("Error when fetching Realm : +%v", err2) diff --git a/logger/logger.go b/logger/logger.go index 9ae7f5a..5f318cd 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -49,10 +49,6 @@ func ConfigureWith(config structs.LoggerConfig) { )) } -func Debugf(msg string, args ...any) { - slog.Debug(msg, args...) -} - func Debug(msg string, data map[string]interface{}) { logWithContext(slog.LevelDebug, msg, data, nil) } diff --git a/main_integration_test.go b/main_integration_test.go index b83dbcd..362f9cf 100644 --- a/main_integration_test.go +++ b/main_integration_test.go @@ -8,19 +8,22 @@ import ( "bytes" "context" "fmt" - "github.com/ory/dockertest/v3" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" - "github.com/stretchr/testify/require" "os" "strconv" "testing" "time" + "github.com/ory/dockertest/v3" + "github.com/stretchr/testify/require" + + "github.com/signaux-faibles/keycloakUpdater/v2/structs" + "github.com/ory/dockertest/v3/docker" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" "github.com/signaux-faibles/libwekan" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/signaux-faibles/keycloakUpdater/v2/logger" ) var kc KeycloakContext @@ -117,7 +120,7 @@ func startKeycloak(pool *dockertest.Pool) *dockertest.Resource { logger.ErrorE("Could not set expiration on container keycloak", fields, err) } - logger.Infof("keycloak a démarré avec l'admin %v", keycloakAdmin) + logger.Infof("keycloak a démarré avec l'admin", keycloakAdmin) keycloakPort := keycloak.GetPort("8080/tcp") fields.AddAny("port", keycloakPort) logger.Info("keycloak started", fields) From 64f5d3c396f01d7be8692c594267b3eb256a6fcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Mon, 11 Sep 2023 17:05:04 +0200 Subject: [PATCH 05/41] Revert "retire la methode logger.Debugf" This reverts commit 6c4d7973d88d4fc0668466486fde0b2a9fc46f94. --- config/config.go | 2 +- go.mod | 2 ++ keycloakContext.go | 5 +---- logger/logger.go | 4 ++++ main_integration_test.go | 13 +++++-------- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/config/config.go b/config/config.go index e88c93f..ddfb76d 100644 --- a/config/config.go +++ b/config/config.go @@ -88,7 +88,7 @@ func getAllConfigFilenames(filename string) []string { for _, f := range files { filename := folder + "/" + f.Name() if !strings.HasSuffix(filename, ".toml") { - slog.Debug("ignore le fichier de configuration", slog.String("filename", filename)) + logger.Debugf("ignore le fichier de configuration", slog.String("configFilename", filename)) continue } r = append(r, filename) diff --git a/go.mod b/go.mod index 1acba6f..1f2d5c0 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,8 @@ go 1.21 toolchain go1.21.1 +// replace github.com/signaux-faibles/libwekan => ../libwekan + require ( github.com/BurntSushi/toml v1.3.2 github.com/Nerzal/gocloak/v13 v13.8.0 diff --git a/keycloakContext.go b/keycloakContext.go index 555410c..8a879f6 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -2,11 +2,8 @@ package main import ( "context" - "log/slog" - "github.com/Nerzal/gocloak/v13" "github.com/pkg/errors" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" "github.com/signaux-faibles/keycloakUpdater/v2/structs" ) @@ -380,7 +377,7 @@ func (kc *KeycloakContext) SaveMasterRealm(input gocloak.RealmRepresentation) { } func (kc *KeycloakContext) refreshRealm(realmName string) { - slog.Debug("refresh Realm", slog.String("realm", realmName)) + logger.Debugf("refresh Realm") realm, err2 := kc.API.GetRealm(context.Background(), kc.JWT.AccessToken, realmName) if err2 != nil { logger.Errorf("Error when fetching Realm : +%v", err2) diff --git a/logger/logger.go b/logger/logger.go index 5f318cd..9ae7f5a 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -49,6 +49,10 @@ func ConfigureWith(config structs.LoggerConfig) { )) } +func Debugf(msg string, args ...any) { + slog.Debug(msg, args...) +} + func Debug(msg string, data map[string]interface{}) { logWithContext(slog.LevelDebug, msg, data, nil) } diff --git a/main_integration_test.go b/main_integration_test.go index 362f9cf..b83dbcd 100644 --- a/main_integration_test.go +++ b/main_integration_test.go @@ -8,22 +8,19 @@ import ( "bytes" "context" "fmt" + "github.com/ory/dockertest/v3" + "github.com/signaux-faibles/keycloakUpdater/v2/structs" + "github.com/stretchr/testify/require" "os" "strconv" "testing" "time" - "github.com/ory/dockertest/v3" - "github.com/stretchr/testify/require" - - "github.com/signaux-faibles/keycloakUpdater/v2/structs" - "github.com/ory/dockertest/v3/docker" + "github.com/signaux-faibles/keycloakUpdater/v2/logger" "github.com/signaux-faibles/libwekan" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - - "github.com/signaux-faibles/keycloakUpdater/v2/logger" ) var kc KeycloakContext @@ -120,7 +117,7 @@ func startKeycloak(pool *dockertest.Pool) *dockertest.Resource { logger.ErrorE("Could not set expiration on container keycloak", fields, err) } - logger.Infof("keycloak a démarré avec l'admin", keycloakAdmin) + logger.Infof("keycloak a démarré avec l'admin %v", keycloakAdmin) keycloakPort := keycloak.GetPort("8080/tcp") fields.AddAny("port", keycloakPort) logger.Info("keycloak started", fields) From f02c582911dbc0690518b14e5bdca9a34ce45989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Mon, 11 Sep 2023 17:07:09 +0200 Subject: [PATCH 06/41] Revert "Revert "retire la methode logger.Debugf"" This reverts commit 956473de0ff4f26bb106aa3cdd07fa93779d1edb. --- config/config.go | 2 +- go.mod | 2 -- keycloakContext.go | 5 ++++- logger/logger.go | 4 ---- main_integration_test.go | 13 ++++++++----- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/config/config.go b/config/config.go index ddfb76d..e88c93f 100644 --- a/config/config.go +++ b/config/config.go @@ -88,7 +88,7 @@ func getAllConfigFilenames(filename string) []string { for _, f := range files { filename := folder + "/" + f.Name() if !strings.HasSuffix(filename, ".toml") { - logger.Debugf("ignore le fichier de configuration", slog.String("configFilename", filename)) + slog.Debug("ignore le fichier de configuration", slog.String("filename", filename)) continue } r = append(r, filename) diff --git a/go.mod b/go.mod index 1f2d5c0..1acba6f 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,6 @@ go 1.21 toolchain go1.21.1 -// replace github.com/signaux-faibles/libwekan => ../libwekan - require ( github.com/BurntSushi/toml v1.3.2 github.com/Nerzal/gocloak/v13 v13.8.0 diff --git a/keycloakContext.go b/keycloakContext.go index 8a879f6..555410c 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -2,8 +2,11 @@ package main import ( "context" + "log/slog" + "github.com/Nerzal/gocloak/v13" "github.com/pkg/errors" + "github.com/signaux-faibles/keycloakUpdater/v2/logger" "github.com/signaux-faibles/keycloakUpdater/v2/structs" ) @@ -377,7 +380,7 @@ func (kc *KeycloakContext) SaveMasterRealm(input gocloak.RealmRepresentation) { } func (kc *KeycloakContext) refreshRealm(realmName string) { - logger.Debugf("refresh Realm") + slog.Debug("refresh Realm", slog.String("realm", realmName)) realm, err2 := kc.API.GetRealm(context.Background(), kc.JWT.AccessToken, realmName) if err2 != nil { logger.Errorf("Error when fetching Realm : +%v", err2) diff --git a/logger/logger.go b/logger/logger.go index 9ae7f5a..5f318cd 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -49,10 +49,6 @@ func ConfigureWith(config structs.LoggerConfig) { )) } -func Debugf(msg string, args ...any) { - slog.Debug(msg, args...) -} - func Debug(msg string, data map[string]interface{}) { logWithContext(slog.LevelDebug, msg, data, nil) } diff --git a/main_integration_test.go b/main_integration_test.go index b83dbcd..362f9cf 100644 --- a/main_integration_test.go +++ b/main_integration_test.go @@ -8,19 +8,22 @@ import ( "bytes" "context" "fmt" - "github.com/ory/dockertest/v3" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" - "github.com/stretchr/testify/require" "os" "strconv" "testing" "time" + "github.com/ory/dockertest/v3" + "github.com/stretchr/testify/require" + + "github.com/signaux-faibles/keycloakUpdater/v2/structs" + "github.com/ory/dockertest/v3/docker" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" "github.com/signaux-faibles/libwekan" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" + + "github.com/signaux-faibles/keycloakUpdater/v2/logger" ) var kc KeycloakContext @@ -117,7 +120,7 @@ func startKeycloak(pool *dockertest.Pool) *dockertest.Resource { logger.ErrorE("Could not set expiration on container keycloak", fields, err) } - logger.Infof("keycloak a démarré avec l'admin %v", keycloakAdmin) + logger.Infof("keycloak a démarré avec l'admin", keycloakAdmin) keycloakPort := keycloak.GetPort("8080/tcp") fields.AddAny("port", keycloakPort) logger.Info("keycloak started", fields) From 4fdef663d87287f0877785603093029962d20bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Mon, 11 Sep 2023 17:13:36 +0200 Subject: [PATCH 07/41] retire la methode logger.Infof --- config/config.go | 6 +++--- logger/logger.go | 4 ---- main_integration_test.go | 3 ++- updater.go | 4 +++- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/config/config.go b/config/config.go index e88c93f..be36d81 100644 --- a/config/config.go +++ b/config/config.go @@ -18,10 +18,10 @@ func InitConfig(configFilename string) (structs.Config, error) { func OverrideConfig(original structs.Config, overridingFilename string) structs.Config { if overridingFilename == "" { - logger.Infof("pas de surcharge de configuration") + slog.Debug("pas de surcharge de configuration") return original } - logger.Infof("surcharge de configuration : %s", overridingFilename) + slog.Info("surcharge de configuration", slog.String("filename", overridingFilename)) overridingConfig, err := initConfig(overridingFilename, true) if err != nil { logger.Errorf( @@ -38,7 +38,7 @@ func initConfig(configFilename string, quietly bool) (structs.Config, error) { //var err error //var meta toml.MetaData filenames := getAllConfigFilenames(configFilename) - logger.Infof("config files : %s", filenames) + slog.Info("config files", slog.Any("filenames", filenames)) allConfig := readAllConfigFiles(filenames) for _, current := range allConfig { conf = merge(conf, current) diff --git a/logger/logger.go b/logger/logger.go index 5f318cd..1d5edc6 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -53,10 +53,6 @@ func Debug(msg string, data map[string]interface{}) { logWithContext(slog.LevelDebug, msg, data, nil) } -func Infof(msg string, args ...any) { - slog.Info(msg, args...) -} - func Info(msg string, data map[string]interface{}) { logWithContext(slog.LevelInfo, msg, data, nil) } diff --git a/main_integration_test.go b/main_integration_test.go index 362f9cf..b5df516 100644 --- a/main_integration_test.go +++ b/main_integration_test.go @@ -8,6 +8,7 @@ import ( "bytes" "context" "fmt" + "log/slog" "os" "strconv" "testing" @@ -120,7 +121,7 @@ func startKeycloak(pool *dockertest.Pool) *dockertest.Resource { logger.ErrorE("Could not set expiration on container keycloak", fields, err) } - logger.Infof("keycloak a démarré avec l'admin", keycloakAdmin) + slog.Info("keycloak a démarré avec l'admin", slog.String("name", keycloakAdmin)) keycloakPort := keycloak.GetPort("8080/tcp") fields.AddAny("port", keycloakPort) logger.Info("keycloak started", fields) diff --git a/updater.go b/updater.go index 637fd78..a70cdb5 100644 --- a/updater.go +++ b/updater.go @@ -3,11 +3,13 @@ package main import ( "context" "fmt" + "log/slog" "sort" "strconv" "github.com/Nerzal/gocloak/v13" "github.com/pkg/errors" + "github.com/signaux-faibles/keycloakUpdater/v2/logger" ) @@ -72,7 +74,7 @@ func UpdateKeycloak( if err != nil { logger.ErrorE("failed creating new roles", fields, err) } - logger.Infof("%d roles created", i) + slog.Info("roles created", slog.Int("size", i)) // check and adjust composite roles if err = kc.ComposeRoles(clientId, compositeRoles); err != nil { From 8ab2bd88656726f3a89426380aa0e83ebd333b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Mon, 11 Sep 2023 17:20:59 +0200 Subject: [PATCH 08/41] retire la methode logger.Warnf --- config/config.go | 8 ++++++-- logger/logger.go | 4 ---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/config.go b/config/config.go index be36d81..5cfec69 100644 --- a/config/config.go +++ b/config/config.go @@ -73,7 +73,7 @@ func getAllConfigFilenames(filename string) []string { } folder := config.Stock.ClientsAndRealmFolder if folder == "" { - logger.Warnf("no configuration folder is defined") + slog.Warn("no configuration folder is defined") return r } stockFilename := config.Stock.UsersAndRolesFilename @@ -105,7 +105,11 @@ func extractConfig(filename string) structs.Config { } if meta.Undecoded() != nil { for _, key := range meta.Undecoded() { - logger.Warnf("Caution : key '%s' from config file '%s' is not used", key, filename) + slog.Warn( + "Attention : la clé du fichier de configuration n'est pas utilisée", + slog.String("clé", key.String()), + slog.String("filename", filename), + ) } } return conf diff --git a/logger/logger.go b/logger/logger.go index 1d5edc6..39349af 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -57,10 +57,6 @@ func Info(msg string, data map[string]interface{}) { logWithContext(slog.LevelInfo, msg, data, nil) } -func Warnf(msg string, args ...interface{}) { - slog.Warn(msg, args...) -} - func Warn(msg string, data map[string]interface{}) { logWithContext(slog.LevelWarn, msg, data, nil) } From ce1b37ffa122e8c2008912787e931452b20f5a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Mon, 11 Sep 2023 22:05:50 +0200 Subject: [PATCH 09/41] retire la methode logger.Errorf --- config/config.go | 8 ++++---- config/merge.go | 40 +++++++++++++++++++++------------------- keycloakContext.go | 8 ++++---- logger/logger.go | 6 +----- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/config/config.go b/config/config.go index 5cfec69..d56bbf5 100644 --- a/config/config.go +++ b/config/config.go @@ -24,10 +24,10 @@ func OverrideConfig(original structs.Config, overridingFilename string) structs. slog.Info("surcharge de configuration", slog.String("filename", overridingFilename)) overridingConfig, err := initConfig(overridingFilename, true) if err != nil { - logger.Errorf( - "erreur pendant la récupération de la surcharge de configuration '%s' : %s", - overridingFilename, - err) + slog.Error( + "erreur pendant la récupération de la surcharge de configuration", + slog.String("filename", overridingFilename), + slog.Any("error", err)) return original } return merge(original, overridingConfig) diff --git a/config/merge.go b/config/merge.go index c9a16b6..49c1069 100644 --- a/config/merge.go +++ b/config/merge.go @@ -1,29 +1,31 @@ package config import ( - "github.com/Nerzal/gocloak/v13" - "github.com/imdario/mergo" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" + "log/slog" + + "github.com/Nerzal/gocloak/v13" + "github.com/imdario/mergo" + + "github.com/signaux-faibles/keycloakUpdater/v2/structs" ) func merge(first structs.Config, second structs.Config) structs.Config { - allClients := concatClients(first.Clients, second.Clients) - err := mergo.Merge(&first, second, mergo.WithOverride) - if err != nil { - logger.Errorf("erreur pendant le merging de la configuration : %s", err) - } - first.Clients = allClients - return first + allClients := concatClients(first.Clients, second.Clients) + err := mergo.Merge(&first, second, mergo.WithOverride) + if err != nil { + slog.Error("erreur pendant le merging de la configuration", slog.Any("error", err)) + } + first.Clients = allClients + return first } func concatClients(first []*gocloak.Client, second []*gocloak.Client) []*gocloak.Client { - r := make([]*gocloak.Client, 0) - if first != nil { - r = append(r, first[:]...) - } - if second != nil { - r = append(r, second[:]...) - } - return r + r := make([]*gocloak.Client, 0) + if first != nil { + r = append(r, first[:]...) + } + if second != nil { + r = append(r, second[:]...) + } + return r } diff --git a/keycloakContext.go b/keycloakContext.go index 555410c..73554a6 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -381,10 +381,10 @@ func (kc *KeycloakContext) SaveMasterRealm(input gocloak.RealmRepresentation) { func (kc *KeycloakContext) refreshRealm(realmName string) { slog.Debug("refresh Realm", slog.String("realm", realmName)) - realm, err2 := kc.API.GetRealm(context.Background(), kc.JWT.AccessToken, realmName) - if err2 != nil { - logger.Errorf("Error when fetching Realm : +%v", err2) - panic(err2) + realm, err := kc.API.GetRealm(context.Background(), kc.JWT.AccessToken, realmName) + if err != nil { + slog.Error("Erreur pendant la récupération du Realm", slog.Any("error", err)) + panic(err) } kc.Realm = realm } diff --git a/logger/logger.go b/logger/logger.go index 39349af..ea22754 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -73,12 +73,8 @@ func ErrorE(msg string, data map[string]interface{}, err error) { logWithContext(slog.LevelWarn, msg, data, err) } -func Errorf(msg string, args ...interface{}) { +func Panicf(msg string, args ...any) { slog.Error(msg, args...) -} - -func Panicf(msg string, args ...interface{}) { - Errorf(msg, args) panic(msg) } From b4a1db834cc1b6466044d1bc66fde69378978f98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Tue, 12 Sep 2023 15:37:21 +0200 Subject: [PATCH 10/41] retire la methode logger.Panic... --- config/config.go | 29 ++++++++++++++++++++++++----- logger/logger.go | 9 --------- main.go | 12 +++++++++--- main_integration_test.go | 17 ++++++++--------- updater.go | 18 ++++++++++++------ 5 files changed, 53 insertions(+), 32 deletions(-) diff --git a/config/config.go b/config/config.go index d56bbf5..5ad7216 100644 --- a/config/config.go +++ b/config/config.go @@ -8,7 +8,6 @@ import ( "github.com/BurntSushi/toml" "github.com/pkg/errors" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" "github.com/signaux-faibles/keycloakUpdater/v2/structs" ) @@ -63,7 +62,12 @@ func getAllConfigFilenames(filename string) []string { // checking file exist var err error if _, err = os.Open(filename); err != nil { - logger.Panicf("error reading clients config file : %s", err) + slog.Error( + "error pendant la lecture des du fichier de configuration", + slog.String("filename", filename), + slog.Any("error", err), + ) + panic(err) } r = append(r, filename) var files []os.DirEntry @@ -79,11 +83,21 @@ func getAllConfigFilenames(filename string) []string { stockFilename := config.Stock.UsersAndRolesFilename if stockFilename != "" { if _, err = os.ReadFile(stockFilename); err != nil { - logger.Panicf("error reading stock file '%s' : %s", stockFilename, err) + slog.Error( + "error pendant la lecture des du fichier stock", + slog.String("filename", stockFilename), + slog.Any("error", err), + ) + panic(err) } } if files, err = os.ReadDir(folder); err != nil { - logger.Panicf("error reading clients config folder : %s", err) + slog.Error( + "error pendant la lecture des clients Keycloak", + slog.Any("folder", folder), + slog.Any("error", err), + ) + panic(err) } for _, f := range files { filename := folder + "/" + f.Name() @@ -101,7 +115,12 @@ func extractConfig(filename string) structs.Config { var err error var meta toml.MetaData if meta, err = toml.DecodeFile(filename, &conf); err != nil { - logger.Panicf("error decoding toml config file '%s': %s", filename, err) + slog.Error( + "error pendant le décodage du fichier de configuration Toml", + slog.Any("filename", filename), + slog.Any("error", err), + ) + panic(err) } if meta.Undecoded() != nil { for _, key := range meta.Undecoded() { diff --git a/logger/logger.go b/logger/logger.go index ea22754..8968029 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -73,15 +73,6 @@ func ErrorE(msg string, data map[string]interface{}, err error) { logWithContext(slog.LevelWarn, msg, data, err) } -func Panicf(msg string, args ...any) { - slog.Error(msg, args...) - panic(msg) -} - -func Panic(err error) { - Panicf(err.Error()) -} - func logWithContext(level slog.Level, msg string, data map[string]interface{}, err error) { var logCtx []any for k, v := range data { diff --git a/main.go b/main.go index d9c8ba5..106e1bd 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,10 @@ package main import ( "flag" "fmt" + "log/slog" + "github.com/pkg/errors" + "github.com/signaux-faibles/keycloakUpdater/v2/config" "github.com/signaux-faibles/keycloakUpdater/v2/logger" ) @@ -35,14 +38,16 @@ func main() { logger.Info("lecture du fichier excel stock", fields) users, compositeRoles, err := loadExcel(conf.Stock.UsersAndRolesFilename) if err != nil { - logger.Panic(err) + slog.Error("erreur pendant la lecture du fichier Excel", slog.Any("error", err)) + panic(err) } if conf.Keycloak != nil { clientId := conf.Stock.ClientForRoles kc, err := NewKeycloakContext(conf.Keycloak) if err != nil { - logger.Panic(err) + slog.Error("erreur pendant l'initialisation du contexte Keycloak'", slog.Any("error", err)) + panic(err) } if err = UpdateKeycloak( @@ -55,7 +60,8 @@ func main() { Username(conf.Keycloak.Username), conf.Stock.MaxChangesToAccept, ); err != nil { - logger.Panic(err) + slog.Error("erreur pendant la mise à jour de Keycloak", slog.Any("error", err)) + panic(err) } } diff --git a/main_integration_test.go b/main_integration_test.go index b5df516..eab1d72 100644 --- a/main_integration_test.go +++ b/main_integration_test.go @@ -50,16 +50,12 @@ func TestMain(m *testing.M) { Level: "DEBUG", }) if err != nil { - logger.Panicf("Could not connect to docker: %s", err) + slog.Error("erreur pendant la connection à Docker", slog.Any("error", err)) + panic(err) } - var keycloak *dockertest.Resource - - keycloak = startKeycloak(pool) + keycloak := startKeycloak(pool) mongodb = startWekanDB(pool) - if err != nil { - logger.Panicf("Could not read excel test cases") - } code := m.Run() @@ -75,7 +71,8 @@ func kill(resource *dockertest.Resource) { return } if err := resource.Close(); err != nil { - logger.Panicf("Could not purge resource: %s", err) + slog.Error("erreur pendant la purge des ressources Docker", slog.Any("error", err)) + panic(err) } } @@ -114,6 +111,7 @@ func startKeycloak(pool *dockertest.Pool) *dockertest.Resource { if err != nil { kill(keycloak) logger.ErrorE("Could not start keycloak", fields, err) + panic(err) } // container stops after 120 seconds if err = keycloak.Expire(600); err != nil { @@ -135,7 +133,8 @@ func startKeycloak(pool *dockertest.Pool) *dockertest.Resource { } return nil }); err != nil { - logger.Panicf("Could not connect to keycloak: %s", err) + slog.Error("erreur pendant la connexion à Keycloak", slog.Any("error", err)) + panic(err) } logger.Info("keycloak est prêt", fields) return keycloak diff --git a/updater.go b/updater.go index a70cdb5..4095410 100644 --- a/updater.go +++ b/updater.go @@ -72,31 +72,37 @@ func UpdateKeycloak( i, err := kc.CreateClientRoles(clientId, newRoles) if err != nil { - logger.ErrorE("failed creating new roles", fields, err) + slog.Error("erreur pendant l'écriture des nouveaux rôles", slog.Any("error", err)) + panic(err) } slog.Info("roles created", slog.Int("size", i)) // check and adjust composite roles if err = kc.ComposeRoles(clientId, compositeRoles); err != nil { - logger.Panic(err) + slog.Error("erreur pendant l'écriture des rôles composés", slog.Any("error", err)) + panic(err) } if err = kc.CreateUsers(missing, users, clientId); err != nil { - logger.Panic(err) + slog.Error("erreur pendant la création des utilisateurs", slog.Any("error", err)) + panic(err) } // disable obsolete users if err = kc.DisableUsers(obsolete, clientId); err != nil { - logger.Panic(err) + slog.Error("erreur pendant la désactivation des utilisateurs", slog.Any("error", err)) + panic(err) } // enable existing but disabled users if err = kc.EnableUsers(update); err != nil { - logger.Panic(err) + slog.Error("erreur pendant l'activation des utilisateurs", slog.Any("error", err)) + panic(err) } // make sure every on has correct roles if err = kc.UpdateCurrentUsers(current, users, clientId); err != nil { - logger.Panic(err) + slog.Error("erreur pendant la mise à jour des utilisateurs", slog.Any("error", err)) + panic(err) } // delete old roles From 90fda04073c2200ea023650e94b12ca4c4f11ce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Tue, 12 Sep 2023 15:49:18 +0200 Subject: [PATCH 11/41] retire la methode logger.WarnE --- keycloakContext.go | 26 +++++++++++++------------- logger/logger.go | 10 +--------- main.go | 2 +- main_integration_test.go | 6 +++--- roles.go | 10 ++++++---- wekanUsers.go | 12 +++++++----- 6 files changed, 31 insertions(+), 35 deletions(-) diff --git a/keycloakContext.go b/keycloakContext.go index 73554a6..7391314 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -96,7 +96,7 @@ func (kc *KeycloakContext) CreateClientRoles(clientID string, roles Roles) (int, defer func() { if err := kc.refreshClientRoles(); err != nil { - logger.ErrorE("error refreshing client roles", fields, err) + logger.Error("error refreshing client roles", fields, err) panic(err) } }() @@ -195,10 +195,10 @@ func (kc *KeycloakContext) CreateUsers(users []gocloak.User, userMap Users, clie for _, user := range users { fields := logger.DataForMethod("kc.CreateUsers") fields.AddUser(user) - logger.Info("creating user", fields) + logger.Info("crée l'utilisateur Keycloak", fields) u, err := kc.API.CreateUser(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), user) if err != nil { - logger.WarnE("unable to create user", fields, err) + logger.Error("Erreur keycloak pendant la création de l'utilisateur", fields, err) } configRoles := userMap[Username(*user.Username)].getRoles() @@ -207,7 +207,7 @@ func (kc *KeycloakContext) CreateUsers(users []gocloak.User, userMap Users, clie if roles != nil { logger.Info("adding roles to user", fields) if err = kc.AddClientRolesToUser(internalID, u, roles); err != nil { - logger.ErrorE("error adding client roles", fields, err) + logger.Error("error adding client roles", fields, err) return err } } else { @@ -246,12 +246,12 @@ func (kc *KeycloakContext) disableUser(u gocloak.User, internalClientID string) logger.Info("disabling user", fields) err := kc.API.UpdateUser(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), u) if err != nil { - logger.WarnE("error disabling user", fields, err) + logger.Error("error disabling user", fields, err) return err } roles, err := kc.API.GetClientRolesByUserID(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), internalClientID, *u.ID) if err != nil { - logger.WarnE("failed to retrieve roles for user", fields, err) + logger.Error("failed to retrieve roles for user", fields, err) } var ro []gocloak.Role for _, r := range roles { @@ -261,7 +261,7 @@ func (kc *KeycloakContext) disableUser(u gocloak.User, internalClientID string) logger.Info("remove roles from user", fields) err = kc.API.DeleteClientRolesFromUser(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), internalClientID, *u.ID, ro) if err != nil { - logger.WarnE("failed to remove roles", fields, err) + logger.Error("failed to remove roles", fields, err) return err } return nil @@ -277,7 +277,7 @@ func (kc *KeycloakContext) EnableUsers(users []gocloak.User) error { user.Enabled = &t err := kc.API.UpdateUser(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), user) if err != nil { - logger.WarnE("failed to enable user", fields, err) + logger.Error("failed to enable user", fields, err) } } err := kc.refreshUsers() @@ -323,7 +323,7 @@ func (kc KeycloakContext) UpdateCurrentUsers(users []gocloak.User, userMap Users logger.Info("updating user name and attributes", fields) err := kc.API.UpdateUser(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), update) if err != nil { - logger.WarnE("failed to update user names", fields, err) + logger.Error("failed to update user names", fields, err) return err } } @@ -334,7 +334,7 @@ func (kc KeycloakContext) UpdateCurrentUsers(users []gocloak.User, userMap Users logger.Info("deleting unused roles", fields) err = kc.API.DeleteClientRolesFromUser(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), internalID, *user.ID, kc.FindKeycloakRoles(clientName, old)) if err != nil { - logger.WarnE("failed to delete roles", fields, err) + logger.Error("failed to delete roles", fields, err) } fields.Remove("oldRoles") } @@ -345,7 +345,7 @@ func (kc KeycloakContext) UpdateCurrentUsers(users []gocloak.User, userMap Users keycloakRoles := kc.FindKeycloakRoles(clientName, novel) err = kc.AddClientRolesToUser(internalID, *user.ID, keycloakRoles) if err != nil { - logger.WarnE("failed to add roles", fields, err) + logger.Error("failed to add roles", fields, err) } fields.Remove("novelRoles") } @@ -355,7 +355,7 @@ func (kc KeycloakContext) UpdateCurrentUsers(users []gocloak.User, userMap Users logger.Info("disabling account management", fields) err = kc.API.DeleteClientRolesFromUser(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), accountInternalID, *user.ID, kc.FindKeycloakRoles("account", accountRoles)) if err != nil { - logger.WarnE("failed to disable management", fields, err) + logger.Error("failed to disable management", fields, err) } fields.Remove("accountRoles") } @@ -372,7 +372,7 @@ func (kc *KeycloakContext) SaveMasterRealm(input gocloak.RealmRepresentation) { input.Realm = &id logger.Info("update realm", fields) if err := kc.API.UpdateRealm(context.Background(), kc.JWT.AccessToken, input); err != nil { - logger.ErrorE("Error when updating Realm ", fields, err) + logger.Error("Error when updating Realm ", fields, err) panic(err) } diff --git a/logger/logger.go b/logger/logger.go index 8968029..4660772 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -61,15 +61,7 @@ func Warn(msg string, data map[string]interface{}) { logWithContext(slog.LevelWarn, msg, data, nil) } -func WarnE(msg string, data map[string]interface{}, err error) { - logWithContext(slog.LevelWarn, msg, data, err) -} - -func Error(msg string, data map[string]interface{}) { - logWithContext(slog.LevelWarn, msg, data, nil) -} - -func ErrorE(msg string, data map[string]interface{}, err error) { +func Error(msg string, data map[string]interface{}, err error) { logWithContext(slog.LevelWarn, msg, data, err) } diff --git a/main.go b/main.go index 106e1bd..8dafa61 100644 --- a/main.go +++ b/main.go @@ -76,7 +76,7 @@ func main() { } if err != nil { - logger.ErrorE("le traitement s'est terminé de façon anormale", fields, err) + logger.Error("le traitement s'est terminé de façon anormale", fields, err) fmt.Println("======= Détail de l'erreur") printErrChain(err, 0) } else { diff --git a/main_integration_test.go b/main_integration_test.go index eab1d72..d956b5d 100644 --- a/main_integration_test.go +++ b/main_integration_test.go @@ -110,13 +110,13 @@ func startKeycloak(pool *dockertest.Pool) *dockertest.Resource { ) if err != nil { kill(keycloak) - logger.ErrorE("Could not start keycloak", fields, err) + logger.Error("Could not start keycloak", fields, err) panic(err) } // container stops after 120 seconds if err = keycloak.Expire(600); err != nil { kill(keycloak) - logger.ErrorE("Could not set expiration on container keycloak", fields, err) + logger.Error("Could not set expiration on container keycloak", fields, err) } slog.Info("keycloak a démarré avec l'admin", slog.String("name", keycloakAdmin)) @@ -209,7 +209,7 @@ func restoreMongoDumpInDatabase(mongodb *dockertest.Resource, suffix string, t * logger.Info("Restaure le dump", fields) if exitCode, err := mongodb.Exec([]string{"/bin/bash", "-c", command}, dockerOptions); err != nil { fields.AddAny("exitCode", exitCode) - logger.ErrorE("Erreur lors de la restauration du dump", fields, err) + logger.Error("Erreur lors de la restauration du dump", fields, err) require.Nil(t, err) } err := outputWriter.Flush() diff --git a/roles.go b/roles.go index 996a380..5c1770c 100644 --- a/roles.go +++ b/roles.go @@ -3,7 +3,9 @@ package main import ( "context" "fmt" + "github.com/Nerzal/gocloak/v13" + "github.com/signaux-faibles/keycloakUpdater/v2/logger" ) @@ -119,21 +121,21 @@ func (kc KeycloakContext) ComposeRoles(clientID string, compositeRoles Composite logger.Info("add composite roles", fields) err := kc.API.AddClientRoleComposite(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), *gocloakRole.ID, gocloakRoles) if err != nil { - logger.WarnE("error from keycloak", fields, err) + logger.Error("error from keycloak", fields, err) } } // Clean composite roles internalID, err := kc.GetInternalIDFromClientID(clientID) if err != nil { - logger.WarnE("can't resolve client", fields, err) + logger.Error("can't resolve client", fields, err) } for _, r := range kc.ClientRoles[clientID] { fields.AddRole(*r) composingRoles, err := kc.API.GetCompositeClientRolesByRoleID(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), internalID, *r.ID) if err != nil { - logger.ErrorE("error when searching composite client role", fields, err) + logger.Error("error when searching composite client role", fields, err) } wantedRoles := compositeRoles[*r.Name] var deleteRoles []gocloak.Role @@ -146,7 +148,7 @@ func (kc KeycloakContext) ComposeRoles(clientID string, compositeRoles Composite fields.AddRoles(deleteRoles) logger.Info("removing composing role(s)", fields) if err = kc.API.DeleteClientRoleComposite(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), *r.ID, deleteRoles); err != nil { - logger.ErrorE("Error deleting client role composite", fields, err) + logger.Error("Error deleting client role composite", fields, err) } } } diff --git a/wekanUsers.go b/wekanUsers.go index ff22acc..d670b4e 100644 --- a/wekanUsers.go +++ b/wekanUsers.go @@ -3,9 +3,11 @@ package main import ( "context" "fmt" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" - "github.com/signaux-faibles/libwekan" "strings" + + "github.com/signaux-faibles/libwekan" + + "github.com/signaux-faibles/keycloakUpdater/v2/logger" ) var GENUINEUSERSELECTOR = []func(wekan libwekan.Wekan, user libwekan.User) bool{ @@ -86,7 +88,7 @@ func insertUsers(ctx context.Context, wekan libwekan.Wekan, users libwekan.Users logger.Info(">>> crée l'utilisateur", fields) err := wekan.InsertUser(ctx, user) if err != nil { - logger.Error(err.Error(), fields) + logger.Error("erreur Wekan pendant la création des utilisateurs", fields, err) return err } } @@ -108,7 +110,7 @@ func ensureUsersAreEnabled(ctx context.Context, wekan libwekan.Wekan, users libw continue } if err != nil { - logger.Error(err.Error(), fields) + logger.Error("erreur Wekan pendant la radiation des utilisateurs", fields, err) return err } logger.Info(">>> active l'utilisateur", fields) @@ -128,7 +130,7 @@ func ensureUsersAreDisabled(ctx context.Context, wekan libwekan.Wekan, users lib continue } if err != nil { - logger.Error(err.Error(), fields) + logger.Error("erreur Wekan pendant l'examen du statut des utilisateurs", fields, err) return err } logger.Info(">>> désactive l'utilisateur", fields) From 710cd34ed961f5c9421d7c2caf66db66ac641fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Tue, 12 Sep 2023 16:40:49 +0200 Subject: [PATCH 12/41] retire le package slog des packages --- config/config.go | 64 +++++++++++++++++++----------------- config/merge.go | 5 ++- keycloakContext.go | 16 ++++----- keycloak_integration_test.go | 2 +- logger/logData.go | 41 ++++++++++++++++------- logger/logger.go | 11 +++++-- main.go | 2 +- main_integration_test.go | 37 ++++++++++----------- roles.go | 2 +- updater.go | 4 +-- wekan.go | 6 ++-- wekanBoardsMembers.go | 12 ++++--- wekanTaskforce.go | 18 +++++----- wekanUsers.go | 8 ++--- 14 files changed, 128 insertions(+), 100 deletions(-) diff --git a/config/config.go b/config/config.go index 5ad7216..9308fa7 100644 --- a/config/config.go +++ b/config/config.go @@ -1,13 +1,13 @@ package config import ( - "log/slog" "os" "strings" "github.com/BurntSushi/toml" "github.com/pkg/errors" + "github.com/signaux-faibles/keycloakUpdater/v2/logger" "github.com/signaux-faibles/keycloakUpdater/v2/structs" ) @@ -17,16 +17,17 @@ func InitConfig(configFilename string) (structs.Config, error) { func OverrideConfig(original structs.Config, overridingFilename string) structs.Config { if overridingFilename == "" { - slog.Debug("pas de surcharge de configuration") + logger.Debug("pas de surcharge de configuration", nil) return original } - slog.Info("surcharge de configuration", slog.String("filename", overridingFilename)) + logContext := logger.ContextForMethode(OverrideConfig) + logger.Info("surcharge de configuration", logContext.AddAny("filename", overridingFilename)) overridingConfig, err := initConfig(overridingFilename, true) if err != nil { - slog.Error( + logger.Error( "erreur pendant la récupération de la surcharge de configuration", - slog.String("filename", overridingFilename), - slog.Any("error", err)) + logContext.AddAny("filename", overridingFilename), + err) return original } return merge(original, overridingConfig) @@ -37,7 +38,11 @@ func initConfig(configFilename string, quietly bool) (structs.Config, error) { //var err error //var meta toml.MetaData filenames := getAllConfigFilenames(configFilename) - slog.Info("config files", slog.Any("filenames", filenames)) + + logger.Info( + "config files", + logger.ContextForMethode(initConfig).AddArray("filenames", filenames), + ) allConfig := readAllConfigFiles(filenames) for _, current := range allConfig { conf = merge(conf, current) @@ -59,15 +64,15 @@ func readAllConfigFiles(filenames []string) []structs.Config { func getAllConfigFilenames(filename string) []string { var r = make([]string, 0) + logContext := logger.ContextForMethode(getAllConfigFilenames) // checking file exist var err error if _, err = os.Open(filename); err != nil { - slog.Error( - "error pendant la lecture des du fichier de configuration", - slog.String("filename", filename), - slog.Any("error", err), + logger.Panic( + "erreur pendant la lecture des du fichier de configuration", + logContext.AddAny("filename", filename), + err, ) - panic(err) } r = append(r, filename) var files []os.DirEntry @@ -77,32 +82,30 @@ func getAllConfigFilenames(filename string) []string { } folder := config.Stock.ClientsAndRealmFolder if folder == "" { - slog.Warn("no configuration folder is defined") + logger.Warn("Attention : aucun répertoire de configuration n'est défini", logContext) return r } stockFilename := config.Stock.UsersAndRolesFilename if stockFilename != "" { if _, err = os.ReadFile(stockFilename); err != nil { - slog.Error( - "error pendant la lecture des du fichier stock", - slog.String("filename", stockFilename), - slog.Any("error", err), + logger.Panic( + "erreur pendant la lecture des du fichier stock", + logContext.AddAny("filename", stockFilename), + err, ) - panic(err) } } if files, err = os.ReadDir(folder); err != nil { - slog.Error( - "error pendant la lecture des clients Keycloak", - slog.Any("folder", folder), - slog.Any("error", err), + logger.Panic( + "erreur pendant la lecture des clients Keycloak", + logContext.AddAny("folder", folder), + err, ) - panic(err) } for _, f := range files { filename := folder + "/" + f.Name() if !strings.HasSuffix(filename, ".toml") { - slog.Debug("ignore le fichier de configuration", slog.String("filename", filename)) + logger.Debug("ignore le fichier de configuration", logContext.AddAny("filename", filename)) continue } r = append(r, filename) @@ -111,23 +114,22 @@ func getAllConfigFilenames(filename string) []string { } func extractConfig(filename string) structs.Config { + logContext := logger.ContextForMethode(extractConfig) var conf structs.Config var err error var meta toml.MetaData if meta, err = toml.DecodeFile(filename, &conf); err != nil { - slog.Error( + logger.Panic( "error pendant le décodage du fichier de configuration Toml", - slog.Any("filename", filename), - slog.Any("error", err), + logContext.AddAny("filename", filename), + err, ) - panic(err) } if meta.Undecoded() != nil { for _, key := range meta.Undecoded() { - slog.Warn( + logger.Warn( "Attention : la clé du fichier de configuration n'est pas utilisée", - slog.String("clé", key.String()), - slog.String("filename", filename), + logContext.AddAny("clé", key.String()).AddAny("filename", filename), ) } } diff --git a/config/merge.go b/config/merge.go index 49c1069..061170b 100644 --- a/config/merge.go +++ b/config/merge.go @@ -1,11 +1,10 @@ package config import ( - "log/slog" - "github.com/Nerzal/gocloak/v13" "github.com/imdario/mergo" + "github.com/signaux-faibles/keycloakUpdater/v2/logger" "github.com/signaux-faibles/keycloakUpdater/v2/structs" ) @@ -13,7 +12,7 @@ func merge(first structs.Config, second structs.Config) structs.Config { allClients := concatClients(first.Clients, second.Clients) err := mergo.Merge(&first, second, mergo.WithOverride) if err != nil { - slog.Error("erreur pendant le merging de la configuration", slog.Any("error", err)) + logger.Error("erreur pendant le merging de la configuration", logger.ContextForMethode(merge), err) } first.Clients = allClients return first diff --git a/keycloakContext.go b/keycloakContext.go index 7391314..7405593 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -29,7 +29,7 @@ func NewKeycloakContext(access *structs.Keycloak) (KeycloakContext, error) { // Init provides a connected keycloak context object func Init(hostname, realm, username, password string) (KeycloakContext, error) { - fields := logger.DataForMethod("Init") + fields := logger.ContextForMethod("Init") fields.AddAny("path", hostname) fields.AddAny("realm", realm) fields.AddAny("user", username) @@ -92,7 +92,7 @@ func (kc KeycloakContext) GetRoles() Roles { // CreateClientRoles creates a bunch of roles in a client from a []string func (kc *KeycloakContext) CreateClientRoles(clientID string, roles Roles) (int, error) { - fields := logger.DataForMethod("kc.CreateClientRoles") + fields := logger.ContextForMethod("kc.CreateClientRoles") defer func() { if err := kc.refreshClientRoles(); err != nil { @@ -193,7 +193,7 @@ func (kc *KeycloakContext) CreateUsers(users []gocloak.User, userMap Users, clie return err } for _, user := range users { - fields := logger.DataForMethod("kc.CreateUsers") + fields := logger.ContextForMethod("kc.CreateUsers") fields.AddUser(user) logger.Info("crée l'utilisateur Keycloak", fields) u, err := kc.API.CreateUser(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), user) @@ -239,7 +239,7 @@ func (kc *KeycloakContext) DisableUsers(users []gocloak.User, clientName string) } func (kc *KeycloakContext) disableUser(u gocloak.User, internalClientID string) error { - fields := logger.DataForMethod("kc.disableUser") + fields := logger.ContextForMethod("kc.disableUser") disabled := false u.Enabled = &disabled fields.AddUser(u) @@ -269,7 +269,7 @@ func (kc *KeycloakContext) disableUser(u gocloak.User, internalClientID string) // EnableUsers enables users and adds roles func (kc *KeycloakContext) EnableUsers(users []gocloak.User) error { - fields := logger.DataForMethod("kc.EnableUsers") + fields := logger.ContextForMethod("kc.EnableUsers") t := true for _, user := range users { fields.AddUser(user) @@ -286,7 +286,7 @@ func (kc *KeycloakContext) EnableUsers(users []gocloak.User) error { // UpdateCurrentUsers sets client roles on specified users according userMap func (kc KeycloakContext) UpdateCurrentUsers(users []gocloak.User, userMap Users, clientName string) error { - fields := logger.DataForMethod("kc.UpdateCurrentUsers") + fields := logger.ContextForMethod("kc.UpdateCurrentUsers") accountInternalID, err := kc.GetInternalIDFromClientID("account") if err != nil { return err @@ -366,7 +366,7 @@ func (kc KeycloakContext) UpdateCurrentUsers(users []gocloak.User, userMap Users // SaveMasterRealm update master Realm func (kc *KeycloakContext) SaveMasterRealm(input gocloak.RealmRepresentation) { - fields := logger.DataForMethod("kc.SaveMasterRealm") + fields := logger.ContextForMethod("kc.SaveMasterRealm") id := "master" input.ID = &id input.Realm = &id @@ -404,7 +404,7 @@ func (kc *KeycloakContext) SaveClients(input []*gocloak.Client) error { } func (kc KeycloakContext) saveClient(input gocloak.Client) error { - fields := logger.DataForMethod("kc.saveClient") + fields := logger.ContextForMethod("kc.saveClient") fields.AddClient(input) //kc.refreshClients() id, found := kc.GetQuietlyInternalIDFromClientID(*input.ClientID) diff --git a/keycloak_integration_test.go b/keycloak_integration_test.go index 4e7d9b4..2a0ad3d 100644 --- a/keycloak_integration_test.go +++ b/keycloak_integration_test.go @@ -292,7 +292,7 @@ func readStdin(message string) *os.File { } func logUser(client gocloak.Client, user gocloak.User) error { - fields := logger.DataForMethod("logUser") + fields := logger.ContextForMethod("logUser") fields.AddUser(user) fields.AddClient(client) // try connecting a user diff --git a/logger/logData.go b/logger/logData.go index 73c9f8b..19d3904 100644 --- a/logger/logData.go +++ b/logger/logData.go @@ -1,53 +1,71 @@ package logger import ( + "reflect" + "runtime" "strings" "github.com/Nerzal/gocloak/v13" ) -type Data map[string]interface{} +type LogContext map[string]interface{} -func DataForMethod(method string) Data { +func ContextForMethod(method string) LogContext { fields := map[string]interface{}{ "method": method, } return fields } -func (d Data) AddUser(user gocloak.User) { +func ContextForMethode(method interface{}) LogContext { + methodName := runtime.FuncForPC(reflect.ValueOf(method).Pointer()).Name() + fields := map[string]interface{}{ + "method": methodName, + } + return fields +} + +func (d LogContext) AddUser(user gocloak.User) LogContext { d["user"] = *user.Username + return d } -func (d Data) AddError(err error) { +func (d LogContext) AddError(err error) LogContext { d["error"] = err + return d } -func (d Data) removeError() { +func (d LogContext) removeError() LogContext { delete(d, "error") + return d } -func (d Data) AddArray(key string, any []string) { +func (d LogContext) AddArray(key string, any []string) LogContext { d[key] = strings.Join(any, ", ") + return d } -func (d Data) AddAny(key string, any interface{}) { +func (d LogContext) AddAny(key string, any interface{}) LogContext { d[key] = any + return d } -func (d Data) Remove(key string) { +func (d LogContext) Remove(key string) LogContext { delete(d, key) + return d } -func (d Data) AddClient(input gocloak.Client) { +func (d LogContext) AddClient(input gocloak.Client) LogContext { d["clientId"] = *input.ClientID + return d } -func (d Data) AddRole(input gocloak.Role) { +func (d LogContext) AddRole(input gocloak.Role) LogContext { d["role"] = role2string(input) + return d } -func (d Data) AddRoles(all []gocloak.Role) { +func (d LogContext) AddRoles(all []gocloak.Role) LogContext { var val string if all == nil { val = "" @@ -55,4 +73,5 @@ func (d Data) AddRoles(all []gocloak.Role) { val = strings.Join(toStrings(all, role2string), ", ") } d["roles"] = val + return d } diff --git a/logger/logger.go b/logger/logger.go index 4660772..93b4e51 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -65,15 +65,20 @@ func Error(msg string, data map[string]interface{}, err error) { logWithContext(slog.LevelWarn, msg, data, err) } +func Panic(msg string, data map[string]interface{}, err error) { + Error(msg, data, err) + panic(err) +} + func logWithContext(level slog.Level, msg string, data map[string]interface{}, err error) { - var logCtx []any + var logCtx []slog.Attr for k, v := range data { logCtx = append(logCtx, slog.Any(k, v)) } if err != nil { - logCtx = append(logCtx, slog.String("error", err.Error())) + logCtx = append(logCtx, slog.Any("error", err)) } - slog.Log(context.Background(), level, msg, logCtx...) + slog.LogAttrs(context.Background(), level, msg, logCtx...) } func findBuildSetting(settings []debug.BuildSetting, search string) string { diff --git a/main.go b/main.go index 8dafa61..0e9b058 100644 --- a/main.go +++ b/main.go @@ -32,7 +32,7 @@ func main() { } logger.ConfigureWith(*conf.Logger) - fields := logger.DataForMethod("main") + fields := logger.ContextForMethod("main") // loading desired state for users, composites roles logger.Info("lecture du fichier excel stock", fields) diff --git a/main_integration_test.go b/main_integration_test.go index d956b5d..9793462 100644 --- a/main_integration_test.go +++ b/main_integration_test.go @@ -8,7 +8,6 @@ import ( "bytes" "context" "fmt" - "log/slog" "os" "strconv" "testing" @@ -41,6 +40,7 @@ const keycloakAdmin = "ti_admin" const keycloakPassword = "pwd" func TestMain(m *testing.M) { + logContext := logger.ContextForMethode(TestMain) var err error pool, err := dockertest.NewPool("") pool.MaxWait = time.Minute * 2 @@ -50,8 +50,7 @@ func TestMain(m *testing.M) { Level: "DEBUG", }) if err != nil { - slog.Error("erreur pendant la connection à Docker", slog.Any("error", err)) - panic(err) + logger.Panic("erreur pendant la connection à Docker", logContext, err) } keycloak := startKeycloak(pool) @@ -67,12 +66,12 @@ func TestMain(m *testing.M) { } func kill(resource *dockertest.Resource) { + logContext := logger.ContextForMethode(kill) if resource == nil { return } if err := resource.Close(); err != nil { - slog.Error("erreur pendant la purge des ressources Docker", slog.Any("error", err)) - panic(err) + logger.Panic("erreur pendant la purge des ressources Docker", logContext, err) } } @@ -81,12 +80,12 @@ func startKeycloak(pool *dockertest.Pool) *dockertest.Resource { return nil } // uses a sensible default on windows (tcp/http) and linux/osx (socket) - fields := logger.DataForMethod("startKeycloak") + logContext := logger.ContextForMethode(startKeycloak) // pulls an image, creates a container based on it and runs it keycloakContainerName := "keycloakUpdater-ti-" + strconv.Itoa(time.Now().Nanosecond()) - fields.AddAny("container", keycloakContainerName) - logger.Info("Démarre keycloak", fields) + logContext.AddAny("container", keycloakContainerName) + logger.Info("Démarre keycloak", logContext) keycloak, err := pool.RunWithOptions( &dockertest.RunOptions{ @@ -110,39 +109,37 @@ func startKeycloak(pool *dockertest.Pool) *dockertest.Resource { ) if err != nil { kill(keycloak) - logger.Error("Could not start keycloak", fields, err) - panic(err) + logger.Panic("Could not start keycloak", logContext, err) } // container stops after 120 seconds if err = keycloak.Expire(600); err != nil { kill(keycloak) - logger.Error("Could not set expiration on container keycloak", fields, err) + logger.Error("Could not set expiration on container keycloak", logContext, err) } - slog.Info("keycloak a démarré avec l'admin", slog.String("name", keycloakAdmin)) + logger.Info("keycloak a démarré avec l'admin", logContext.AddAny("name", keycloakAdmin)) keycloakPort := keycloak.GetPort("8080/tcp") - fields.AddAny("port", keycloakPort) - logger.Info("keycloak started", fields) + logContext.AddAny("port", keycloakPort) + logger.Info("keycloak started", logContext) //exponential backoff-retry, because the application in the container might not be ready to accept connections yet if err := pool.Retry(func() error { var err error kc, err = Init("http://localhost:"+keycloakPort+"/auth", "master", keycloakAdmin, keycloakPassword) if err != nil { - logger.Info("keycloak n'est pas prêt", fields) + logger.Info("keycloak n'est pas prêt", logContext) return err } return nil }); err != nil { - slog.Error("erreur pendant la connexion à Keycloak", slog.Any("error", err)) - panic(err) + logger.Panic("erreur pendant la connexion à Keycloak", logContext, err) } - logger.Info("keycloak est prêt", fields) + logger.Info("keycloak est prêt", logContext) return keycloak } func startWekanDB(pool *dockertest.Pool) *dockertest.Resource { dir, _ := os.Getwd() - fields := logger.DataForMethod("startWekanDB") + fields := logger.ContextForMethod("startWekanDB") mongodbContainerName := "mongodb-ti-" + strconv.Itoa(time.Now().Nanosecond()) mongodb, err := pool.RunWithOptions( &dockertest.RunOptions{ @@ -195,7 +192,7 @@ func startWekanDB(pool *dockertest.Pool) *dockertest.Resource { func restoreMongoDumpInDatabase(mongodb *dockertest.Resource, suffix string, t *testing.T, slugDomainRegexp string) libwekan.Wekan { databasename := t.Name() + suffix - fields := logger.DataForMethod("restoreMongoDump") + fields := logger.ContextForMethod("restoreMongoDump") fields.AddAny("database", databasename) var output bytes.Buffer outputWriter := bufio.NewWriter(&output) diff --git a/roles.go b/roles.go index 5c1770c..faa3157 100644 --- a/roles.go +++ b/roles.go @@ -97,7 +97,7 @@ func (kc KeycloakContext) FindKeycloakRoles(clientName string, roles Roles) []go // ComposeRoles writes roles composition to keycloak server func (kc KeycloakContext) ComposeRoles(clientID string, compositeRoles CompositeRoles) error { - fields := logger.DataForMethod("kc.ComposeRoles") + fields := logger.ContextForMethod("kc.ComposeRoles") fields.AddAny("clientId", clientID) // Add known roles for role, roles := range compositeRoles { diff --git a/updater.go b/updater.go index 4095410..27a3731 100644 --- a/updater.go +++ b/updater.go @@ -23,7 +23,7 @@ func UpdateKeycloak( configuredUsername Username, maxChangesToAccept int, ) error { - fields := logger.DataForMethod("UpdateAll") + fields := logger.ContextForMethod("UpdateAll") if _, exists := users[configuredUsername]; !exists { return errors.Errorf( @@ -131,7 +131,7 @@ func UpdateKeycloak( } func areYouSureTooApplyChanges(changes, keeps, acceptedChanges int) bool { - fields := logger.DataForMethod("areYouSureTooApplyChanges") + fields := logger.ContextForMethod("areYouSureTooApplyChanges") logger.Info("nombre d'utilisateurs à rajouter/supprimer/activer : "+strconv.Itoa(changes), fields) logger.Info("nombre d'utilisateurs à conserver : "+strconv.Itoa(keeps), fields) if keeps < 1 { diff --git a/wekan.go b/wekan.go index 3215647..68e29e4 100644 --- a/wekan.go +++ b/wekan.go @@ -3,8 +3,10 @@ package main import ( "context" "fmt" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" + "github.com/signaux-faibles/libwekan" + + "github.com/signaux-faibles/keycloakUpdater/v2/logger" ) type Pipeline []PipelineStage @@ -28,7 +30,7 @@ func (pipeline Pipeline) Run(wekan libwekan.Wekan, fromConfig Users) error { } func (pipeline Pipeline) StopAfter(wekan libwekan.Wekan, fromConfig Users, lastStage PipelineStage) error { - fields := logger.DataForMethod("StopAfter") + fields := logger.ContextForMethod("StopAfter") for _, stage := range pipeline { fields.AddAny("stage", stage.id) logger.Debug("applique le pipeline", fields) diff --git a/wekanBoardsMembers.go b/wekanBoardsMembers.go index 39f6ab2..31e67e9 100644 --- a/wekanBoardsMembers.go +++ b/wekanBoardsMembers.go @@ -2,14 +2,16 @@ package main import ( "context" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" + "github.com/signaux-faibles/libwekan" + + "github.com/signaux-faibles/keycloakUpdater/v2/logger" ) type BoardsMembers map[libwekan.BoardSlug]Users func manageBoardsMembers(wekan libwekan.Wekan, fromConfig Users) error { - fields := logger.DataForMethod("manageBoardsMembers") + fields := logger.ContextForMethod("manageBoardsMembers") // périmètre du stage wekanBoardsMembers := fromConfig.inferBoardsMember() domainBoards, err := wekan.SelectDomainBoards(context.Background()) @@ -29,7 +31,7 @@ func manageBoardsMembers(wekan libwekan.Wekan, fromConfig Users) error { } func updateBoardMembers(wekan libwekan.Wekan, boardSlug libwekan.BoardSlug, boardMembers Users) error { - fields := logger.DataForMethod("updateBoardMembers") + fields := logger.ContextForMethod("updateBoardMembers") fields.AddAny("board", boardSlug) board, err := wekan.GetBoardFromSlug(context.Background(), boardSlug) if err != nil { @@ -75,7 +77,7 @@ func updateBoardMembers(wekan libwekan.Wekan, boardSlug libwekan.BoardSlug, boar } func ensureUserIsActiveBoardMember(wekan libwekan.Wekan, user libwekan.User, board libwekan.Board) error { - fields := logger.DataForMethod("ensureUserIsActiveBoardMember") + fields := logger.ContextForMethod("ensureUserIsActiveBoardMember") fields.AddAny("username", user.Username) fields.AddAny("board", board.Slug) logger.Debug(">>> examine l'utilisateur", fields) @@ -90,7 +92,7 @@ func ensureUserIsActiveBoardMember(wekan libwekan.Wekan, user libwekan.User, boa } func ensureUserIsInactiveBoardMember(wekan libwekan.Wekan, user libwekan.User, board libwekan.Board) error { - fields := logger.DataForMethod("ensureUserIsInactiveBoardMember") + fields := logger.ContextForMethod("ensureUserIsInactiveBoardMember") fields.AddAny("username", user.Username) fields.AddAny("board", board.Slug) logger.Debug(">>> vérifie la non-participation", fields) diff --git a/wekanTaskforce.go b/wekanTaskforce.go index ff55ab0..ea8f983 100644 --- a/wekanTaskforce.go +++ b/wekanTaskforce.go @@ -2,15 +2,17 @@ package main import ( "context" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" + "github.com/signaux-faibles/libwekan" + + "github.com/signaux-faibles/keycloakUpdater/v2/logger" ) // addMissingRulesAndCardMembership // Calcule et insère les règles manquantes pour correspondre à la configuration Users // Ajuste la participation des utilisateurs aux cartes concernées par les labels en cas de changement func addMissingRulesAndCardMembership(wekan libwekan.Wekan, users Users) error { - fields := logger.DataForMethod("addMissingRulesAndCardMembership") + fields := logger.ContextForMethod("addMissingRulesAndCardMembership") logger.Info("> ajoute les nouvelles règles", fields) occurence := 0 for _, user := range users { @@ -50,14 +52,14 @@ func addMissingRulesAndCardMembership(wekan libwekan.Wekan, users Users) error { } } if occurence == 0 { - fields = logger.DataForMethod("addMissingRulesAndCardMembership") + fields = logger.ContextForMethod("addMissingRulesAndCardMembership") logger.Info("> aucune règle à ajouter", fields) } return nil } func EnsureRuleAddTaskforceMemberExists(wekan libwekan.Wekan, wekanUser libwekan.User, board libwekan.Board, label libwekan.BoardLabel) (int, error) { - fields := logger.DataForMethod("EnsureRuleAddTaskforceMemberExists") + fields := logger.ContextForMethod("EnsureRuleAddTaskforceMemberExists") fields.AddAny("username", wekanUser.Username) fields.AddAny("board", board.Slug) fields.AddAny("label", label.Name) @@ -72,7 +74,7 @@ func EnsureRuleAddTaskforceMemberExists(wekan libwekan.Wekan, wekanUser libwekan } func EnsureRuleRemoveTaskforceMemberExists(wekan libwekan.Wekan, wekanUser libwekan.User, board libwekan.Board, label libwekan.BoardLabel) (int, error) { - fields := logger.DataForMethod("EnsureRuleRemoveTaskforceMemberExists") + fields := logger.ContextForMethod("EnsureRuleRemoveTaskforceMemberExists") fields.AddAny("username", wekanUser.Username) fields.AddAny("board", board.Slug) fields.AddAny("label", label.Name) @@ -90,7 +92,7 @@ func EnsureRuleRemoveTaskforceMemberExists(wekan libwekan.Wekan, wekanUser libwe // Calcule et insert les règles manquantes pour correspondre à la configuration Users // Ajuste la participation des utilisateurs aux cartes concernées par les labels en cas de changement func removeExtraRulesAndCardsMembership(wekan libwekan.Wekan, users Users) error { - fields := logger.DataForMethod("RemoveExtraRulesAndCardMembership") + fields := logger.ContextForMethod("RemoveExtraRulesAndCardMembership") logger.Info("> supprime les règles obsolètes", fields) domainBoards, err := wekan.SelectDomainBoards(context.Background()) if err != nil { @@ -140,7 +142,7 @@ func userHasTaskforceLabel(user User) func(label libwekan.BoardLabel) bool { } func removeCardMembership(wekan libwekan.Wekan, wekanUsername libwekan.Username, board libwekan.Board, label libwekan.BoardLabel) error { - fields := logger.DataForMethod("removeCardMembership") + fields := logger.ContextForMethod("removeCardMembership") fields.AddAny("username", wekanUsername) fields.AddAny("label", label.Name) fields.AddAny("board", board.Slug) @@ -174,7 +176,7 @@ func removeCardMembership(wekan libwekan.Wekan, wekanUsername libwekan.Username, } func addCardMemberShip(wekan libwekan.Wekan, wekanUser libwekan.User, board libwekan.Board, label libwekan.BoardLabel) error { - fields := logger.DataForMethod("AddCardMembership") + fields := logger.ContextForMethod("AddCardMembership") fields.AddAny("username", wekanUser.Username) fields.AddAny("label", label.Name) fields.AddAny("board", board.Slug) diff --git a/wekanUsers.go b/wekanUsers.go index d670b4e..32408e6 100644 --- a/wekanUsers.go +++ b/wekanUsers.go @@ -18,7 +18,7 @@ var GENUINEUSERSELECTOR = []func(wekan libwekan.Wekan, user libwekan.User) bool{ // checkNativeUsers apporte des logs permettant de garder un œil sur les utilisateurs gérés manuellement func checkNativeUsers(wekan libwekan.Wekan, _ Users) error { ctx := context.Background() - fields := logger.DataForMethod("checkNativeUsers") + fields := logger.ContextForMethod("checkNativeUsers") logger.Info("inventaire des comptes standards", fields) wekanUsers, err := wekan.GetUsers(ctx) if err != nil { @@ -75,7 +75,7 @@ func selectWekanUsers(wekan libwekan.Wekan) (libwekan.Users, error) { } func insertUsers(ctx context.Context, wekan libwekan.Wekan, users libwekan.Users) error { - fields := logger.DataForMethod("insertUser") + fields := logger.ContextForMethod("insertUser") logger.Info("> traite les inscriptions des utilisateurs", fields) fields.AddAny("population", len(users)) logger.Info(">> inscrit les nouveaux utilisateurs", fields) @@ -96,7 +96,7 @@ func insertUsers(ctx context.Context, wekan libwekan.Wekan, users libwekan.Users } func ensureUsersAreEnabled(ctx context.Context, wekan libwekan.Wekan, users libwekan.Users) error { - fields := logger.DataForMethod("ensureUsersAreEnabled") + fields := logger.ContextForMethod("ensureUsersAreEnabled") fields.AddAny("population", len(users)) logger.Info(">> active des utilisateurs réinscrits", fields) if err := wekan.AssertPrivileged(ctx); err != nil { @@ -119,7 +119,7 @@ func ensureUsersAreEnabled(ctx context.Context, wekan libwekan.Wekan, users libw } func ensureUsersAreDisabled(ctx context.Context, wekan libwekan.Wekan, users libwekan.Users) error { - fields := logger.DataForMethod("ensureUsersAreDisabled") + fields := logger.ContextForMethod("ensureUsersAreDisabled") fields.AddAny("population", len(users)) logger.Info(">> radie les utilisateurs absents", fields) for _, user := range users { From 9d7fd2b921fc0529201b66696a551cf0f61638ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Tue, 12 Sep 2023 17:11:40 +0200 Subject: [PATCH 13/41] =?UTF-8?q?retire=20les=20r=C3=A9f=C3=A9rences=20?= =?UTF-8?q?=C3=A0=20slog=20dans=20tous=20les=20packages=20sauf=20le=20pack?= =?UTF-8?q?age=20logger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- keycloakContext.go | 7 ++--- logger/configuration.go | 2 +- main.go | 18 +++++------ main_integration_test.go | 6 ++-- roles_test.go | 3 +- updater.go | 41 +++++++++++--------------- updater_test.go | 3 +- user_test.go | 3 +- wekanBoardsMembers_integration_test.go | 3 +- wekanUsers_integration_test.go | 3 +- wekan_test.go | 3 +- 11 files changed, 42 insertions(+), 50 deletions(-) diff --git a/keycloakContext.go b/keycloakContext.go index 7405593..013de4a 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -2,7 +2,6 @@ package main import ( "context" - "log/slog" "github.com/Nerzal/gocloak/v13" "github.com/pkg/errors" @@ -380,11 +379,11 @@ func (kc *KeycloakContext) SaveMasterRealm(input gocloak.RealmRepresentation) { } func (kc *KeycloakContext) refreshRealm(realmName string) { - slog.Debug("refresh Realm", slog.String("realm", realmName)) + logContext := logger.ContextForMethode(kc.refreshRealm) + logger.Debug("refresh Realm", logContext.AddAny("realm", realmName)) realm, err := kc.API.GetRealm(context.Background(), kc.JWT.AccessToken, realmName) if err != nil { - slog.Error("Erreur pendant la récupération du Realm", slog.Any("error", err)) - panic(err) + logger.Panic("Erreur pendant la récupération du Realm", logContext, err) } kc.Realm = realm } diff --git a/logger/configuration.go b/logger/configuration.go index 8d871c5..c3f6ddc 100644 --- a/logger/configuration.go +++ b/logger/configuration.go @@ -34,7 +34,7 @@ func configFileHandler(logFilename string) *slog.TextHandler { func configLogLevel(configLogLevel string) { var err error - var level = loglevel.Level() + level := loglevel.Level() if level, err = parseLogLevel(configLogLevel); err != nil { slog.Warn("erreur de configuration sur le log level", slog.String("valeur", configLogLevel)) } diff --git a/main.go b/main.go index 0e9b058..e5d3099 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,6 @@ package main import ( "flag" "fmt" - "log/slog" "github.com/pkg/errors" @@ -32,22 +31,20 @@ func main() { } logger.ConfigureWith(*conf.Logger) - fields := logger.ContextForMethod("main") + logContext := logger.ContextForMethode(main) // loading desired state for users, composites roles - logger.Info("lecture du fichier excel stock", fields) + logger.Info("lecture du fichier excel stock", logContext) users, compositeRoles, err := loadExcel(conf.Stock.UsersAndRolesFilename) if err != nil { - slog.Error("erreur pendant la lecture du fichier Excel", slog.Any("error", err)) - panic(err) + logger.Panic("erreur pendant la lecture du fichier Excel", logContext, err) } if conf.Keycloak != nil { clientId := conf.Stock.ClientForRoles kc, err := NewKeycloakContext(conf.Keycloak) if err != nil { - slog.Error("erreur pendant l'initialisation du contexte Keycloak'", slog.Any("error", err)) - panic(err) + logger.Panic("erreur pendant l'initialisation du contexte Keycloak'", logContext, err) } if err = UpdateKeycloak( @@ -60,8 +57,7 @@ func main() { Username(conf.Keycloak.Username), conf.Stock.MaxChangesToAccept, ); err != nil { - slog.Error("erreur pendant la mise à jour de Keycloak", slog.Any("error", err)) - panic(err) + logger.Error("erreur pendant la mise à jour de Keycloak", logContext, err) } } @@ -76,11 +72,11 @@ func main() { } if err != nil { - logger.Error("le traitement s'est terminé de façon anormale", fields, err) + logger.Error("le traitement s'est terminé de façon anormale", logContext, err) fmt.Println("======= Détail de l'erreur") printErrChain(err, 0) } else { - logger.Info("le traitement s'est terminé correctement", fields) + logger.Info("le traitement s'est terminé correctement", logContext) } } diff --git a/main_integration_test.go b/main_integration_test.go index 9793462..b1d3f16 100644 --- a/main_integration_test.go +++ b/main_integration_test.go @@ -14,16 +14,14 @@ import ( "time" "github.com/ory/dockertest/v3" - "github.com/stretchr/testify/require" - - "github.com/signaux-faibles/keycloakUpdater/v2/structs" - "github.com/ory/dockertest/v3/docker" "github.com/signaux-faibles/libwekan" + "github.com/stretchr/testify/require" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "github.com/signaux-faibles/keycloakUpdater/v2/logger" + "github.com/signaux-faibles/keycloakUpdater/v2/structs" ) var kc KeycloakContext diff --git a/roles_test.go b/roles_test.go index fba4f15..e709cba 100644 --- a/roles_test.go +++ b/roles_test.go @@ -1,8 +1,9 @@ package main import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestRoles_add_on_nil_roles_dont_throw_error(t *testing.T) { diff --git a/updater.go b/updater.go index 27a3731..e593f09 100644 --- a/updater.go +++ b/updater.go @@ -3,7 +3,6 @@ package main import ( "context" "fmt" - "log/slog" "sort" "strconv" @@ -23,7 +22,7 @@ func UpdateKeycloak( configuredUsername Username, maxChangesToAccept int, ) error { - fields := logger.ContextForMethod("UpdateAll") + logContext := logger.ContextForMethode(UpdateKeycloak) if _, exists := users[configuredUsername]; !exists { return errors.Errorf( @@ -42,11 +41,11 @@ func UpdateKeycloak( ) } - logger.Info("START", fields) - logger.Info("accepte "+strconv.Itoa(maxChangesToAccept)+" changements pour les users", fields) + logger.Info("START", logContext) + logger.Info("accepte "+strconv.Itoa(maxChangesToAccept)+" changements pour les users", logContext) // checking users - logger.Info("checking users", fields) + logger.Info("checking users", logContext) missing, obsolete, update, current := users.Compare(*kc) changes := len(missing) + len(obsolete) + len(update) keeps := len(current) @@ -55,11 +54,11 @@ func UpdateKeycloak( } // gather roles, newRoles are created before users, oldRoles are deleted after users - logger.Info("checking roles", fields) + logger.Info("checking roles", logContext) neededRoles := neededRoles(compositeRoles, users) newRoles, oldRoles := neededRoles.compare(kc.GetClientRoles()[clientId]) - logger.Info("starting keycloak configuration", fields) + logger.Info("starting keycloak configuration", logContext) // realmName conf if realm != nil { kc.SaveMasterRealm(*realm) @@ -72,45 +71,39 @@ func UpdateKeycloak( i, err := kc.CreateClientRoles(clientId, newRoles) if err != nil { - slog.Error("erreur pendant l'écriture des nouveaux rôles", slog.Any("error", err)) - panic(err) + logger.Panic("erreur pendant l'écriture des nouveaux rôles", logContext, err) } - slog.Info("roles created", slog.Int("size", i)) + logger.Info("roles created", logContext.AddAny("size", i)) // check and adjust composite roles if err = kc.ComposeRoles(clientId, compositeRoles); err != nil { - slog.Error("erreur pendant l'écriture des rôles composés", slog.Any("error", err)) - panic(err) + logger.Panic("erreur pendant l'écriture des rôles composés", logContext, err) } if err = kc.CreateUsers(missing, users, clientId); err != nil { - slog.Error("erreur pendant la création des utilisateurs", slog.Any("error", err)) - panic(err) + logger.Panic("erreur pendant la création des utilisateurs", logContext, err) } // disable obsolete users if err = kc.DisableUsers(obsolete, clientId); err != nil { - slog.Error("erreur pendant la désactivation des utilisateurs", slog.Any("error", err)) - panic(err) + logger.Panic("erreur pendant la désactivation des utilisateurs", logContext, err) } // enable existing but disabled users if err = kc.EnableUsers(update); err != nil { - slog.Error("erreur pendant l'activation des utilisateurs", slog.Any("error", err)) - panic(err) + logger.Panic("erreur pendant l'activation des utilisateurs", logContext, err) } // make sure every on has correct roles if err = kc.UpdateCurrentUsers(current, users, clientId); err != nil { - slog.Error("erreur pendant la mise à jour des utilisateurs", slog.Any("error", err)) - panic(err) + logger.Error("erreur pendant la mise à jour des utilisateurs", logContext, err) } // delete old roles if len(oldRoles) > 0 { sort.Strings(oldRoles) - fields.AddArray("toDelete", oldRoles) - logger.Info("removing unused roles", fields) - fields.Remove("toDelete") + logContext.AddArray("toDelete", oldRoles) + logger.Info("removing unused roles", logContext) + logContext.Remove("toDelete") internalID, err := kc.GetInternalIDFromClientID(clientId) if err != nil { panic(err) @@ -126,7 +119,7 @@ func UpdateKeycloak( panic(err) } } - logger.Info("DONE", fields) + logger.Info("DONE", logContext) return nil } diff --git a/updater_test.go b/updater_test.go index bc1a44b..a71dd4a 100644 --- a/updater_test.go +++ b/updater_test.go @@ -1,8 +1,9 @@ package main import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func Test_areYouSureTooApplyChanges(t *testing.T) { diff --git a/user_test.go b/user_test.go index 69e38df..6ca5182 100644 --- a/user_test.go +++ b/user_test.go @@ -1,9 +1,10 @@ package main import ( - "github.com/stretchr/testify/assert" "sort" "testing" + + "github.com/stretchr/testify/assert" ) func TestUser_roles_with_niveau_a(t *testing.T) { diff --git a/wekanBoardsMembers_integration_test.go b/wekanBoardsMembers_integration_test.go index b0e2473..04355aa 100644 --- a/wekanBoardsMembers_integration_test.go +++ b/wekanBoardsMembers_integration_test.go @@ -6,9 +6,10 @@ package main import ( + "testing" + "github.com/signaux-faibles/libwekan" "github.com/stretchr/testify/assert" - "testing" ) func TestWekan_ManageBoardsMembers_withoutBoard(t *testing.T) { diff --git a/wekanUsers_integration_test.go b/wekanUsers_integration_test.go index 6e3ca7f..63e235f 100644 --- a/wekanUsers_integration_test.go +++ b/wekanUsers_integration_test.go @@ -5,9 +5,10 @@ package main import ( + "testing" + "github.com/signaux-faibles/libwekan" "github.com/stretchr/testify/assert" - "testing" ) func TestWekan_ManageUsers_withoutScopeWekan(t *testing.T) { diff --git a/wekan_test.go b/wekan_test.go index bec90d6..68fe5b0 100644 --- a/wekan_test.go +++ b/wekan_test.go @@ -1,10 +1,11 @@ package main import ( + "testing" + "github.com/signaux-faibles/libwekan" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "testing" ) func TestWekan_ListBoards(t *testing.T) { From 77db0ad36835e7e98d0bbb4d5b25d92793157875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Tue, 12 Sep 2023 17:23:24 +0200 Subject: [PATCH 14/41] =?UTF-8?q?utilise=20les=20methodes=20plut=C3=B4t=20?= =?UTF-8?q?qu'une=20string=20pour=20donner=20le=20nom=20du=20context?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/config.go | 8 ++++---- config/merge.go | 2 +- keycloakContext.go | 18 +++++++++--------- keycloak_integration_test.go | 2 +- logger/{logData.go => context.go} | 9 +-------- main.go | 2 +- main_integration_test.go | 10 +++++----- roles.go | 2 +- updater.go | 4 ++-- wekan.go | 2 +- wekanBoardsMembers.go | 8 ++++---- wekanTaskforce.go | 14 +++++++------- wekanUsers.go | 8 ++++---- 13 files changed, 41 insertions(+), 48 deletions(-) rename logger/{logData.go => context.go} (87%) diff --git a/config/config.go b/config/config.go index 9308fa7..e611390 100644 --- a/config/config.go +++ b/config/config.go @@ -20,7 +20,7 @@ func OverrideConfig(original structs.Config, overridingFilename string) structs. logger.Debug("pas de surcharge de configuration", nil) return original } - logContext := logger.ContextForMethode(OverrideConfig) + logContext := logger.ContextForMethod(OverrideConfig) logger.Info("surcharge de configuration", logContext.AddAny("filename", overridingFilename)) overridingConfig, err := initConfig(overridingFilename, true) if err != nil { @@ -41,7 +41,7 @@ func initConfig(configFilename string, quietly bool) (structs.Config, error) { logger.Info( "config files", - logger.ContextForMethode(initConfig).AddArray("filenames", filenames), + logger.ContextForMethod(initConfig).AddArray("filenames", filenames), ) allConfig := readAllConfigFiles(filenames) for _, current := range allConfig { @@ -64,7 +64,7 @@ func readAllConfigFiles(filenames []string) []structs.Config { func getAllConfigFilenames(filename string) []string { var r = make([]string, 0) - logContext := logger.ContextForMethode(getAllConfigFilenames) + logContext := logger.ContextForMethod(getAllConfigFilenames) // checking file exist var err error if _, err = os.Open(filename); err != nil { @@ -114,7 +114,7 @@ func getAllConfigFilenames(filename string) []string { } func extractConfig(filename string) structs.Config { - logContext := logger.ContextForMethode(extractConfig) + logContext := logger.ContextForMethod(extractConfig) var conf structs.Config var err error var meta toml.MetaData diff --git a/config/merge.go b/config/merge.go index 061170b..7980163 100644 --- a/config/merge.go +++ b/config/merge.go @@ -12,7 +12,7 @@ func merge(first structs.Config, second structs.Config) structs.Config { allClients := concatClients(first.Clients, second.Clients) err := mergo.Merge(&first, second, mergo.WithOverride) if err != nil { - logger.Error("erreur pendant le merging de la configuration", logger.ContextForMethode(merge), err) + logger.Error("erreur pendant le merging de la configuration", logger.ContextForMethod(merge), err) } first.Clients = allClients return first diff --git a/keycloakContext.go b/keycloakContext.go index 013de4a..b9a24c6 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -28,7 +28,7 @@ func NewKeycloakContext(access *structs.Keycloak) (KeycloakContext, error) { // Init provides a connected keycloak context object func Init(hostname, realm, username, password string) (KeycloakContext, error) { - fields := logger.ContextForMethod("Init") + fields := logger.ContextForMethod(Init) fields.AddAny("path", hostname) fields.AddAny("realm", realm) fields.AddAny("user", username) @@ -91,7 +91,7 @@ func (kc KeycloakContext) GetRoles() Roles { // CreateClientRoles creates a bunch of roles in a client from a []string func (kc *KeycloakContext) CreateClientRoles(clientID string, roles Roles) (int, error) { - fields := logger.ContextForMethod("kc.CreateClientRoles") + fields := logger.ContextForMethod(kc.CreateClientRoles) defer func() { if err := kc.refreshClientRoles(); err != nil { @@ -192,7 +192,7 @@ func (kc *KeycloakContext) CreateUsers(users []gocloak.User, userMap Users, clie return err } for _, user := range users { - fields := logger.ContextForMethod("kc.CreateUsers") + fields := logger.ContextForMethod(kc.CreateUsers) fields.AddUser(user) logger.Info("crée l'utilisateur Keycloak", fields) u, err := kc.API.CreateUser(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), user) @@ -238,7 +238,7 @@ func (kc *KeycloakContext) DisableUsers(users []gocloak.User, clientName string) } func (kc *KeycloakContext) disableUser(u gocloak.User, internalClientID string) error { - fields := logger.ContextForMethod("kc.disableUser") + fields := logger.ContextForMethod(kc.disableUser) disabled := false u.Enabled = &disabled fields.AddUser(u) @@ -268,7 +268,7 @@ func (kc *KeycloakContext) disableUser(u gocloak.User, internalClientID string) // EnableUsers enables users and adds roles func (kc *KeycloakContext) EnableUsers(users []gocloak.User) error { - fields := logger.ContextForMethod("kc.EnableUsers") + fields := logger.ContextForMethod(kc.EnableUsers) t := true for _, user := range users { fields.AddUser(user) @@ -285,7 +285,7 @@ func (kc *KeycloakContext) EnableUsers(users []gocloak.User) error { // UpdateCurrentUsers sets client roles on specified users according userMap func (kc KeycloakContext) UpdateCurrentUsers(users []gocloak.User, userMap Users, clientName string) error { - fields := logger.ContextForMethod("kc.UpdateCurrentUsers") + fields := logger.ContextForMethod(kc.UpdateCurrentUsers) accountInternalID, err := kc.GetInternalIDFromClientID("account") if err != nil { return err @@ -365,7 +365,7 @@ func (kc KeycloakContext) UpdateCurrentUsers(users []gocloak.User, userMap Users // SaveMasterRealm update master Realm func (kc *KeycloakContext) SaveMasterRealm(input gocloak.RealmRepresentation) { - fields := logger.ContextForMethod("kc.SaveMasterRealm") + fields := logger.ContextForMethod(kc.SaveMasterRealm) id := "master" input.ID = &id input.Realm = &id @@ -379,7 +379,7 @@ func (kc *KeycloakContext) SaveMasterRealm(input gocloak.RealmRepresentation) { } func (kc *KeycloakContext) refreshRealm(realmName string) { - logContext := logger.ContextForMethode(kc.refreshRealm) + logContext := logger.ContextForMethod(kc.refreshRealm) logger.Debug("refresh Realm", logContext.AddAny("realm", realmName)) realm, err := kc.API.GetRealm(context.Background(), kc.JWT.AccessToken, realmName) if err != nil { @@ -403,7 +403,7 @@ func (kc *KeycloakContext) SaveClients(input []*gocloak.Client) error { } func (kc KeycloakContext) saveClient(input gocloak.Client) error { - fields := logger.ContextForMethod("kc.saveClient") + fields := logger.ContextForMethod(kc.saveClient) fields.AddClient(input) //kc.refreshClients() id, found := kc.GetQuietlyInternalIDFromClientID(*input.ClientID) diff --git a/keycloak_integration_test.go b/keycloak_integration_test.go index 2a0ad3d..25ff372 100644 --- a/keycloak_integration_test.go +++ b/keycloak_integration_test.go @@ -292,7 +292,7 @@ func readStdin(message string) *os.File { } func logUser(client gocloak.Client, user gocloak.User) error { - fields := logger.ContextForMethod("logUser") + fields := logger.ContextForMethod(logUser) fields.AddUser(user) fields.AddClient(client) // try connecting a user diff --git a/logger/logData.go b/logger/context.go similarity index 87% rename from logger/logData.go rename to logger/context.go index 19d3904..17714d3 100644 --- a/logger/logData.go +++ b/logger/context.go @@ -10,14 +10,7 @@ import ( type LogContext map[string]interface{} -func ContextForMethod(method string) LogContext { - fields := map[string]interface{}{ - "method": method, - } - return fields -} - -func ContextForMethode(method interface{}) LogContext { +func ContextForMethod(method interface{}) LogContext { methodName := runtime.FuncForPC(reflect.ValueOf(method).Pointer()).Name() fields := map[string]interface{}{ "method": methodName, diff --git a/main.go b/main.go index e5d3099..4d4de58 100644 --- a/main.go +++ b/main.go @@ -31,7 +31,7 @@ func main() { } logger.ConfigureWith(*conf.Logger) - logContext := logger.ContextForMethode(main) + logContext := logger.ContextForMethod(main) // loading desired state for users, composites roles logger.Info("lecture du fichier excel stock", logContext) diff --git a/main_integration_test.go b/main_integration_test.go index b1d3f16..bcdfd5c 100644 --- a/main_integration_test.go +++ b/main_integration_test.go @@ -38,7 +38,7 @@ const keycloakAdmin = "ti_admin" const keycloakPassword = "pwd" func TestMain(m *testing.M) { - logContext := logger.ContextForMethode(TestMain) + logContext := logger.ContextForMethod(TestMain) var err error pool, err := dockertest.NewPool("") pool.MaxWait = time.Minute * 2 @@ -64,7 +64,7 @@ func TestMain(m *testing.M) { } func kill(resource *dockertest.Resource) { - logContext := logger.ContextForMethode(kill) + logContext := logger.ContextForMethod(kill) if resource == nil { return } @@ -78,7 +78,7 @@ func startKeycloak(pool *dockertest.Pool) *dockertest.Resource { return nil } // uses a sensible default on windows (tcp/http) and linux/osx (socket) - logContext := logger.ContextForMethode(startKeycloak) + logContext := logger.ContextForMethod(startKeycloak) // pulls an image, creates a container based on it and runs it keycloakContainerName := "keycloakUpdater-ti-" + strconv.Itoa(time.Now().Nanosecond()) @@ -137,7 +137,7 @@ func startKeycloak(pool *dockertest.Pool) *dockertest.Resource { func startWekanDB(pool *dockertest.Pool) *dockertest.Resource { dir, _ := os.Getwd() - fields := logger.ContextForMethod("startWekanDB") + fields := logger.ContextForMethod(startWekanDB) mongodbContainerName := "mongodb-ti-" + strconv.Itoa(time.Now().Nanosecond()) mongodb, err := pool.RunWithOptions( &dockertest.RunOptions{ @@ -190,7 +190,7 @@ func startWekanDB(pool *dockertest.Pool) *dockertest.Resource { func restoreMongoDumpInDatabase(mongodb *dockertest.Resource, suffix string, t *testing.T, slugDomainRegexp string) libwekan.Wekan { databasename := t.Name() + suffix - fields := logger.ContextForMethod("restoreMongoDump") + fields := logger.ContextForMethod(restoreMongoDumpInDatabase) fields.AddAny("database", databasename) var output bytes.Buffer outputWriter := bufio.NewWriter(&output) diff --git a/roles.go b/roles.go index faa3157..fbe368a 100644 --- a/roles.go +++ b/roles.go @@ -97,7 +97,7 @@ func (kc KeycloakContext) FindKeycloakRoles(clientName string, roles Roles) []go // ComposeRoles writes roles composition to keycloak server func (kc KeycloakContext) ComposeRoles(clientID string, compositeRoles CompositeRoles) error { - fields := logger.ContextForMethod("kc.ComposeRoles") + fields := logger.ContextForMethod(kc.ComposeRoles) fields.AddAny("clientId", clientID) // Add known roles for role, roles := range compositeRoles { diff --git a/updater.go b/updater.go index e593f09..60e4015 100644 --- a/updater.go +++ b/updater.go @@ -22,7 +22,7 @@ func UpdateKeycloak( configuredUsername Username, maxChangesToAccept int, ) error { - logContext := logger.ContextForMethode(UpdateKeycloak) + logContext := logger.ContextForMethod(UpdateKeycloak) if _, exists := users[configuredUsername]; !exists { return errors.Errorf( @@ -124,7 +124,7 @@ func UpdateKeycloak( } func areYouSureTooApplyChanges(changes, keeps, acceptedChanges int) bool { - fields := logger.ContextForMethod("areYouSureTooApplyChanges") + fields := logger.ContextForMethod(areYouSureTooApplyChanges) logger.Info("nombre d'utilisateurs à rajouter/supprimer/activer : "+strconv.Itoa(changes), fields) logger.Info("nombre d'utilisateurs à conserver : "+strconv.Itoa(keeps), fields) if keeps < 1 { diff --git a/wekan.go b/wekan.go index 68e29e4..d475fce 100644 --- a/wekan.go +++ b/wekan.go @@ -30,7 +30,7 @@ func (pipeline Pipeline) Run(wekan libwekan.Wekan, fromConfig Users) error { } func (pipeline Pipeline) StopAfter(wekan libwekan.Wekan, fromConfig Users, lastStage PipelineStage) error { - fields := logger.ContextForMethod("StopAfter") + fields := logger.ContextForMethod(pipeline.StopAfter) for _, stage := range pipeline { fields.AddAny("stage", stage.id) logger.Debug("applique le pipeline", fields) diff --git a/wekanBoardsMembers.go b/wekanBoardsMembers.go index 31e67e9..6aa7890 100644 --- a/wekanBoardsMembers.go +++ b/wekanBoardsMembers.go @@ -11,7 +11,7 @@ import ( type BoardsMembers map[libwekan.BoardSlug]Users func manageBoardsMembers(wekan libwekan.Wekan, fromConfig Users) error { - fields := logger.ContextForMethod("manageBoardsMembers") + fields := logger.ContextForMethod(manageBoardsMembers) // périmètre du stage wekanBoardsMembers := fromConfig.inferBoardsMember() domainBoards, err := wekan.SelectDomainBoards(context.Background()) @@ -31,7 +31,7 @@ func manageBoardsMembers(wekan libwekan.Wekan, fromConfig Users) error { } func updateBoardMembers(wekan libwekan.Wekan, boardSlug libwekan.BoardSlug, boardMembers Users) error { - fields := logger.ContextForMethod("updateBoardMembers") + fields := logger.ContextForMethod(updateBoardMembers) fields.AddAny("board", boardSlug) board, err := wekan.GetBoardFromSlug(context.Background(), boardSlug) if err != nil { @@ -77,7 +77,7 @@ func updateBoardMembers(wekan libwekan.Wekan, boardSlug libwekan.BoardSlug, boar } func ensureUserIsActiveBoardMember(wekan libwekan.Wekan, user libwekan.User, board libwekan.Board) error { - fields := logger.ContextForMethod("ensureUserIsActiveBoardMember") + fields := logger.ContextForMethod(ensureUserIsActiveBoardMember) fields.AddAny("username", user.Username) fields.AddAny("board", board.Slug) logger.Debug(">>> examine l'utilisateur", fields) @@ -92,7 +92,7 @@ func ensureUserIsActiveBoardMember(wekan libwekan.Wekan, user libwekan.User, boa } func ensureUserIsInactiveBoardMember(wekan libwekan.Wekan, user libwekan.User, board libwekan.Board) error { - fields := logger.ContextForMethod("ensureUserIsInactiveBoardMember") + fields := logger.ContextForMethod(ensureUserIsInactiveBoardMember) fields.AddAny("username", user.Username) fields.AddAny("board", board.Slug) logger.Debug(">>> vérifie la non-participation", fields) diff --git a/wekanTaskforce.go b/wekanTaskforce.go index ea8f983..c3cad38 100644 --- a/wekanTaskforce.go +++ b/wekanTaskforce.go @@ -12,7 +12,7 @@ import ( // Calcule et insère les règles manquantes pour correspondre à la configuration Users // Ajuste la participation des utilisateurs aux cartes concernées par les labels en cas de changement func addMissingRulesAndCardMembership(wekan libwekan.Wekan, users Users) error { - fields := logger.ContextForMethod("addMissingRulesAndCardMembership") + fields := logger.ContextForMethod(addMissingRulesAndCardMembership) logger.Info("> ajoute les nouvelles règles", fields) occurence := 0 for _, user := range users { @@ -52,14 +52,14 @@ func addMissingRulesAndCardMembership(wekan libwekan.Wekan, users Users) error { } } if occurence == 0 { - fields = logger.ContextForMethod("addMissingRulesAndCardMembership") + fields = logger.ContextForMethod(addMissingRulesAndCardMembership) logger.Info("> aucune règle à ajouter", fields) } return nil } func EnsureRuleAddTaskforceMemberExists(wekan libwekan.Wekan, wekanUser libwekan.User, board libwekan.Board, label libwekan.BoardLabel) (int, error) { - fields := logger.ContextForMethod("EnsureRuleAddTaskforceMemberExists") + fields := logger.ContextForMethod(EnsureRuleAddTaskforceMemberExists) fields.AddAny("username", wekanUser.Username) fields.AddAny("board", board.Slug) fields.AddAny("label", label.Name) @@ -74,7 +74,7 @@ func EnsureRuleAddTaskforceMemberExists(wekan libwekan.Wekan, wekanUser libwekan } func EnsureRuleRemoveTaskforceMemberExists(wekan libwekan.Wekan, wekanUser libwekan.User, board libwekan.Board, label libwekan.BoardLabel) (int, error) { - fields := logger.ContextForMethod("EnsureRuleRemoveTaskforceMemberExists") + fields := logger.ContextForMethod(EnsureRuleRemoveTaskforceMemberExists) fields.AddAny("username", wekanUser.Username) fields.AddAny("board", board.Slug) fields.AddAny("label", label.Name) @@ -92,7 +92,7 @@ func EnsureRuleRemoveTaskforceMemberExists(wekan libwekan.Wekan, wekanUser libwe // Calcule et insert les règles manquantes pour correspondre à la configuration Users // Ajuste la participation des utilisateurs aux cartes concernées par les labels en cas de changement func removeExtraRulesAndCardsMembership(wekan libwekan.Wekan, users Users) error { - fields := logger.ContextForMethod("RemoveExtraRulesAndCardMembership") + fields := logger.ContextForMethod(removeExtraRulesAndCardsMembership) logger.Info("> supprime les règles obsolètes", fields) domainBoards, err := wekan.SelectDomainBoards(context.Background()) if err != nil { @@ -142,7 +142,7 @@ func userHasTaskforceLabel(user User) func(label libwekan.BoardLabel) bool { } func removeCardMembership(wekan libwekan.Wekan, wekanUsername libwekan.Username, board libwekan.Board, label libwekan.BoardLabel) error { - fields := logger.ContextForMethod("removeCardMembership") + fields := logger.ContextForMethod(removeCardMembership) fields.AddAny("username", wekanUsername) fields.AddAny("label", label.Name) fields.AddAny("board", board.Slug) @@ -176,7 +176,7 @@ func removeCardMembership(wekan libwekan.Wekan, wekanUsername libwekan.Username, } func addCardMemberShip(wekan libwekan.Wekan, wekanUser libwekan.User, board libwekan.Board, label libwekan.BoardLabel) error { - fields := logger.ContextForMethod("AddCardMembership") + fields := logger.ContextForMethod(addCardMemberShip) fields.AddAny("username", wekanUser.Username) fields.AddAny("label", label.Name) fields.AddAny("board", board.Slug) diff --git a/wekanUsers.go b/wekanUsers.go index 32408e6..30e8dbf 100644 --- a/wekanUsers.go +++ b/wekanUsers.go @@ -18,7 +18,7 @@ var GENUINEUSERSELECTOR = []func(wekan libwekan.Wekan, user libwekan.User) bool{ // checkNativeUsers apporte des logs permettant de garder un œil sur les utilisateurs gérés manuellement func checkNativeUsers(wekan libwekan.Wekan, _ Users) error { ctx := context.Background() - fields := logger.ContextForMethod("checkNativeUsers") + fields := logger.ContextForMethod(checkNativeUsers) logger.Info("inventaire des comptes standards", fields) wekanUsers, err := wekan.GetUsers(ctx) if err != nil { @@ -75,7 +75,7 @@ func selectWekanUsers(wekan libwekan.Wekan) (libwekan.Users, error) { } func insertUsers(ctx context.Context, wekan libwekan.Wekan, users libwekan.Users) error { - fields := logger.ContextForMethod("insertUser") + fields := logger.ContextForMethod(insertUsers) logger.Info("> traite les inscriptions des utilisateurs", fields) fields.AddAny("population", len(users)) logger.Info(">> inscrit les nouveaux utilisateurs", fields) @@ -96,7 +96,7 @@ func insertUsers(ctx context.Context, wekan libwekan.Wekan, users libwekan.Users } func ensureUsersAreEnabled(ctx context.Context, wekan libwekan.Wekan, users libwekan.Users) error { - fields := logger.ContextForMethod("ensureUsersAreEnabled") + fields := logger.ContextForMethod(ensureUsersAreEnabled) fields.AddAny("population", len(users)) logger.Info(">> active des utilisateurs réinscrits", fields) if err := wekan.AssertPrivileged(ctx); err != nil { @@ -119,7 +119,7 @@ func ensureUsersAreEnabled(ctx context.Context, wekan libwekan.Wekan, users libw } func ensureUsersAreDisabled(ctx context.Context, wekan libwekan.Wekan, users libwekan.Users) error { - fields := logger.ContextForMethod("ensureUsersAreDisabled") + fields := logger.ContextForMethod(ensureUsersAreDisabled) fields.AddAny("population", len(users)) logger.Info(">> radie les utilisateurs absents", fields) for _, user := range users { From 540e53dcd04b7b156388e9f852690af4aff88fe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Tue, 12 Sep 2023 19:41:10 +0200 Subject: [PATCH 15/41] utilise les slog.Attr pour logguer le contexte --- config/config.go | 2 +- logger/context.go | 68 ++++++++++++++++++++++-------------------- logger/context_test.go | 20 +++++++++++++ logger/logger.go | 16 +++++----- 4 files changed, 64 insertions(+), 42 deletions(-) create mode 100644 logger/context_test.go diff --git a/config/config.go b/config/config.go index e611390..662cd6c 100644 --- a/config/config.go +++ b/config/config.go @@ -21,7 +21,7 @@ func OverrideConfig(original structs.Config, overridingFilename string) structs. return original } logContext := logger.ContextForMethod(OverrideConfig) - logger.Info("surcharge de configuration", logContext.AddAny("filename", overridingFilename)) + logger.Info("surcharge de configuration", logContext.AddString("filename", overridingFilename)) overridingConfig, err := initConfig(overridingFilename, true) if err != nil { logger.Error( diff --git a/logger/context.go b/logger/context.go index 17714d3..b3e7d85 100644 --- a/logger/context.go +++ b/logger/context.go @@ -1,70 +1,72 @@ package logger import ( + "log/slog" "reflect" "runtime" + "slices" "strings" "github.com/Nerzal/gocloak/v13" ) -type LogContext map[string]interface{} +type LogContext []slog.Attr -func ContextForMethod(method interface{}) LogContext { +func ContextForMethod(method interface{}) *LogContext { methodName := runtime.FuncForPC(reflect.ValueOf(method).Pointer()).Name() - fields := map[string]interface{}{ - "method": methodName, - } - return fields + context := make([]slog.Attr, 0) + context = append(context, slog.String("method", methodName)) + r := LogContext(context) + return &r } -func (d LogContext) AddUser(user gocloak.User) LogContext { - d["user"] = *user.Username +func (d *LogContext) AddAny(key string, any interface{}) *LogContext { + *d = append(*d, slog.Any(key, any)) return d } -func (d LogContext) AddError(err error) LogContext { - d["error"] = err +func (d *LogContext) AddString(key string, value string) *LogContext { + *d = append(*d, slog.String(key, value)) return d } -func (d LogContext) removeError() LogContext { - delete(d, "error") +func (d *LogContext) AddInt(key string, value int) *LogContext { + *d = append(*d, slog.Int(key, value)) return d } -func (d LogContext) AddArray(key string, any []string) LogContext { - d[key] = strings.Join(any, ", ") - return d +func (d *LogContext) AddArray(key string, any []string) *LogContext { + return d.AddString(key, strings.Join(any, ", ")) } -func (d LogContext) AddAny(key string, any interface{}) LogContext { - d[key] = any - return d +func (d *LogContext) AddClient(input gocloak.Client) *LogContext { + return d.AddAny("clientId", input) } -func (d LogContext) Remove(key string) LogContext { - delete(d, key) - return d +func (d *LogContext) AddRole(input gocloak.Role) *LogContext { + return d.AddString("role", role2string(input)) } -func (d LogContext) AddClient(input gocloak.Client) LogContext { - d["clientId"] = *input.ClientID - return d -} - -func (d LogContext) AddRole(input gocloak.Role) LogContext { - d["role"] = role2string(input) - return d -} - -func (d LogContext) AddRoles(all []gocloak.Role) LogContext { +func (d *LogContext) AddRoles(all []gocloak.Role) *LogContext { var val string if all == nil { val = "" } else { val = strings.Join(toStrings(all, role2string), ", ") } - d["roles"] = val + return d.AddString("roles", val) +} + +func (d *LogContext) AddUser(user gocloak.User) *LogContext { + *d = append(*d, slog.Any("user", user)) + return d +} + +func (d *LogContext) Remove(key string) *LogContext { + *d = slices.DeleteFunc(*d, func(c slog.Attr) bool { return c.Key == key }) return d } + +func (d *LogContext) addError(err error) *LogContext { + return d.AddAny("error", err) +} diff --git a/logger/context_test.go b/logger/context_test.go new file mode 100644 index 0000000..af1eb81 --- /dev/null +++ b/logger/context_test.go @@ -0,0 +1,20 @@ +package logger + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_Context_addString(t *testing.T) { + ass := assert.New(t) + logContext := ContextForMethod(Test_Context_addString). + AddString("un TU", "c'est trop cool"). + AddAny("deux TU", "c'est encore mieux") + ass.Len(*logContext, 3) + ass.Equal((*logContext)[0].Key, "method") + ass.Equal((*logContext)[1].Key, "un TU") + ass.Equal((*logContext)[1].Value.String(), "c'est trop cool") + ass.Equal((*logContext)[2].Key, "deux TU") + ass.Equal((*logContext)[2].Value.String(), "c'est encore mieux") +} diff --git a/logger/logger.go b/logger/logger.go index 93b4e51..44043ef 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -49,31 +49,31 @@ func ConfigureWith(config structs.LoggerConfig) { )) } -func Debug(msg string, data map[string]interface{}) { +func Debug(msg string, data *LogContext) { logWithContext(slog.LevelDebug, msg, data, nil) } -func Info(msg string, data map[string]interface{}) { +func Info(msg string, data *LogContext) { logWithContext(slog.LevelInfo, msg, data, nil) } -func Warn(msg string, data map[string]interface{}) { +func Warn(msg string, data *LogContext) { logWithContext(slog.LevelWarn, msg, data, nil) } -func Error(msg string, data map[string]interface{}, err error) { +func Error(msg string, data *LogContext, err error) { logWithContext(slog.LevelWarn, msg, data, err) } -func Panic(msg string, data map[string]interface{}, err error) { +func Panic(msg string, data *LogContext, err error) { Error(msg, data, err) panic(err) } -func logWithContext(level slog.Level, msg string, data map[string]interface{}, err error) { +func logWithContext(level slog.Level, msg string, data *LogContext, err error) { var logCtx []slog.Attr - for k, v := range data { - logCtx = append(logCtx, slog.Any(k, v)) + for _, v := range *data { + logCtx = append(logCtx, v) } if err != nil { logCtx = append(logCtx, slog.Any("error", err)) From 569c02d4720602d6d7fb75e0e9d33e9b577d0749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Tue, 12 Sep 2023 19:43:38 +0200 Subject: [PATCH 16/41] ajoute un test sur le remove --- logger/context_test.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/logger/context_test.go b/logger/context_test.go index af1eb81..63a59a7 100644 --- a/logger/context_test.go +++ b/logger/context_test.go @@ -6,9 +6,9 @@ import ( "github.com/stretchr/testify/assert" ) -func Test_Context_addString(t *testing.T) { +func Test_Context_addSomeFields(t *testing.T) { ass := assert.New(t) - logContext := ContextForMethod(Test_Context_addString). + logContext := ContextForMethod(Test_Context_addSomeFields). AddString("un TU", "c'est trop cool"). AddAny("deux TU", "c'est encore mieux") ass.Len(*logContext, 3) @@ -18,3 +18,12 @@ func Test_Context_addString(t *testing.T) { ass.Equal((*logContext)[2].Key, "deux TU") ass.Equal((*logContext)[2].Value.String(), "c'est encore mieux") } + +func Test_Context_reomveSomeField(t *testing.T) { + ass := assert.New(t) + logContext := ContextForMethod(Test_Context_addSomeFields). + AddAny("to remove", fake.Lorem().Word()). + Remove("to remove") + ass.Len(*logContext, 1) + ass.Equal((*logContext)[0].Key, "method") +} From 291155a46cb376925f6c6be9998674f367728655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Tue, 12 Sep 2023 19:59:30 +0200 Subject: [PATCH 17/41] =?UTF-8?q?corrige=20le=20bug=20sur=20le=20niveau=20?= =?UTF-8?q?de=20log=20Warn=20afich=C3=A9=20pour=20une=20erreur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- logger/logger.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logger/logger.go b/logger/logger.go index 44043ef..28618f2 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -62,7 +62,7 @@ func Warn(msg string, data *LogContext) { } func Error(msg string, data *LogContext, err error) { - logWithContext(slog.LevelWarn, msg, data, err) + logWithContext(slog.LevelError, msg, data, err) } func Panic(msg string, data *LogContext, err error) { From a723f6641991e84d838239165098986f1b54b7fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Tue, 12 Sep 2023 20:21:20 +0200 Subject: [PATCH 18/41] =?UTF-8?q?retire=20le=20mot=20'toolchain'=20du=20go?= =?UTF-8?q?=20mod=20qui=20est=20arriv=C3=A9=20l=C3=A0=20je=20ne=20sais=20p?= =?UTF-8?q?as=20comment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.mod b/go.mod index 1acba6f..497dbff 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,6 @@ module github.com/signaux-faibles/keycloakUpdater/v2 go 1.21 -toolchain go1.21.1 - require ( github.com/BurntSushi/toml v1.3.2 github.com/Nerzal/gocloak/v13 v13.8.0 From 59b808efba098ad599f7ef7965364b20c8c14a35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Tue, 12 Sep 2023 20:38:08 +0200 Subject: [PATCH 19/41] corrige 2 bugs --- config/merge.go | 2 +- logger/logger.go | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/config/merge.go b/config/merge.go index 7980163..8c117bc 100644 --- a/config/merge.go +++ b/config/merge.go @@ -12,7 +12,7 @@ func merge(first structs.Config, second structs.Config) structs.Config { allClients := concatClients(first.Clients, second.Clients) err := mergo.Merge(&first, second, mergo.WithOverride) if err != nil { - logger.Error("erreur pendant le merging de la configuration", logger.ContextForMethod(merge), err) + logger.Panic("erreur pendant le merging de la configuration", logger.ContextForMethod(merge), err) } first.Clients = allClients return first diff --git a/logger/logger.go b/logger/logger.go index 28618f2..d152069 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -72,8 +72,10 @@ func Panic(msg string, data *LogContext, err error) { func logWithContext(level slog.Level, msg string, data *LogContext, err error) { var logCtx []slog.Attr - for _, v := range *data { - logCtx = append(logCtx, v) + if data != nil { + for _, v := range *data { + logCtx = append(logCtx, v) + } } if err != nil { logCtx = append(logCtx, slog.Any("error", err)) From 3024bec03cb1a42af327f98fc6a7ae6f1046dd63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Tue, 12 Sep 2023 20:41:38 +0200 Subject: [PATCH 20/41] utilise go mod pour fixer la version de go dans le pipeline --- .github/workflows/publish.yml | 4 ++-- .github/workflows/tests.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f4d173a..dda2e5a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -16,10 +16,10 @@ jobs: - name: Check out code uses: actions/checkout@v4 - - name: Set up Go 1.20 + - name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version-file: go.mod - name: Build package run: go build -v . diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7bfd7f0..6e89746 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,10 +16,10 @@ jobs: - name: Check out code uses: actions/checkout@v4 - - name: Set up Go 1.20 + - name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version-file: go.mod - name: Build package run: go build -v . From d461c32bfbb74ff615eff65bfd7e2023efed751b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Tue, 12 Sep 2023 23:15:40 +0200 Subject: [PATCH 21/41] renomme les modules --- config/config.go | 4 ++-- config/config_test.go | 2 +- config/merge.go | 4 ++-- config/merge_test.go | 6 ++++-- go.mod | 6 +++--- keycloakContext.go | 4 ++-- keycloak_integration_test.go | 6 +++--- logger/logger.go | 2 +- logger/logger_test.go | 2 +- main.go | 4 ++-- main_integration_test.go | 4 ++-- roles.go | 2 +- updater.go | 2 +- wekan.go | 2 +- wekanBoardsMembers.go | 2 +- wekanTaskforce.go | 2 +- wekanUsers.go | 2 +- 17 files changed, 29 insertions(+), 27 deletions(-) diff --git a/config/config.go b/config/config.go index 662cd6c..2f34a8a 100644 --- a/config/config.go +++ b/config/config.go @@ -7,8 +7,8 @@ import ( "github.com/BurntSushi/toml" "github.com/pkg/errors" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" + "keycloakUpdater/v2/logger" + "keycloakUpdater/v2/structs" ) func InitConfig(configFilename string) (structs.Config, error) { diff --git a/config/config_test.go b/config/config_test.go index 4cda6d0..d704d86 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" + "keycloakUpdater/v2/structs" ) func Test_InitConfig(t *testing.T) { diff --git a/config/merge.go b/config/merge.go index 8c117bc..b7edefa 100644 --- a/config/merge.go +++ b/config/merge.go @@ -4,8 +4,8 @@ import ( "github.com/Nerzal/gocloak/v13" "github.com/imdario/mergo" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" + "keycloakUpdater/v2/logger" + "keycloakUpdater/v2/structs" ) func merge(first structs.Config, second structs.Config) structs.Config { diff --git a/config/merge_test.go b/config/merge_test.go index 88c18b3..b778530 100644 --- a/config/merge_test.go +++ b/config/merge_test.go @@ -1,10 +1,12 @@ package config import ( + "testing" + "github.com/Nerzal/gocloak/v13" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" "github.com/stretchr/testify/assert" - "testing" + + "keycloakUpdater/v2/structs" ) func Test_merge(t *testing.T) { diff --git a/go.mod b/go.mod index 497dbff..1e69172 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,13 @@ -module github.com/signaux-faibles/keycloakUpdater/v2 +module keycloakUpdater/v2 go 1.21 require ( + bou.ke/monkey v1.0.2 github.com/BurntSushi/toml v1.3.2 github.com/Nerzal/gocloak/v13 v13.8.0 github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 + github.com/jaswdr/faker v1.19.0 github.com/ory/dockertest/v3 v3.10.0 github.com/pkg/errors v0.9.1 github.com/samber/slog-formatter v1.0.0 @@ -16,8 +18,6 @@ require ( ) require ( - bou.ke/monkey v1.0.2 // indirect - github.com/jaswdr/faker v1.19.0 // indirect github.com/peterbourgon/diskv/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/samber/lo v1.38.1 // indirect diff --git a/keycloakContext.go b/keycloakContext.go index b9a24c6..44b6041 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -6,8 +6,8 @@ import ( "github.com/Nerzal/gocloak/v13" "github.com/pkg/errors" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" + "keycloakUpdater/v2/logger" + "keycloakUpdater/v2/structs" ) // KeycloakContext carry keycloak state diff --git a/keycloak_integration_test.go b/keycloak_integration_test.go index 25ff372..763e011 100644 --- a/keycloak_integration_test.go +++ b/keycloak_integration_test.go @@ -13,9 +13,9 @@ import ( "github.com/Nerzal/gocloak/v13" "github.com/stretchr/testify/assert" - "github.com/signaux-faibles/keycloakUpdater/v2/config" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" + "keycloakUpdater/v2/config" + "keycloakUpdater/v2/logger" + "keycloakUpdater/v2/structs" ) func TestKeycloakConfiguration_access_username_should_be_present_in_stock_file(t *testing.T) { diff --git a/logger/logger.go b/logger/logger.go index d152069..a12c8de 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -11,7 +11,7 @@ import ( "github.com/pkg/errors" slogmulti "github.com/samber/slog-multi" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" + "keycloakUpdater/v2/structs" ) var loglevel *slog.LevelVar diff --git a/logger/logger_test.go b/logger/logger_test.go index 18544f0..921799e 100644 --- a/logger/logger_test.go +++ b/logger/logger_test.go @@ -14,7 +14,7 @@ import ( "github.com/jaswdr/faker" "github.com/stretchr/testify/assert" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" + "keycloakUpdater/v2/structs" ) var fake faker.Faker diff --git a/main.go b/main.go index 4d4de58..790e92b 100644 --- a/main.go +++ b/main.go @@ -6,8 +6,8 @@ import ( "github.com/pkg/errors" - "github.com/signaux-faibles/keycloakUpdater/v2/config" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" + "keycloakUpdater/v2/config" + "keycloakUpdater/v2/logger" ) var overridingConfigFilename string diff --git a/main_integration_test.go b/main_integration_test.go index bcdfd5c..4b1b0e8 100644 --- a/main_integration_test.go +++ b/main_integration_test.go @@ -20,8 +20,8 @@ import ( "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" - "github.com/signaux-faibles/keycloakUpdater/v2/structs" + "keycloakUpdater/v2/logger" + "keycloakUpdater/v2/structs" ) var kc KeycloakContext diff --git a/roles.go b/roles.go index fbe368a..66a3be9 100644 --- a/roles.go +++ b/roles.go @@ -6,7 +6,7 @@ import ( "github.com/Nerzal/gocloak/v13" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" + "keycloakUpdater/v2/logger" ) // Roles is role collection in []string with some handy functions attached diff --git a/updater.go b/updater.go index 60e4015..4ccc91d 100644 --- a/updater.go +++ b/updater.go @@ -9,7 +9,7 @@ import ( "github.com/Nerzal/gocloak/v13" "github.com/pkg/errors" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" + "keycloakUpdater/v2/logger" ) func UpdateKeycloak( diff --git a/wekan.go b/wekan.go index d475fce..c5c3bef 100644 --- a/wekan.go +++ b/wekan.go @@ -6,7 +6,7 @@ import ( "github.com/signaux-faibles/libwekan" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" + "keycloakUpdater/v2/logger" ) type Pipeline []PipelineStage diff --git a/wekanBoardsMembers.go b/wekanBoardsMembers.go index 6aa7890..75e7ddb 100644 --- a/wekanBoardsMembers.go +++ b/wekanBoardsMembers.go @@ -5,7 +5,7 @@ import ( "github.com/signaux-faibles/libwekan" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" + "keycloakUpdater/v2/logger" ) type BoardsMembers map[libwekan.BoardSlug]Users diff --git a/wekanTaskforce.go b/wekanTaskforce.go index c3cad38..2306b6d 100644 --- a/wekanTaskforce.go +++ b/wekanTaskforce.go @@ -5,7 +5,7 @@ import ( "github.com/signaux-faibles/libwekan" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" + "keycloakUpdater/v2/logger" ) // addMissingRulesAndCardMembership diff --git a/wekanUsers.go b/wekanUsers.go index 30e8dbf..3cf44d7 100644 --- a/wekanUsers.go +++ b/wekanUsers.go @@ -7,7 +7,7 @@ import ( "github.com/signaux-faibles/libwekan" - "github.com/signaux-faibles/keycloakUpdater/v2/logger" + "keycloakUpdater/v2/logger" ) var GENUINEUSERSELECTOR = []func(wekan libwekan.Wekan, user libwekan.User) bool{ From d180261680a33e5d1d26fdfa78252e9c5e2ed1d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Wed, 13 Sep 2023 08:41:19 +0200 Subject: [PATCH 22/41] =?UTF-8?q?d=C3=A9place=20les=20modules=20go=20dans?= =?UTF-8?q?=20un=20r=C3=A9pertoire=20pkg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- keycloakContext.go | 4 ++-- keycloak_integration_test.go | 6 +++--- main.go | 4 ++-- main_integration_test.go | 4 ++-- {config => pkg/config}/config.go | 4 ++-- {config => pkg/config}/config_test.go | 2 +- {config => pkg/config}/empty_test_file.txt | 0 {config => pkg/config}/merge.go | 4 ++-- {config => pkg/config}/merge_test.go | 2 +- {config => pkg/config}/test_config.toml | 0 {config => pkg/config}/test_overriding_config.toml | 0 {logger => pkg/logger}/configuration.go | 0 {logger => pkg/logger}/context.go | 0 {logger => pkg/logger}/context_test.go | 2 +- {logger => pkg/logger}/formatters.go | 0 {logger => pkg/logger}/logger.go | 2 +- {logger => pkg/logger}/logger_test.go | 2 +- {structs => pkg/structs}/structs.go | 0 roles.go | 2 +- updater.go | 2 +- wekan.go | 2 +- wekanBoardsMembers.go | 2 +- wekanTaskforce.go | 2 +- wekanUsers.go | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) rename {config => pkg/config}/config.go (98%) rename {config => pkg/config}/config_test.go (98%) rename {config => pkg/config}/empty_test_file.txt (100%) rename {config => pkg/config}/merge.go (91%) rename {config => pkg/config}/merge_test.go (98%) rename {config => pkg/config}/test_config.toml (100%) rename {config => pkg/config}/test_overriding_config.toml (100%) rename {logger => pkg/logger}/configuration.go (100%) rename {logger => pkg/logger}/context.go (100%) rename {logger => pkg/logger}/context_test.go (94%) rename {logger => pkg/logger}/formatters.go (100%) rename {logger => pkg/logger}/logger.go (98%) rename {logger => pkg/logger}/logger_test.go (99%) rename {structs => pkg/structs}/structs.go (100%) diff --git a/keycloakContext.go b/keycloakContext.go index 44b6041..779ba8d 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -6,8 +6,8 @@ import ( "github.com/Nerzal/gocloak/v13" "github.com/pkg/errors" - "keycloakUpdater/v2/logger" - "keycloakUpdater/v2/structs" + "keycloakUpdater/v2/pkg/logger" + "keycloakUpdater/v2/pkg/structs" ) // KeycloakContext carry keycloak state diff --git a/keycloak_integration_test.go b/keycloak_integration_test.go index 763e011..35d903d 100644 --- a/keycloak_integration_test.go +++ b/keycloak_integration_test.go @@ -13,9 +13,9 @@ import ( "github.com/Nerzal/gocloak/v13" "github.com/stretchr/testify/assert" - "keycloakUpdater/v2/config" - "keycloakUpdater/v2/logger" - "keycloakUpdater/v2/structs" + "keycloakUpdater/v2/pkg/config" + "keycloakUpdater/v2/pkg/logger" + "keycloakUpdater/v2/pkg/structs" ) func TestKeycloakConfiguration_access_username_should_be_present_in_stock_file(t *testing.T) { diff --git a/main.go b/main.go index 790e92b..505ff10 100644 --- a/main.go +++ b/main.go @@ -6,8 +6,8 @@ import ( "github.com/pkg/errors" - "keycloakUpdater/v2/config" - "keycloakUpdater/v2/logger" + "keycloakUpdater/v2/pkg/config" + "keycloakUpdater/v2/pkg/logger" ) var overridingConfigFilename string diff --git a/main_integration_test.go b/main_integration_test.go index 4b1b0e8..a3b5733 100644 --- a/main_integration_test.go +++ b/main_integration_test.go @@ -20,8 +20,8 @@ import ( "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - "keycloakUpdater/v2/logger" - "keycloakUpdater/v2/structs" + "keycloakUpdater/v2/pkg/logger" + "keycloakUpdater/v2/pkg/structs" ) var kc KeycloakContext diff --git a/config/config.go b/pkg/config/config.go similarity index 98% rename from config/config.go rename to pkg/config/config.go index 2f34a8a..b02bc87 100644 --- a/config/config.go +++ b/pkg/config/config.go @@ -7,8 +7,8 @@ import ( "github.com/BurntSushi/toml" "github.com/pkg/errors" - "keycloakUpdater/v2/logger" - "keycloakUpdater/v2/structs" + "keycloakUpdater/v2/pkg/logger" + "keycloakUpdater/v2/pkg/structs" ) func InitConfig(configFilename string) (structs.Config, error) { diff --git a/config/config_test.go b/pkg/config/config_test.go similarity index 98% rename from config/config_test.go rename to pkg/config/config_test.go index d704d86..ce03ac0 100644 --- a/config/config_test.go +++ b/pkg/config/config_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" - "keycloakUpdater/v2/structs" + "keycloakUpdater/v2/pkg/structs" ) func Test_InitConfig(t *testing.T) { diff --git a/config/empty_test_file.txt b/pkg/config/empty_test_file.txt similarity index 100% rename from config/empty_test_file.txt rename to pkg/config/empty_test_file.txt diff --git a/config/merge.go b/pkg/config/merge.go similarity index 91% rename from config/merge.go rename to pkg/config/merge.go index b7edefa..45b3d9d 100644 --- a/config/merge.go +++ b/pkg/config/merge.go @@ -4,8 +4,8 @@ import ( "github.com/Nerzal/gocloak/v13" "github.com/imdario/mergo" - "keycloakUpdater/v2/logger" - "keycloakUpdater/v2/structs" + "keycloakUpdater/v2/pkg/logger" + "keycloakUpdater/v2/pkg/structs" ) func merge(first structs.Config, second structs.Config) structs.Config { diff --git a/config/merge_test.go b/pkg/config/merge_test.go similarity index 98% rename from config/merge_test.go rename to pkg/config/merge_test.go index b778530..fa85572 100644 --- a/config/merge_test.go +++ b/pkg/config/merge_test.go @@ -6,7 +6,7 @@ import ( "github.com/Nerzal/gocloak/v13" "github.com/stretchr/testify/assert" - "keycloakUpdater/v2/structs" + "keycloakUpdater/v2/pkg/structs" ) func Test_merge(t *testing.T) { diff --git a/config/test_config.toml b/pkg/config/test_config.toml similarity index 100% rename from config/test_config.toml rename to pkg/config/test_config.toml diff --git a/config/test_overriding_config.toml b/pkg/config/test_overriding_config.toml similarity index 100% rename from config/test_overriding_config.toml rename to pkg/config/test_overriding_config.toml diff --git a/logger/configuration.go b/pkg/logger/configuration.go similarity index 100% rename from logger/configuration.go rename to pkg/logger/configuration.go diff --git a/logger/context.go b/pkg/logger/context.go similarity index 100% rename from logger/context.go rename to pkg/logger/context.go diff --git a/logger/context_test.go b/pkg/logger/context_test.go similarity index 94% rename from logger/context_test.go rename to pkg/logger/context_test.go index 63a59a7..e01ea50 100644 --- a/logger/context_test.go +++ b/pkg/logger/context_test.go @@ -19,7 +19,7 @@ func Test_Context_addSomeFields(t *testing.T) { ass.Equal((*logContext)[2].Value.String(), "c'est encore mieux") } -func Test_Context_reomveSomeField(t *testing.T) { +func Test_Context_removeField(t *testing.T) { ass := assert.New(t) logContext := ContextForMethod(Test_Context_addSomeFields). AddAny("to remove", fake.Lorem().Word()). diff --git a/logger/formatters.go b/pkg/logger/formatters.go similarity index 100% rename from logger/formatters.go rename to pkg/logger/formatters.go diff --git a/logger/logger.go b/pkg/logger/logger.go similarity index 98% rename from logger/logger.go rename to pkg/logger/logger.go index a12c8de..3b33cd1 100644 --- a/logger/logger.go +++ b/pkg/logger/logger.go @@ -11,7 +11,7 @@ import ( "github.com/pkg/errors" slogmulti "github.com/samber/slog-multi" - "keycloakUpdater/v2/structs" + "keycloakUpdater/v2/pkg/structs" ) var loglevel *slog.LevelVar diff --git a/logger/logger_test.go b/pkg/logger/logger_test.go similarity index 99% rename from logger/logger_test.go rename to pkg/logger/logger_test.go index 921799e..d93bd03 100644 --- a/logger/logger_test.go +++ b/pkg/logger/logger_test.go @@ -14,7 +14,7 @@ import ( "github.com/jaswdr/faker" "github.com/stretchr/testify/assert" - "keycloakUpdater/v2/structs" + "keycloakUpdater/v2/pkg/structs" ) var fake faker.Faker diff --git a/structs/structs.go b/pkg/structs/structs.go similarity index 100% rename from structs/structs.go rename to pkg/structs/structs.go diff --git a/roles.go b/roles.go index 66a3be9..6141121 100644 --- a/roles.go +++ b/roles.go @@ -6,7 +6,7 @@ import ( "github.com/Nerzal/gocloak/v13" - "keycloakUpdater/v2/logger" + "keycloakUpdater/v2/pkg/logger" ) // Roles is role collection in []string with some handy functions attached diff --git a/updater.go b/updater.go index 4ccc91d..7cd5581 100644 --- a/updater.go +++ b/updater.go @@ -9,7 +9,7 @@ import ( "github.com/Nerzal/gocloak/v13" "github.com/pkg/errors" - "keycloakUpdater/v2/logger" + "keycloakUpdater/v2/pkg/logger" ) func UpdateKeycloak( diff --git a/wekan.go b/wekan.go index c5c3bef..819e200 100644 --- a/wekan.go +++ b/wekan.go @@ -6,7 +6,7 @@ import ( "github.com/signaux-faibles/libwekan" - "keycloakUpdater/v2/logger" + "keycloakUpdater/v2/pkg/logger" ) type Pipeline []PipelineStage diff --git a/wekanBoardsMembers.go b/wekanBoardsMembers.go index 75e7ddb..f743871 100644 --- a/wekanBoardsMembers.go +++ b/wekanBoardsMembers.go @@ -5,7 +5,7 @@ import ( "github.com/signaux-faibles/libwekan" - "keycloakUpdater/v2/logger" + "keycloakUpdater/v2/pkg/logger" ) type BoardsMembers map[libwekan.BoardSlug]Users diff --git a/wekanTaskforce.go b/wekanTaskforce.go index 2306b6d..344941c 100644 --- a/wekanTaskforce.go +++ b/wekanTaskforce.go @@ -5,7 +5,7 @@ import ( "github.com/signaux-faibles/libwekan" - "keycloakUpdater/v2/logger" + "keycloakUpdater/v2/pkg/logger" ) // addMissingRulesAndCardMembership diff --git a/wekanUsers.go b/wekanUsers.go index 3cf44d7..74ccc39 100644 --- a/wekanUsers.go +++ b/wekanUsers.go @@ -7,7 +7,7 @@ import ( "github.com/signaux-faibles/libwekan" - "keycloakUpdater/v2/logger" + "keycloakUpdater/v2/pkg/logger" ) var GENUINEUSERSELECTOR = []func(wekan libwekan.Wekan, user libwekan.User) bool{ From 7744b8fdb34ca65aed492d20bf509d5965c63f6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Wed, 13 Sep 2023 10:27:43 +0200 Subject: [PATCH 23/41] =?UTF-8?q?corrige=20le=20bug=20des=20champs=20r?= =?UTF-8?q?=C3=A9p=C3=A9t=C3=A9s=20et=20ajoute=20le=20test=20correspondant?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/logger/context.go | 22 +++++++++------------- pkg/logger/context_test.go | 22 ++++++++++++++++------ 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/pkg/logger/context.go b/pkg/logger/context.go index b3e7d85..578dddb 100644 --- a/pkg/logger/context.go +++ b/pkg/logger/context.go @@ -4,34 +4,31 @@ import ( "log/slog" "reflect" "runtime" - "slices" "strings" "github.com/Nerzal/gocloak/v13" ) -type LogContext []slog.Attr +type LogContext map[string]slog.Attr func ContextForMethod(method interface{}) *LogContext { methodName := runtime.FuncForPC(reflect.ValueOf(method).Pointer()).Name() - context := make([]slog.Attr, 0) - context = append(context, slog.String("method", methodName)) - r := LogContext(context) - return &r + context := make(LogContext) + return (&context).AddString("method", methodName) } -func (d *LogContext) AddAny(key string, any interface{}) *LogContext { - *d = append(*d, slog.Any(key, any)) +func (d *LogContext) AddAny(key string, value any) *LogContext { + (*d)[key] = slog.Any(key, value) return d } func (d *LogContext) AddString(key string, value string) *LogContext { - *d = append(*d, slog.String(key, value)) + (*d)[key] = slog.String(key, value) return d } func (d *LogContext) AddInt(key string, value int) *LogContext { - *d = append(*d, slog.Int(key, value)) + (*d)[key] = slog.Int(key, value) return d } @@ -58,12 +55,11 @@ func (d *LogContext) AddRoles(all []gocloak.Role) *LogContext { } func (d *LogContext) AddUser(user gocloak.User) *LogContext { - *d = append(*d, slog.Any("user", user)) - return d + return d.AddAny("user", user) } func (d *LogContext) Remove(key string) *LogContext { - *d = slices.DeleteFunc(*d, func(c slog.Attr) bool { return c.Key == key }) + delete(*d, key) return d } diff --git a/pkg/logger/context_test.go b/pkg/logger/context_test.go index e01ea50..b2e2b0d 100644 --- a/pkg/logger/context_test.go +++ b/pkg/logger/context_test.go @@ -12,11 +12,11 @@ func Test_Context_addSomeFields(t *testing.T) { AddString("un TU", "c'est trop cool"). AddAny("deux TU", "c'est encore mieux") ass.Len(*logContext, 3) - ass.Equal((*logContext)[0].Key, "method") - ass.Equal((*logContext)[1].Key, "un TU") - ass.Equal((*logContext)[1].Value.String(), "c'est trop cool") - ass.Equal((*logContext)[2].Key, "deux TU") - ass.Equal((*logContext)[2].Value.String(), "c'est encore mieux") + ass.Equal((*logContext)["method"].Key, "method") + ass.Equal((*logContext)["un TU"].Key, "un TU") + ass.Equal((*logContext)["un TU"].Value.String(), "c'est trop cool") + ass.Equal((*logContext)["deux TU"].Key, "deux TU") + ass.Equal((*logContext)["deux TU"].Value.String(), "c'est encore mieux") } func Test_Context_removeField(t *testing.T) { @@ -25,5 +25,15 @@ func Test_Context_removeField(t *testing.T) { AddAny("to remove", fake.Lorem().Word()). Remove("to remove") ass.Len(*logContext, 1) - ass.Equal((*logContext)[0].Key, "method") + ass.Equal((*logContext)["method"].Key, "method") +} + +func Test_Context_addSameFieldTwiceGetOnlyLastValue(t *testing.T) { + ass := assert.New(t) + logContext := ContextForMethod(Test_Context_addSomeFields). + AddAny("un test", fake.Lorem().Word()). + AddString("un test", "c'est bien") + ass.Len(*logContext, 2) + ass.Equal((*logContext)["un test"].Key, "un test") + ass.Equal((*logContext)["un test"].Value.String(), "c'est bien") } From 3ddb18a4c9c56a06573af708a02f32d8a4d5241d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Wed, 13 Sep 2023 10:36:11 +0200 Subject: [PATCH 24/41] remplace quelques AddAny par des AddString --- keycloakContext.go | 10 +++++----- main_integration_test.go | 2 +- roles.go | 2 +- wekanBoardsMembers.go | 3 +-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/keycloakContext.go b/keycloakContext.go index 779ba8d..7dd3b71 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -28,10 +28,10 @@ func NewKeycloakContext(access *structs.Keycloak) (KeycloakContext, error) { // Init provides a connected keycloak context object func Init(hostname, realm, username, password string) (KeycloakContext, error) { - fields := logger.ContextForMethod(Init) - fields.AddAny("path", hostname) - fields.AddAny("realm", realm) - fields.AddAny("user", username) + fields := logger.ContextForMethod(Init). + AddString("path", hostname). + AddString("realm", realm). + AddString("user", username) logger.Info("initialize KeycloakContext [START]", fields) kc := KeycloakContext{} @@ -380,7 +380,7 @@ func (kc *KeycloakContext) SaveMasterRealm(input gocloak.RealmRepresentation) { func (kc *KeycloakContext) refreshRealm(realmName string) { logContext := logger.ContextForMethod(kc.refreshRealm) - logger.Debug("refresh Realm", logContext.AddAny("realm", realmName)) + logger.Debug("refresh Realm", logContext.AddString("realm", realmName)) realm, err := kc.API.GetRealm(context.Background(), kc.JWT.AccessToken, realmName) if err != nil { logger.Panic("Erreur pendant la récupération du Realm", logContext, err) diff --git a/main_integration_test.go b/main_integration_test.go index a3b5733..c334f85 100644 --- a/main_integration_test.go +++ b/main_integration_test.go @@ -82,7 +82,7 @@ func startKeycloak(pool *dockertest.Pool) *dockertest.Resource { // pulls an image, creates a container based on it and runs it keycloakContainerName := "keycloakUpdater-ti-" + strconv.Itoa(time.Now().Nanosecond()) - logContext.AddAny("container", keycloakContainerName) + logContext.AddString("container", keycloakContainerName) logger.Info("Démarre keycloak", logContext) keycloak, err := pool.RunWithOptions( diff --git a/roles.go b/roles.go index 6141121..f6211e6 100644 --- a/roles.go +++ b/roles.go @@ -98,7 +98,7 @@ func (kc KeycloakContext) FindKeycloakRoles(clientName string, roles Roles) []go // ComposeRoles writes roles composition to keycloak server func (kc KeycloakContext) ComposeRoles(clientID string, compositeRoles CompositeRoles) error { fields := logger.ContextForMethod(kc.ComposeRoles) - fields.AddAny("clientId", clientID) + fields.AddString("clientId", clientID) // Add known roles for role, roles := range compositeRoles { fields.AddAny("role", role) diff --git a/wekanBoardsMembers.go b/wekanBoardsMembers.go index f743871..6d8b1bb 100644 --- a/wekanBoardsMembers.go +++ b/wekanBoardsMembers.go @@ -31,8 +31,7 @@ func manageBoardsMembers(wekan libwekan.Wekan, fromConfig Users) error { } func updateBoardMembers(wekan libwekan.Wekan, boardSlug libwekan.BoardSlug, boardMembers Users) error { - fields := logger.ContextForMethod(updateBoardMembers) - fields.AddAny("board", boardSlug) + fields := logger.ContextForMethod(updateBoardMembers).AddAny("board", boardSlug) board, err := wekan.GetBoardFromSlug(context.Background(), boardSlug) if err != nil { return err From 5f4658909f186ac9aabea4da0a55c1282a30bfae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Wed, 13 Sep 2023 10:36:57 +0200 Subject: [PATCH 25/41] remplace quelques AddAny par des AddString --- wekanTaskforce.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wekanTaskforce.go b/wekanTaskforce.go index 344941c..cc4af4c 100644 --- a/wekanTaskforce.go +++ b/wekanTaskforce.go @@ -24,7 +24,7 @@ func addMissingRulesAndCardMembership(wekan libwekan.Wekan, users Users) error { } for _, boardSlug := range user.boards { - fields.AddAny("board", boardSlug) + fields.AddString("board", boardSlug) logger.Debug(">>> examine le tableau", fields) board, err := wekan.GetBoardFromSlug(context.Background(), libwekan.BoardSlug(boardSlug)) if err != nil { From 2444af877b6688f385f7829af2cb06bf0335f824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Wed, 13 Sep 2023 11:29:23 +0200 Subject: [PATCH 26/41] ajoute une fonction de Clone sur le contexte des logs --- pkg/logger/context.go | 6 ++++-- pkg/logger/context_test.go | 21 +++++++++++++++++++++ roles.go | 30 +++++++++++++++--------------- updater.go | 5 ++++- 4 files changed, 44 insertions(+), 18 deletions(-) diff --git a/pkg/logger/context.go b/pkg/logger/context.go index 578dddb..ccd617f 100644 --- a/pkg/logger/context.go +++ b/pkg/logger/context.go @@ -2,6 +2,7 @@ package logger import ( "log/slog" + "maps" "reflect" "runtime" "strings" @@ -63,6 +64,7 @@ func (d *LogContext) Remove(key string) *LogContext { return d } -func (d *LogContext) addError(err error) *LogContext { - return d.AddAny("error", err) +func (d *LogContext) Clone() *LogContext { + clone := maps.Clone(*d) + return &clone } diff --git a/pkg/logger/context_test.go b/pkg/logger/context_test.go index b2e2b0d..8dc0b42 100644 --- a/pkg/logger/context_test.go +++ b/pkg/logger/context_test.go @@ -37,3 +37,24 @@ func Test_Context_addSameFieldTwiceGetOnlyLastValue(t *testing.T) { ass.Equal((*logContext)["un test"].Key, "un test") ass.Equal((*logContext)["un test"].Value.String(), "c'est bien") } + +func Test_Context_clone(t *testing.T) { + ass := assert.New(t) + originalContext := ContextForMethod(Test_Context_addSomeFields). + AddString("original", "c'est bien") + + clonedContext := originalContext.Clone().AddString("clone", "c'est pas bien de copier") + ass.NotEqual(*originalContext, *clonedContext) + ass.NotSame(originalContext, clonedContext) + + ass.Len(*originalContext, 2) + ass.Equal((*originalContext)["original"].Key, "original") + ass.Equal((*originalContext)["original"].Value.String(), "c'est bien") + + ass.Len(*clonedContext, 3) + ass.Equal((*clonedContext)["original"].Key, "original") + ass.Equal((*clonedContext)["original"].Value.String(), "c'est bien") + ass.Equal((*clonedContext)["clone"].Key, "clone") + ass.Equal((*clonedContext)["clone"].Value.String(), "c'est pas bien de copier") + +} diff --git a/roles.go b/roles.go index f6211e6..9119589 100644 --- a/roles.go +++ b/roles.go @@ -97,45 +97,45 @@ func (kc KeycloakContext) FindKeycloakRoles(clientName string, roles Roles) []go // ComposeRoles writes roles composition to keycloak server func (kc KeycloakContext) ComposeRoles(clientID string, compositeRoles CompositeRoles) error { - fields := logger.ContextForMethod(kc.ComposeRoles) - fields.AddString("clientId", clientID) + logContext := logger.ContextForMethod(kc.ComposeRoles).AddString("clientId", clientID) + // Add known roles for role, roles := range compositeRoles { - fields.AddAny("role", role) + logContext.AddAny("role", role) gocloakRole := kc.GetRoleFromRoleName(clientID, role) if gocloakRole == nil { - logger.Warn("role doesn't exists", fields) + logger.Warn("role doesn't exists", logContext) continue } gocloakRoles := kc.FindKeycloakRoles(clientID, roles) - fields.AddRoles(gocloakRoles) + logContext.AddRoles(gocloakRoles) if len(gocloakRoles) != len(roles) { message := fmt.Sprintf("only %d on %d roles exist, some roles may not be used in user base", len(gocloakRoles), len(roles)) - logger.Warn(message, fields) + logger.Warn(message, logContext) if len(gocloakRoles) == 0 { - logger.Warn("no composite roles to send, discarding", fields) + logger.Warn("no composite roles to send, discarding", logContext) continue } } - logger.Info("add composite roles", fields) + logger.Debug("ajoute les roles composites", logContext) err := kc.API.AddClientRoleComposite(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), *gocloakRole.ID, gocloakRoles) if err != nil { - logger.Error("error from keycloak", fields, err) + logger.Error("erreur Keycloak", logContext, err) } } // Clean composite roles internalID, err := kc.GetInternalIDFromClientID(clientID) if err != nil { - logger.Error("can't resolve client", fields, err) + logger.Error("can't resolve client", logContext, err) } for _, r := range kc.ClientRoles[clientID] { - fields.AddRole(*r) + logContext.AddRole(*r) composingRoles, err := kc.API.GetCompositeClientRolesByRoleID(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), internalID, *r.ID) if err != nil { - logger.Error("error when searching composite client role", fields, err) + logger.Error("error when searching composite client role", logContext, err) } wantedRoles := compositeRoles[*r.Name] var deleteRoles []gocloak.Role @@ -145,10 +145,10 @@ func (kc KeycloakContext) ComposeRoles(clientID string, compositeRoles Composite } } if len(deleteRoles) != 0 { - fields.AddRoles(deleteRoles) - logger.Info("removing composing role(s)", fields) + logContext.AddRoles(deleteRoles) + logger.Info("removing composing role(s)", logContext) if err = kc.API.DeleteClientRoleComposite(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), *r.ID, deleteRoles); err != nil { - logger.Error("Error deleting client role composite", fields, err) + logger.Error("Error deleting client role composite", logContext, err) } } } diff --git a/updater.go b/updater.go index 7cd5581..5fe24e6 100644 --- a/updater.go +++ b/updater.go @@ -73,7 +73,10 @@ func UpdateKeycloak( if err != nil { logger.Panic("erreur pendant l'écriture des nouveaux rôles", logContext, err) } - logger.Info("roles created", logContext.AddAny("size", i)) + if i > 0 { + + logger.Info("créations des rôles", logContext.AddAny("size", i)) + } // check and adjust composite roles if err = kc.ComposeRoles(clientId, compositeRoles); err != nil { From 5fc441f5cd96592f1154350e9be6a281e1d40a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Wed, 13 Sep 2023 12:34:25 +0200 Subject: [PATCH 27/41] ajoute des niveaux custom, dont un niveau NOTICE pour Anna --- keycloakContext.go | 6 ++-- main.go | 5 +++- pkg/logger/configuration.go | 3 +- pkg/logger/context_test.go | 1 - pkg/logger/levels.go | 54 ++++++++++++++++++++++++++++++++++++ pkg/logger/levels_test.go | 55 +++++++++++++++++++++++++++++++++++++ pkg/logger/logger.go | 19 ++----------- updater.go | 5 ++-- 8 files changed, 123 insertions(+), 25 deletions(-) create mode 100644 pkg/logger/levels.go create mode 100644 pkg/logger/levels_test.go diff --git a/keycloakContext.go b/keycloakContext.go index 7dd3b71..406d7db 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -33,7 +33,7 @@ func Init(hostname, realm, username, password string) (KeycloakContext, error) { AddString("realm", realm). AddString("user", username) - logger.Info("initialize KeycloakContext [START]", fields) + logger.Info("initialize KeycloakContext", fields.AddString("status", "START")) kc := KeycloakContext{} kc.API = gocloak.NewClient(hostname) var err error @@ -74,7 +74,7 @@ func Init(hostname, realm, username, password string) (KeycloakContext, error) { if err != nil { return KeycloakContext{}, err } - logger.Info("initialize KeycloakContext [DONE]", fields) + logger.Info("initialize KeycloakContext", fields.AddString("status", "END")) return kc, nil } @@ -369,7 +369,7 @@ func (kc *KeycloakContext) SaveMasterRealm(input gocloak.RealmRepresentation) { id := "master" input.ID = &id input.Realm = &id - logger.Info("update realm", fields) + logger.Info("met à jour le Realm", fields) if err := kc.API.UpdateRealm(context.Background(), kc.JWT.AccessToken, input); err != nil { logger.Error("Error when updating Realm ", fields, err) panic(err) diff --git a/main.go b/main.go index 505ff10..bba3fe9 100644 --- a/main.go +++ b/main.go @@ -34,7 +34,10 @@ func main() { logContext := logger.ContextForMethod(main) // loading desired state for users, composites roles - logger.Info("lecture du fichier excel stock", logContext) + logger.Debug( + "lecture du fichier excel stock", + logContext.AddString("filename", conf.Stock.UsersAndRolesFilename), + ) users, compositeRoles, err := loadExcel(conf.Stock.UsersAndRolesFilename) if err != nil { logger.Panic("erreur pendant la lecture du fichier Excel", logContext, err) diff --git a/pkg/logger/configuration.go b/pkg/logger/configuration.go index c3f6ddc..5bd08f2 100644 --- a/pkg/logger/configuration.go +++ b/pkg/logger/configuration.go @@ -28,7 +28,8 @@ func configFileHandler(logFilename string) *slog.TextHandler { panic(err) } return slog.NewTextHandler(file, &slog.HandlerOptions{ - Level: loglevel, + Level: loglevel, + ReplaceAttr: customizeLogLevelNames(), }) } diff --git a/pkg/logger/context_test.go b/pkg/logger/context_test.go index 8dc0b42..d43356b 100644 --- a/pkg/logger/context_test.go +++ b/pkg/logger/context_test.go @@ -56,5 +56,4 @@ func Test_Context_clone(t *testing.T) { ass.Equal((*clonedContext)["original"].Value.String(), "c'est bien") ass.Equal((*clonedContext)["clone"].Key, "clone") ass.Equal((*clonedContext)["clone"].Value.String(), "c'est pas bien de copier") - } diff --git a/pkg/logger/levels.go b/pkg/logger/levels.go new file mode 100644 index 0000000..fd2329e --- /dev/null +++ b/pkg/logger/levels.go @@ -0,0 +1,54 @@ +package logger + +import ( + "log/slog" + "strings" + + "github.com/pkg/errors" +) + +const ( + LevelTrace = slog.Level(-8) + LevelNotice = slog.Level(2) + LevelTraceName = "TRACE" + LevelNoticeName = "NOTICE" +) + +var levelNames = map[slog.Leveler]string{ + LevelTrace: LevelTraceName, + LevelNotice: LevelNoticeName, +} + +func customizeLogLevelNames() func(groups []string, a slog.Attr) slog.Attr { + return func(groups []string, a slog.Attr) slog.Attr { + if a.Key == slog.LevelKey { + level := a.Value.Any().(slog.Level) + levelLabel, exists := levelNames[level] + if !exists { + levelLabel = level.String() + } + a.Value = slog.StringValue(levelLabel) + } + return a + } +} + +func parseLogLevel(logLevel string) (slog.Level, error) { + switch strings.ToUpper(logLevel) { + case "DEBUG": + return slog.LevelDebug, nil + case "INFO": + return slog.LevelInfo, nil + case "WARN": + return slog.LevelWarn, nil + case "ERROR": + return slog.LevelError, nil + // custom levels + case LevelTraceName: + return LevelTrace, nil + case LevelNoticeName: + return LevelNotice, nil + default: + return slog.LevelWarn, errors.New("log level inconnu : '" + logLevel + "'") + } +} diff --git a/pkg/logger/levels_test.go b/pkg/logger/levels_test.go new file mode 100644 index 0000000..88524ad --- /dev/null +++ b/pkg/logger/levels_test.go @@ -0,0 +1,55 @@ +package logger + +import ( + "context" + "log/slog" + "os" + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "keycloakUpdater/v2/pkg/structs" +) + +func Test_level_Trace(t *testing.T) { + ass := assert.New(t) + + traceloggerConfig := structs.LoggerConfig{ + Filename: createTempFilename(t), + Level: "trace", + TimestampFormat: time.DateTime, + } + ConfigureWith(traceloggerConfig) + slog.Log(context.Background(), LevelTrace, "message de Trace") + slog.Log(context.Background(), slog.LevelDebug, "message de Debug") + + var logsFromFile []byte + var err error + logsFromFile, err = os.ReadFile(traceloggerConfig.Filename) + ass.NoError(err) + ass.Contains(string(logsFromFile), "level="+LevelTraceName) + ass.Contains(string(logsFromFile), "level="+slog.LevelDebug.String()) +} + +func Test_level_Notice(t *testing.T) { + ass := assert.New(t) + + noticeloggerConfig := structs.LoggerConfig{ + Filename: createTempFilename(t), + Level: LevelNoticeName, + TimestampFormat: time.DateTime, + } + ConfigureWith(noticeloggerConfig) + slog.Log(context.Background(), slog.LevelInfo, "message d'Info") + slog.Log(context.Background(), LevelNotice, "message de Notice") + slog.Log(context.Background(), slog.LevelWarn, "message de Warn") + + var logsFromFile []byte + var err error + logsFromFile, err = os.ReadFile(noticeloggerConfig.Filename) + ass.NoError(err) + ass.NotContains(string(logsFromFile), "level="+slog.LevelInfo.String()) + ass.Contains(string(logsFromFile), "level="+LevelNoticeName) + ass.Contains(string(logsFromFile), "level="+slog.LevelWarn.String()) +} diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 3b33cd1..7b496cd 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -8,7 +8,6 @@ import ( "slices" "strings" - "github.com/pkg/errors" slogmulti "github.com/samber/slog-multi" "keycloakUpdater/v2/pkg/structs" @@ -21,7 +20,8 @@ func init() { loglevel.Set(slog.LevelInfo) handler := slog.NewJSONHandler(log.Default().Writer(), &slog.HandlerOptions{ - Level: loglevel, + Level: loglevel, + ReplaceAttr: customizeLogLevelNames(), }) parentLogger := slog.New(handler) buildInfo, _ := debug.ReadBuildInfo() @@ -96,18 +96,3 @@ func findBuildSetting(settings []debug.BuildSetting, search string) string { } return retour } - -func parseLogLevel(logLevel string) (slog.Level, error) { - switch strings.ToUpper(logLevel) { - case "DEBUG": - return slog.LevelDebug, nil - case "INFO": - return slog.LevelInfo, nil - case "WARN": - return slog.LevelWarn, nil - case "ERROR": - return slog.LevelError, nil - default: - return slog.LevelInfo, errors.New("log level inconnu : '" + logLevel + "'") - } -} diff --git a/updater.go b/updater.go index 5fe24e6..737c604 100644 --- a/updater.go +++ b/updater.go @@ -74,8 +74,9 @@ func UpdateKeycloak( logger.Panic("erreur pendant l'écriture des nouveaux rôles", logContext, err) } if i > 0 { - - logger.Info("créations des rôles", logContext.AddAny("size", i)) + logger.Info("rôles créés", logContext.Clone().AddAny("size", i).AddArray("roles", newRoles)) + } else { + logger.Debug("pas de rôle à créer", logContext) } // check and adjust composite roles From 7230622db9ce9e506850bb3df4fdd060d2caca0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Wed, 13 Sep 2023 12:42:17 +0200 Subject: [PATCH 28/41] =?UTF-8?q?corrige=20les=20chemins=20des=20fichiers?= =?UTF-8?q?=20apr=C3=A8s=20le=20renommage=20des=20r=C3=A9pertoires=20pkg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/config/config_test.go | 12 ++++++------ pkg/config/test_config.toml | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index ce03ac0..1949af3 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -26,9 +26,9 @@ func Test_InitConfig(t *testing.T) { ass.Equal(expectedKeycloak, *config.Keycloak) expectedStock := structs.Stock{ - ClientsAndRealmFolder: "../test/sample/test_config.d", + ClientsAndRealmFolder: "../../test/sample/test_config.d", ClientForRoles: "signauxfaibles", - UsersAndRolesFilename: "../test/sample/userBase.xlsx", + UsersAndRolesFilename: "../../test/sample/userBase.xlsx", BoardsConfigFilename: "", MaxChangesToAccept: 0, } @@ -76,7 +76,7 @@ func Test_OverrideConfig(t *testing.T) { ass.Equal(expectedKeycloak, *overrided.Keycloak) expectedStock := structs.Stock{ - ClientsAndRealmFolder: "../test/sample/test_config.d", + ClientsAndRealmFolder: "../../test/sample/test_config.d", ClientForRoles: "signauxfaibles", UsersAndRolesFilename: "empty_test_file.txt", BoardsConfigFilename: "", @@ -91,9 +91,9 @@ func Test_getAllConfigFilenames(t *testing.T) { currentConfigFile := "test_config.toml" expected := []string{ currentConfigFile, - "../test/sample/test_config.d/another.toml", - "../test/sample/test_config.d/realm_master.toml", - "../test/sample/test_config.d/client_signauxfaibles.toml", + "../../test/sample/test_config.d/another.toml", + "../../test/sample/test_config.d/realm_master.toml", + "../../test/sample/test_config.d/client_signauxfaibles.toml", } // using the function diff --git a/pkg/config/test_config.toml b/pkg/config/test_config.toml index b36a5a5..586229a 100644 --- a/pkg/config/test_config.toml +++ b/pkg/config/test_config.toml @@ -10,9 +10,9 @@ level = "TRACE" timestampFormat = "2006-01-02 15:04:05" [stock] -clientsAndRealmFolder = "../test/sample/test_config.d" +clientsAndRealmFolder = "../../test/sample/test_config.d" clientForRoles = "signauxfaibles" -usersAndRolesFilename = "../test/sample/userBase.xlsx" +usersAndRolesFilename = "../../test/sample/userBase.xlsx" #[wekan] #username="wekan.ti" From 02a0d17b8ee51b7d7335286394ff729a46009d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Wed, 13 Sep 2023 12:52:25 +0200 Subject: [PATCH 29/41] =?UTF-8?q?ajoute=20les=20m=C3=A9thodes=20Trace=20et?= =?UTF-8?q?=20Notice?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/logger/levels.go | 20 ++++++++++---------- pkg/logger/levels_test.go | 17 ++++++++--------- pkg/logger/logger.go | 8 ++++++++ updater.go | 4 ++-- 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/pkg/logger/levels.go b/pkg/logger/levels.go index fd2329e..0321523 100644 --- a/pkg/logger/levels.go +++ b/pkg/logger/levels.go @@ -8,15 +8,15 @@ import ( ) const ( - LevelTrace = slog.Level(-8) - LevelNotice = slog.Level(2) - LevelTraceName = "TRACE" - LevelNoticeName = "NOTICE" + levelTrace = slog.Level(-8) + levelNotice = slog.Level(2) + levelTraceName = "TRACE" + levelNoticeName = "NOTICE" ) var levelNames = map[slog.Leveler]string{ - LevelTrace: LevelTraceName, - LevelNotice: LevelNoticeName, + levelTrace: levelTraceName, + levelNotice: levelNoticeName, } func customizeLogLevelNames() func(groups []string, a slog.Attr) slog.Attr { @@ -44,10 +44,10 @@ func parseLogLevel(logLevel string) (slog.Level, error) { case "ERROR": return slog.LevelError, nil // custom levels - case LevelTraceName: - return LevelTrace, nil - case LevelNoticeName: - return LevelNotice, nil + case levelTraceName: + return levelTrace, nil + case levelNoticeName: + return levelNotice, nil default: return slog.LevelWarn, errors.New("log level inconnu : '" + logLevel + "'") } diff --git a/pkg/logger/levels_test.go b/pkg/logger/levels_test.go index 88524ad..d1a674d 100644 --- a/pkg/logger/levels_test.go +++ b/pkg/logger/levels_test.go @@ -1,7 +1,6 @@ package logger import ( - "context" "log/slog" "os" "testing" @@ -21,14 +20,14 @@ func Test_level_Trace(t *testing.T) { TimestampFormat: time.DateTime, } ConfigureWith(traceloggerConfig) - slog.Log(context.Background(), LevelTrace, "message de Trace") - slog.Log(context.Background(), slog.LevelDebug, "message de Debug") + Trace("message de Trace", nil) + Debug("message de Debug", nil) var logsFromFile []byte var err error logsFromFile, err = os.ReadFile(traceloggerConfig.Filename) ass.NoError(err) - ass.Contains(string(logsFromFile), "level="+LevelTraceName) + ass.Contains(string(logsFromFile), "level="+levelTraceName) ass.Contains(string(logsFromFile), "level="+slog.LevelDebug.String()) } @@ -37,19 +36,19 @@ func Test_level_Notice(t *testing.T) { noticeloggerConfig := structs.LoggerConfig{ Filename: createTempFilename(t), - Level: LevelNoticeName, + Level: levelNoticeName, TimestampFormat: time.DateTime, } ConfigureWith(noticeloggerConfig) - slog.Log(context.Background(), slog.LevelInfo, "message d'Info") - slog.Log(context.Background(), LevelNotice, "message de Notice") - slog.Log(context.Background(), slog.LevelWarn, "message de Warn") + Info("message d'Info", nil) + Notice("message de Notice", nil) + Warn("message de Warn", nil) var logsFromFile []byte var err error logsFromFile, err = os.ReadFile(noticeloggerConfig.Filename) ass.NoError(err) ass.NotContains(string(logsFromFile), "level="+slog.LevelInfo.String()) - ass.Contains(string(logsFromFile), "level="+LevelNoticeName) + ass.Contains(string(logsFromFile), "level="+levelNoticeName) ass.Contains(string(logsFromFile), "level="+slog.LevelWarn.String()) } diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 7b496cd..474ead9 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -49,6 +49,10 @@ func ConfigureWith(config structs.LoggerConfig) { )) } +func Trace(msg string, data *LogContext) { + logWithContext(levelTrace, msg, data, nil) +} + func Debug(msg string, data *LogContext) { logWithContext(slog.LevelDebug, msg, data, nil) } @@ -57,6 +61,10 @@ func Info(msg string, data *LogContext) { logWithContext(slog.LevelInfo, msg, data, nil) } +func Notice(msg string, data *LogContext) { + logWithContext(levelNotice, msg, data, nil) +} + func Warn(msg string, data *LogContext) { logWithContext(slog.LevelWarn, msg, data, nil) } diff --git a/updater.go b/updater.go index 737c604..2bdf933 100644 --- a/updater.go +++ b/updater.go @@ -74,9 +74,9 @@ func UpdateKeycloak( logger.Panic("erreur pendant l'écriture des nouveaux rôles", logContext, err) } if i > 0 { - logger.Info("rôles créés", logContext.Clone().AddAny("size", i).AddArray("roles", newRoles)) + logger.Notice("rôles créés", logContext.Clone().AddAny("size", i).AddArray("roles", newRoles)) } else { - logger.Debug("pas de rôle à créer", logContext) + logger.Info("pas de rôle à créer", logContext) } // check and adjust composite roles From e346a96a5b7e7e7c33c1344c4c97471f54b3cf41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Wed, 13 Sep 2023 22:40:27 +0200 Subject: [PATCH 30/41] =?UTF-8?q?am=C3=A9liore=20les=20logs=20de=20mise=20?= =?UTF-8?q?=C3=A0=20jour=20pour=20Keycloak?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- keycloakContext.go | 63 +++++++++++++++++++++------------------------- main.go | 2 +- roles.go | 5 +++- updater.go | 21 ++++++++++------ 4 files changed, 46 insertions(+), 45 deletions(-) diff --git a/keycloakContext.go b/keycloakContext.go index 406d7db..2178b74 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -191,26 +191,26 @@ func (kc *KeycloakContext) CreateUsers(users []gocloak.User, userMap Users, clie if err != nil { return err } + logContext := logger.ContextForMethod(kc.CreateUsers).AddString("clientId", clientName) for _, user := range users { - fields := logger.ContextForMethod(kc.CreateUsers) - fields.AddUser(user) - logger.Info("crée l'utilisateur Keycloak", fields) + userLogContext := logContext.Clone().AddUser(user) + logger.Notice("crée l'utilisateur Keycloak", userLogContext) u, err := kc.API.CreateUser(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), user) if err != nil { - logger.Error("Erreur keycloak pendant la création de l'utilisateur", fields, err) + logger.Error("erreur keycloak pendant la création de l'utilisateur", userLogContext, err) } configRoles := userMap[Username(*user.Username)].getRoles() roles := kc.FindKeycloakRoles(clientName, configRoles) - fields.AddRoles(roles) + userLogContext.AddRoles(roles) if roles != nil { - logger.Info("adding roles to user", fields) + logger.Notice("ajoute les rôles à l'utilisateur", userLogContext) if err = kc.AddClientRolesToUser(internalID, u, roles); err != nil { - logger.Error("error adding client roles", fields, err) + logger.Error("erreur pendant l'ajout des rôles à l'utilisateur", userLogContext, err) return err } } else { - logger.Warn("no role to add to user", fields) + logger.Warn("pas de rôle à ajouter au nouvel utilisateur", userLogContext) } } @@ -285,7 +285,7 @@ func (kc *KeycloakContext) EnableUsers(users []gocloak.User) error { // UpdateCurrentUsers sets client roles on specified users according userMap func (kc KeycloakContext) UpdateCurrentUsers(users []gocloak.User, userMap Users, clientName string) error { - fields := logger.ContextForMethod(kc.UpdateCurrentUsers) + logContext := logger.ContextForMethod(kc.UpdateCurrentUsers) accountInternalID, err := kc.GetInternalIDFromClientID("account") if err != nil { return err @@ -296,7 +296,7 @@ func (kc KeycloakContext) UpdateCurrentUsers(users []gocloak.User, userMap Users } for _, user := range users { - fields.AddUser(user) + logContext.AddUser(user) roles, err := kc.API.GetClientRolesByUserID(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), internalID, *user.ID) if err != nil { return err @@ -319,44 +319,41 @@ func (kc KeycloakContext) UpdateCurrentUsers(users []gocloak.User, userMap Users LastName: &u.nom, Attributes: ug.Attributes, } - logger.Info("updating user name and attributes", fields) + logger.Info("met à jour l'utilisateur et ses attributs", logContext.AddAny("update", update)) err := kc.API.UpdateUser(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), update) if err != nil { - logger.Error("failed to update user names", fields, err) + logger.Error("erreur pendant la mise à jour de l'utilisateur", logContext, err) return err } } novel, old := userMap[Username(*user.Username)].getRoles().compare(rolesFromGocloakRoles(roles)) if len(old) > 0 { - fields.AddArray("oldRoles", old) - logger.Info("deleting unused roles", fields) + oldRolesLogContext := logContext.Clone().AddArray("oldRoles", old) + logger.Info("retire les rôles inutilisés", oldRolesLogContext) err = kc.API.DeleteClientRolesFromUser(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), internalID, *user.ID, kc.FindKeycloakRoles(clientName, old)) if err != nil { - logger.Error("failed to delete roles", fields, err) + logger.Error("failed to delete roles", oldRolesLogContext, err) } - fields.Remove("oldRoles") } if len(novel) > 0 { - fields.AddArray("novelRoles", novel) - logger.Info("adding missing roles", fields) + novelRolesLogContext := logContext.Clone().AddArray("novelRoles", novel) + logger.Info("adding missing roles", novelRolesLogContext) keycloakRoles := kc.FindKeycloakRoles(clientName, novel) err = kc.AddClientRolesToUser(internalID, *user.ID, keycloakRoles) if err != nil { - logger.Error("failed to add roles", fields, err) + logger.Error("failed to add roles", novelRolesLogContext, err) } - fields.Remove("novelRoles") } if len(accountRoles) > 0 { - fields.AddArray("accountRoles", accountRoles) - logger.Info("disabling account management", fields) + accountRolesLogContext := logContext.Clone().AddArray("accountRoles", accountRoles) + logger.Info("disabling account management", accountRolesLogContext) err = kc.API.DeleteClientRolesFromUser(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), accountInternalID, *user.ID, kc.FindKeycloakRoles("account", accountRoles)) if err != nil { - logger.Error("failed to disable management", fields, err) + logger.Error("failed to disable management", accountRolesLogContext, err) } - fields.Remove("accountRoles") } } @@ -365,16 +362,14 @@ func (kc KeycloakContext) UpdateCurrentUsers(users []gocloak.User, userMap Users // SaveMasterRealm update master Realm func (kc *KeycloakContext) SaveMasterRealm(input gocloak.RealmRepresentation) { - fields := logger.ContextForMethod(kc.SaveMasterRealm) + logContext := logger.ContextForMethod(kc.SaveMasterRealm) id := "master" input.ID = &id input.Realm = &id - logger.Info("met à jour le Realm", fields) + logger.Info("met à jour le Realm", logContext.AddString("realm", id)) if err := kc.API.UpdateRealm(context.Background(), kc.JWT.AccessToken, input); err != nil { - logger.Error("Error when updating Realm ", fields, err) - panic(err) + logger.Panic("Erreur pendant la mise à jour du Realm ", logContext, err) } - kc.refreshRealm(*input.Realm) } @@ -403,24 +398,22 @@ func (kc *KeycloakContext) SaveClients(input []*gocloak.Client) error { } func (kc KeycloakContext) saveClient(input gocloak.Client) error { - fields := logger.ContextForMethod(kc.saveClient) - fields.AddClient(input) - //kc.refreshClients() + logContext := logger.ContextForMethod(kc.saveClient).AddClient(input) id, found := kc.GetQuietlyInternalIDFromClientID(*input.ClientID) // need client creation if !found { - logger.Info("create client", fields) + logger.Info("crée le client Keycloak", logContext) createdId, err := kc.API.CreateClient(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), input) if err != nil { return errors.WithStack(err) } - fields.AddAny("id", createdId) + logContext.AddAny("id", createdId) return nil } // update client input.ID = &id if err := kc.API.UpdateClient(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), input); err != nil { - logger.Info("update client", fields) + logger.Info("update client", logContext) return errors.Wrap(err, "error updating client") } return nil diff --git a/main.go b/main.go index bba3fe9..3213f43 100644 --- a/main.go +++ b/main.go @@ -79,7 +79,7 @@ func main() { fmt.Println("======= Détail de l'erreur") printErrChain(err, 0) } else { - logger.Info("le traitement s'est terminé correctement", logContext) + logger.Notice("le traitement s'est terminé correctement", logContext) } } diff --git a/roles.go b/roles.go index 9119589..9b179e4 100644 --- a/roles.go +++ b/roles.go @@ -3,6 +3,7 @@ package main import ( "context" "fmt" + "slices" "github.com/Nerzal/gocloak/v13" @@ -46,6 +47,8 @@ func (roles Roles) compare(otherRoles Roles) (Roles, Roles) { toDelete.add(r) } } + slices.Sort(toCreate) + slices.Sort(toDelete) return toCreate, toDelete } @@ -118,7 +121,7 @@ func (kc KeycloakContext) ComposeRoles(clientID string, compositeRoles Composite continue } } - logger.Debug("ajoute les roles composites", logContext) + logger.Info("ajoute les roles composites", logContext) err := kc.API.AddClientRoleComposite(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), *gocloakRole.ID, gocloakRoles) if err != nil { logger.Error("erreur Keycloak", logContext, err) diff --git a/updater.go b/updater.go index 2bdf933..81a411e 100644 --- a/updater.go +++ b/updater.go @@ -3,6 +3,7 @@ package main import ( "context" "fmt" + "slices" "sort" "strconv" @@ -22,7 +23,7 @@ func UpdateKeycloak( configuredUsername Username, maxChangesToAccept int, ) error { - logContext := logger.ContextForMethod(UpdateKeycloak) + logContext := logger.ContextForMethod(UpdateKeycloak).AddString("client", clientId) if _, exists := users[configuredUsername]; !exists { return errors.Errorf( @@ -50,7 +51,7 @@ func UpdateKeycloak( changes := len(missing) + len(obsolete) + len(update) keeps := len(current) if sure := areYouSureTooApplyChanges(changes, keeps, maxChangesToAccept); !sure { - return errors.New("Trop de modifications utilisateurs.") + return errors.New("trop de modifications utilisateurs.") } // gather roles, newRoles are created before users, oldRoles are deleted after users @@ -74,6 +75,7 @@ func UpdateKeycloak( logger.Panic("erreur pendant l'écriture des nouveaux rôles", logContext, err) } if i > 0 { + slices.Sort(newRoles) logger.Notice("rôles créés", logContext.Clone().AddAny("size", i).AddArray("roles", newRoles)) } else { logger.Info("pas de rôle à créer", logContext) @@ -128,19 +130,22 @@ func UpdateKeycloak( } func areYouSureTooApplyChanges(changes, keeps, acceptedChanges int) bool { - fields := logger.ContextForMethod(areYouSureTooApplyChanges) - logger.Info("nombre d'utilisateurs à rajouter/supprimer/activer : "+strconv.Itoa(changes), fields) - logger.Info("nombre d'utilisateurs à conserver : "+strconv.Itoa(keeps), fields) + logContext := logger.ContextForMethod(areYouSureTooApplyChanges) + logger.Notice("utilisateurs à rajouter/supprimer/activer", logContext.Clone().AddInt("nombre", changes)) + logger.Info("utilisateurs à conserver", logContext.Clone().AddInt("nombre", keeps)) if keeps < 1 { - fmt.Println("Aucun utilisateur à conserver -> Refus de prendre en compte les changements.") + logger.Warn("aucun utilisateur à conserver -> Refus de prendre en compte les changements.", logContext) return false } if acceptedChanges <= 0 { - fmt.Println("Tous les changements sont acceptés (acceptedChanges: " + strconv.Itoa(changes) + ")") + logger.Info("tous les changements sont acceptés", logContext.Clone().AddInt("changements", changes)) return true } if changes > acceptedChanges { - fmt.Println("Trop de changements à prendre en compte. (Max : " + strconv.Itoa(acceptedChanges) + ")") + logger.Warn( + "trop de changements à prendre en compte.", + logContext.Clone().AddInt("max", acceptedChanges).AddInt("current", changes), + ) return false } // pas trop de modif From 5dddf1ce62e1c7874e311a40d688c5bc1f026b2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Wed, 13 Sep 2023 22:42:59 +0200 Subject: [PATCH 31/41] corrige un test --- keycloak_integration_test.go | 2 +- main.go | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/keycloak_integration_test.go b/keycloak_integration_test.go index 35d903d..33a812d 100644 --- a/keycloak_integration_test.go +++ b/keycloak_integration_test.go @@ -217,7 +217,7 @@ func TestKeycloak_should_not_update_when_too_many_changes(t *testing.T) { Username(conf.Keycloak.Username), 4, ) - ass.EqualError(actual, "Trop de modifications utilisateurs.") + ass.EqualError(actual, "trop de modifications utilisateurs.") } func TestKeycloakUpdate(t *testing.T) { diff --git a/main.go b/main.go index 3213f43..c953a5b 100644 --- a/main.go +++ b/main.go @@ -63,7 +63,6 @@ func main() { logger.Error("erreur pendant la mise à jour de Keycloak", logContext, err) } } - if conf.Mongo != nil && conf.Wekan != nil { err = WekanUpdate( conf.Mongo.Url, From 0fdb7fe7af26720175190ff3ac39ede390b59c6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Wed, 13 Sep 2023 23:45:30 +0200 Subject: [PATCH 32/41] =?UTF-8?q?am=C3=A9liore=20les=20logs=20wekan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- keycloakContext.go | 18 +++--- pkg/logger/configuration.go | 1 + pkg/logger/formatters.go | 7 +++ wekan.go | 6 +- wekanBoardsMembers.go | 36 ++++++------ wekanTaskforce.go | 111 +++++++++++++++++++++--------------- wekanUsers.go | 49 +++++++--------- 7 files changed, 124 insertions(+), 104 deletions(-) diff --git a/keycloakContext.go b/keycloakContext.go index 2178b74..e0f8653 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -28,53 +28,53 @@ func NewKeycloakContext(access *structs.Keycloak) (KeycloakContext, error) { // Init provides a connected keycloak context object func Init(hostname, realm, username, password string) (KeycloakContext, error) { - fields := logger.ContextForMethod(Init). + logContext := logger.ContextForMethod(Init). AddString("path", hostname). AddString("realm", realm). AddString("user", username) - logger.Info("initialize KeycloakContext", fields.AddString("status", "START")) + logger.Info("initialize KeycloakContext", logContext.AddString("status", "START")) kc := KeycloakContext{} kc.API = gocloak.NewClient(hostname) var err error ctx := context.Background() - logger.Debug("récupère le token d'admin", fields) + logger.Debug("récupère le token d'admin", logContext) kc.JWT, err = kc.API.LoginAdmin(ctx, username, password, realm) if err != nil { return KeycloakContext{}, err } // fetch Realm - logger.Debug("récupère le realm", fields) + logger.Debug("récupère le realm", logContext) kc.Realm, err = kc.API.GetRealm(ctx, kc.JWT.AccessToken, realm) if err != nil { return KeycloakContext{}, err } - logger.Debug("synchronise les clients", fields) + logger.Debug("synchronise les clients", logContext) err = kc.refreshClients() if err != nil { return KeycloakContext{}, err } - logger.Debug("synchronise les utilisateurs", fields) + logger.Debug("synchronise les utilisateurs", logContext) err = kc.refreshUsers() if err != nil { return KeycloakContext{}, err } - logger.Debug("synchronise les rôles du Realm", fields) + logger.Debug("synchronise les rôles du Realm", logContext) kc.Roles, err = kc.API.GetRealmRoles(ctx, kc.JWT.AccessToken, realm, gocloak.GetRoleParams{}) if err != nil { return KeycloakContext{}, err } - logger.Debug("synchronise les rôles clients", fields) + logger.Debug("synchronise les rôles clients", logContext) err = kc.refreshClientRoles() if err != nil { return KeycloakContext{}, err } - logger.Info("initialize KeycloakContext", fields.AddString("status", "END")) + logger.Info("initialize KeycloakContext", logContext.AddString("status", "END")) return kc, nil } diff --git a/pkg/logger/configuration.go b/pkg/logger/configuration.go index 5bd08f2..22e8f40 100644 --- a/pkg/logger/configuration.go +++ b/pkg/logger/configuration.go @@ -16,6 +16,7 @@ func configFormatters(timeFormat string) slogmulti.Middleware { clientFormatter(), singleRoleFormatter(), manyRolesFormatter(), + wekanBoardLabelFormatter(), ) return formattingMiddleware } diff --git a/pkg/logger/formatters.go b/pkg/logger/formatters.go index bd9b983..554b3f6 100644 --- a/pkg/logger/formatters.go +++ b/pkg/logger/formatters.go @@ -8,6 +8,7 @@ import ( "github.com/Nerzal/gocloak/v13" "github.com/samber/slog-formatter" slogmulti "github.com/samber/slog-multi" + "github.com/signaux-faibles/libwekan" ) func addFormattersToHandler(formatters slogmulti.Middleware, handler slog.Handler) slog.Handler { @@ -38,6 +39,12 @@ func userFormatter() slogformatter.Formatter { }) } +func wekanBoardLabelFormatter() slogformatter.Formatter { + return slogformatter.FormatByType(func(boardLabel libwekan.BoardLabel) slog.Value { + return slog.StringValue(string(boardLabel.Name)) + }) +} + func singleRoleFormatter() slogformatter.Formatter { return slogformatter.FormatByType(func(role gocloak.Role) slog.Value { return slog.StringValue(role2string(role)) diff --git a/wekan.go b/wekan.go index 819e200..1d7bef6 100644 --- a/wekan.go +++ b/wekan.go @@ -30,10 +30,10 @@ func (pipeline Pipeline) Run(wekan libwekan.Wekan, fromConfig Users) error { } func (pipeline Pipeline) StopAfter(wekan libwekan.Wekan, fromConfig Users, lastStage PipelineStage) error { - fields := logger.ContextForMethod(pipeline.StopAfter) + logContext := logger.ContextForMethod(pipeline.StopAfter) for _, stage := range pipeline { - fields.AddAny("stage", stage.id) - logger.Debug("applique le pipeline", fields) + logContext.AddString("stage", stage.id) + logger.Debug("applique le pipeline", logContext) err := stage.run(wekan, fromConfig) if err != nil || stage.id == lastStage.id { return err diff --git a/wekanBoardsMembers.go b/wekanBoardsMembers.go index 6d8b1bb..360e40d 100644 --- a/wekanBoardsMembers.go +++ b/wekanBoardsMembers.go @@ -11,7 +11,7 @@ import ( type BoardsMembers map[libwekan.BoardSlug]Users func manageBoardsMembers(wekan libwekan.Wekan, fromConfig Users) error { - fields := logger.ContextForMethod(manageBoardsMembers) + logContext := logger.ContextForMethod(manageBoardsMembers) // périmètre du stage wekanBoardsMembers := fromConfig.inferBoardsMember() domainBoards, err := wekan.SelectDomainBoards(context.Background()) @@ -20,7 +20,7 @@ func manageBoardsMembers(wekan libwekan.Wekan, fromConfig Users) error { } wekanBoardsMembers.addBoards(domainBoards) - logger.Info("> inscrit les utilisateurs dans les tableaux", fields) + logger.Info("> inscrit les utilisateurs dans les tableaux", logContext) for boardSlug, boardMembers := range wekanBoardsMembers { err := updateBoardMembers(wekan, boardSlug, boardMembers) if err != nil { @@ -31,7 +31,7 @@ func manageBoardsMembers(wekan libwekan.Wekan, fromConfig Users) error { } func updateBoardMembers(wekan libwekan.Wekan, boardSlug libwekan.BoardSlug, boardMembers Users) error { - fields := logger.ContextForMethod(updateBoardMembers).AddAny("board", boardSlug) + logContext := logger.ContextForMethod(updateBoardMembers).AddAny("board", boardSlug) board, err := wekan.GetBoardFromSlug(context.Background(), boardSlug) if err != nil { return err @@ -49,14 +49,14 @@ func updateBoardMembers(wekan libwekan.Wekan, boardSlug libwekan.BoardSlug, boar alreadyBoardMembers, expectedInactiveBoardMembers, newBoardMembers := intersect(currentUsersIDs, expectedUsersIDs) - logger.Debug(">> examine les nouvelles inscriptions", fields) + logger.Debug(">> examine les nouvelles inscriptions", logContext) for _, userID := range append(alreadyBoardMembers, newBoardMembers...) { if err := ensureUserIsActiveBoardMember(wekan, expectedUsersMap[userID], board); err != nil { return err } } - logger.Debug(">> examine les radiations", fields) + logger.Debug(">> examine les radiations", logContext) for _, userID := range expectedInactiveBoardMembers { if _, ok := currentUsersMap[userID]; ok { if err := ensureUserIsInactiveBoardMember(wekan, currentUsersMap[userID], board); err != nil { @@ -66,41 +66,41 @@ func updateBoardMembers(wekan libwekan.Wekan, boardSlug libwekan.BoardSlug, boar } // globalWekan.AdminUser() est administrateur de toutes les boards, appliquons la règle - logger.Debug(">> vérifie la participation de l'admin", fields) + logger.Debug(">> vérifie la participation de l'admin", logContext) modified, err := wekan.EnsureUserIsBoardAdmin(context.Background(), board.ID, wekan.AdminID()) if modified { - fields.AddAny("username", wekan.AdminUsername()) - logger.Info(">>> donne les privilèges à l'admin", fields) + logContext.AddAny("username", wekan.AdminUsername()) + logger.Notice(">>> donne les privilèges à l'admin", logContext) } return err } func ensureUserIsActiveBoardMember(wekan libwekan.Wekan, user libwekan.User, board libwekan.Board) error { - fields := logger.ContextForMethod(ensureUserIsActiveBoardMember) - fields.AddAny("username", user.Username) - fields.AddAny("board", board.Slug) - logger.Debug(">>> examine l'utilisateur", fields) + logContext := logger.ContextForMethod(ensureUserIsActiveBoardMember). + AddAny("username", user.Username). + AddAny("board", board.Slug) + logger.Debug(">>> examine l'utilisateur", logContext) modified, err := wekan.EnsureUserIsActiveBoardMember(context.Background(), board.ID, user.ID) if err != nil { return err } if modified { - logger.Info(">>> inscrit l'utilisateur", fields) + logger.Notice(">>> inscrit l'utilisateur", logContext) } return nil } func ensureUserIsInactiveBoardMember(wekan libwekan.Wekan, user libwekan.User, board libwekan.Board) error { - fields := logger.ContextForMethod(ensureUserIsInactiveBoardMember) - fields.AddAny("username", user.Username) - fields.AddAny("board", board.Slug) - logger.Debug(">>> vérifie la non-participation", fields) + logContext := logger.ContextForMethod(ensureUserIsInactiveBoardMember). + AddAny("username", user.Username). + AddAny("board", board.Slug) + logger.Debug(">>> vérifie la non-participation", logContext) modified, err := wekan.EnsureUserIsInactiveBoardMember(context.Background(), board.ID, user.ID) if err != nil { return err } if modified { - logger.Info(">>> désinscrit l'utilisateur", fields) + logger.Notice(">>> désinscrit l'utilisateur", logContext) } return nil } diff --git a/wekanTaskforce.go b/wekanTaskforce.go index cc4af4c..c204171 100644 --- a/wekanTaskforce.go +++ b/wekanTaskforce.go @@ -12,20 +12,20 @@ import ( // Calcule et insère les règles manquantes pour correspondre à la configuration Users // Ajuste la participation des utilisateurs aux cartes concernées par les labels en cas de changement func addMissingRulesAndCardMembership(wekan libwekan.Wekan, users Users) error { - fields := logger.ContextForMethod(addMissingRulesAndCardMembership) - logger.Info("> ajoute les nouvelles règles", fields) + logContext := logger.ContextForMethod(addMissingRulesAndCardMembership) + logger.Info("> ajoute les nouvelles règles", logContext) occurence := 0 for _, user := range users { - fields.AddAny("username", user.email) - logger.Debug(">> examine l'utilisateur", fields) + logContext.AddAny("username", user.email) + logger.Debug(">> examine l'utilisateur", logContext) wekanUser, err := wekan.GetUserFromUsername(context.Background(), libwekan.Username(user.email)) if err != nil { return err } for _, boardSlug := range user.boards { - fields.AddString("board", boardSlug) - logger.Debug(">>> examine le tableau", fields) + logContext.AddString("board", boardSlug) + logger.Debug(">>> examine le tableau", logContext) board, err := wekan.GetBoardFromSlug(context.Background(), libwekan.BoardSlug(boardSlug)) if err != nil { return err @@ -52,37 +52,42 @@ func addMissingRulesAndCardMembership(wekan libwekan.Wekan, users Users) error { } } if occurence == 0 { - fields = logger.ContextForMethod(addMissingRulesAndCardMembership) - logger.Info("> aucune règle à ajouter", fields) + logContext = logger.ContextForMethod(addMissingRulesAndCardMembership) + logger.Info("> aucune règle à ajouter", logContext) } return nil } func EnsureRuleAddTaskforceMemberExists(wekan libwekan.Wekan, wekanUser libwekan.User, board libwekan.Board, label libwekan.BoardLabel) (int, error) { - fields := logger.ContextForMethod(EnsureRuleAddTaskforceMemberExists) - fields.AddAny("username", wekanUser.Username) - fields.AddAny("board", board.Slug) - fields.AddAny("label", label.Name) - logger.Debug(">>> s'assure de l'ajout à la taskforce", fields) + logContext := logger.ContextForMethod(EnsureRuleAddTaskforceMemberExists) + logContext.AddAny("username", wekanUser.Username) + logContext.AddAny("board", board.Slug) + logContext.AddAny("label", label.Name) + logger.Debug(">>> s'assure de l'ajout à la taskforce", logContext) if modified, err := wekan.EnsureRuleAddTaskforceMemberExists(context.Background(), wekanUser, board, label); err != nil { return 0, err } else if modified { - logger.Info(">>> crée de la règle d'ajout à la taskforce", fields) + logger.Notice(">>> crée de la règle d'ajout à la taskforce", logContext) return 1, nil } return 0, nil } -func EnsureRuleRemoveTaskforceMemberExists(wekan libwekan.Wekan, wekanUser libwekan.User, board libwekan.Board, label libwekan.BoardLabel) (int, error) { - fields := logger.ContextForMethod(EnsureRuleRemoveTaskforceMemberExists) - fields.AddAny("username", wekanUser.Username) - fields.AddAny("board", board.Slug) - fields.AddAny("label", label.Name) - logger.Debug(">>> s'assure du retrait de la taskforce", fields) +func EnsureRuleRemoveTaskforceMemberExists( + wekan libwekan.Wekan, + wekanUser libwekan.User, + board libwekan.Board, + label libwekan.BoardLabel, +) (int, error) { + logContext := logger.ContextForMethod(EnsureRuleRemoveTaskforceMemberExists). + AddAny("username", wekanUser.Username). + AddAny("board", board.Slug). + AddAny("label", label.Name) + logger.Debug(">>> s'assure du retrait de la taskforce", logContext) if modified, err := wekan.EnsureRuleRemoveTaskforceMemberExists(context.Background(), wekanUser, board, label); err != nil { return 0, err } else if modified { - logger.Info(">>> crée la règle de retrait de la taskforce", fields) + logger.Notice(">>> crée la règle de retrait de la taskforce", logContext) return 1, nil } return 0, nil @@ -92,8 +97,8 @@ func EnsureRuleRemoveTaskforceMemberExists(wekan libwekan.Wekan, wekanUser libwe // Calcule et insert les règles manquantes pour correspondre à la configuration Users // Ajuste la participation des utilisateurs aux cartes concernées par les labels en cas de changement func removeExtraRulesAndCardsMembership(wekan libwekan.Wekan, users Users) error { - fields := logger.ContextForMethod(removeExtraRulesAndCardsMembership) - logger.Info("> supprime les règles obsolètes", fields) + logContext := logger.ContextForMethod(removeExtraRulesAndCardsMembership) + logger.Info("> supprime les règles obsolètes", logContext) domainBoards, err := wekan.SelectDomainBoards(context.Background()) if err != nil { return err @@ -101,9 +106,9 @@ func removeExtraRulesAndCardsMembership(wekan libwekan.Wekan, users Users) error deleted := 0 for _, board := range domainBoards { - fields.Remove("rule") - fields.AddAny("board", board.Slug) - logger.Debug(">> examine les règles du tableau", fields) + logContext.Remove("rule") + logContext.AddAny("board", board.Slug) + logger.Debug(">> examine les règles du tableau", logContext) rules, err := wekan.SelectRulesFromBoardID(context.Background(), board.ID) if err != nil { return err @@ -111,17 +116,20 @@ func removeExtraRulesAndCardsMembership(wekan libwekan.Wekan, users Users) error taskforceRules := append(rules.SelectAddMemberToTaskforceRule(), rules.SelectRemoveMemberFromTaskforceRule()...) for _, rule := range taskforceRules { - fields.AddAny("rule", rule.Title) - logger.Debug(">>> examine la règle", fields) + logContext.AddString("rule", rule.Title) + logger.Debug(">>> examine la règle", logContext) label := board.GetLabelByID(rule.Trigger.LabelID) - user := users[Username(rule.Action.Username)] + logContext.AddAny("label", label) + username := Username(rule.Action.Username) + user := users[Username(username)] + logContext.AddAny("username", username) // l'utilisateur est absent de la config, du scope wekan ou de la board if !userHasTaskforceLabel(user)(label) || !contains(user.boards, string(board.Slug)) { if err := removeCardMembership(wekan, rule.Action.Username, board, label); err != nil { return err } - logger.Info(">>> supprime la règle", fields) + logger.Notice(">>> supprime la règle", logContext) if err := wekan.RemoveRuleWithID(context.Background(), rule.ID); err != nil { return err } @@ -130,9 +138,9 @@ func removeExtraRulesAndCardsMembership(wekan libwekan.Wekan, users Users) error } } if deleted == 0 { - fields.Remove("board") - fields.Remove("rule") - logger.Info("> aucune règle à supprimer", fields) + logContext.Remove("board") + logContext.Remove("rule") + logger.Notice("> aucune règle à supprimer", logContext) } return nil } @@ -142,11 +150,11 @@ func userHasTaskforceLabel(user User) func(label libwekan.BoardLabel) bool { } func removeCardMembership(wekan libwekan.Wekan, wekanUsername libwekan.Username, board libwekan.Board, label libwekan.BoardLabel) error { - fields := logger.ContextForMethod(removeCardMembership) - fields.AddAny("username", wekanUsername) - fields.AddAny("label", label.Name) - fields.AddAny("board", board.Slug) - logger.Debug(">>> examine les cartes", fields) + logContext := logger.ContextForMethod(removeCardMembership). + AddAny("username", wekanUsername). + AddAny("label", label.Name). + AddAny("board", board.Slug) + logger.Debug(">>> examine les cartes", logContext) wekanUser, err := wekan.GetUserFromUsername(context.Background(), wekanUsername) if err != nil { return err @@ -157,6 +165,7 @@ func removeCardMembership(wekan libwekan.Wekan, wekanUsername libwekan.Username, return err } var occurences int + cardsToBeRemoved := make([]string, 0) for _, card := range boardCards { if contains(card.LabelIDs, label.ID) { modified, err := wekan.EnsureMemberOutOfCard(context.Background(), card.ID, wekanUser.ID) @@ -164,23 +173,27 @@ func removeCardMembership(wekan libwekan.Wekan, wekanUsername libwekan.Username, return err } if modified { + cardsToBeRemoved = append(cardsToBeRemoved, card.Title) occurences += 1 } } } if occurences > 0 { - fields.AddAny("occurences", occurences) - logger.Info(">>> radie l'utilisateur des cartes", fields) + logContext.AddAny("occurences", occurences) + logger.Info( + ">>> radie l'utilisateur des cartes", + logContext.AddInt("occurences", occurences).AddArray("cards", cardsToBeRemoved), + ) } return nil } func addCardMemberShip(wekan libwekan.Wekan, wekanUser libwekan.User, board libwekan.Board, label libwekan.BoardLabel) error { - fields := logger.ContextForMethod(addCardMemberShip) - fields.AddAny("username", wekanUser.Username) - fields.AddAny("label", label.Name) - fields.AddAny("board", board.Slug) - logger.Debug(">>> examen des cartes", fields) + logContext := logger.ContextForMethod(addCardMemberShip). + AddAny("username", wekanUser.Username). + AddAny("label", label.Name). + AddAny("board", board.Slug) + logger.Debug(">>> examen des cartes", logContext) cards, err := wekan.SelectCardsFromBoardID(context.Background(), board.ID) boardCards := selectSlice(cards, func(card libwekan.Card) bool { return card.BoardID == board.ID }) @@ -189,6 +202,7 @@ func addCardMemberShip(wekan libwekan.Wekan, wekanUser libwekan.User, board libw return err } var occurences int + cardsToBeAdded := make([]string, 0) for _, card := range boardCards { if contains(card.LabelIDs, label.ID) { modified, err := wekan.EnsureMemberInCard(context.Background(), card.ID, wekanUser.ID) @@ -196,13 +210,16 @@ func addCardMemberShip(wekan libwekan.Wekan, wekanUser libwekan.User, board libw return err } if modified { + cardsToBeAdded = append(cardsToBeAdded, card.Title) occurences++ } } } if occurences > 0 { - fields.AddAny("occurences", occurences) - logger.Info(">>> inscrit l'utilisateur sur les cartes", fields) + logger.Notice( + ">>> inscrit l'utilisateur sur les cartes", + logContext.AddInt("occurences", occurences).AddArray("cards", cardsToBeAdded), + ) } return nil } diff --git a/wekanUsers.go b/wekanUsers.go index 74ccc39..b7f354f 100644 --- a/wekanUsers.go +++ b/wekanUsers.go @@ -18,8 +18,8 @@ var GENUINEUSERSELECTOR = []func(wekan libwekan.Wekan, user libwekan.User) bool{ // checkNativeUsers apporte des logs permettant de garder un œil sur les utilisateurs gérés manuellement func checkNativeUsers(wekan libwekan.Wekan, _ Users) error { ctx := context.Background() - fields := logger.ContextForMethod(checkNativeUsers) - logger.Info("inventaire des comptes standards", fields) + logContext := logger.ContextForMethod(checkNativeUsers) + logger.Info("inventaire des comptes standards", logContext) wekanUsers, err := wekan.GetUsers(ctx) if err != nil { return err @@ -27,7 +27,7 @@ func checkNativeUsers(wekan libwekan.Wekan, _ Users) error { for _, user := range wekanUsers { if !user.LoginDisabled && user.AuthenticationMethod != "oauth2" && user.Username != wekan.AdminUsername() { - fields.AddAny("username", user.Username) + logContext.AddAny("username", user.Username) boards, err := wekan.SelectBoardsFromMemberID(ctx, user.ID) if err != nil { return err @@ -35,8 +35,8 @@ func checkNativeUsers(wekan libwekan.Wekan, _ Users) error { activeUserBoards := selectSlice(boards, func(board libwekan.Board) bool { return board.UserIsActiveMember(user) && board.Slug != "templates" }) activeUserBoardSlugs := mapSlice(activeUserBoards, func(board libwekan.Board) libwekan.BoardSlug { return board.Slug }) - fields.AddAny("boards", activeUserBoardSlugs) - logger.Warn("utilisateur standard actif", fields) + logContext.AddAny("boards", activeUserBoardSlugs) + logger.Warn("utilisateur standard actif", logContext) } } return nil @@ -75,20 +75,18 @@ func selectWekanUsers(wekan libwekan.Wekan) (libwekan.Users, error) { } func insertUsers(ctx context.Context, wekan libwekan.Wekan, users libwekan.Users) error { - fields := logger.ContextForMethod(insertUsers) - logger.Info("> traite les inscriptions des utilisateurs", fields) - fields.AddAny("population", len(users)) - logger.Info(">> inscrit les nouveaux utilisateurs", fields) + logContext := logger.ContextForMethod(insertUsers) + logger.Info("> traite les inscriptions des utilisateurs", logContext) + logContext.AddInt("population", len(users)) + logger.Info(">> inscrit les nouveaux utilisateurs", logContext) if err := wekan.AssertPrivileged(ctx); err != nil { return err } - for _, user := range users { - fields.AddAny("username", user.Username) - logger.Info(">>> crée l'utilisateur", fields) + logger.Notice(">>> crée l'utilisateur", logContext.AddAny("username", user.Username)) err := wekan.InsertUser(ctx, user) if err != nil { - logger.Error("erreur Wekan pendant la création des utilisateurs", fields, err) + logger.Error("erreur Wekan pendant la création des utilisateurs", logContext, err) return err } } @@ -96,44 +94,41 @@ func insertUsers(ctx context.Context, wekan libwekan.Wekan, users libwekan.Users } func ensureUsersAreEnabled(ctx context.Context, wekan libwekan.Wekan, users libwekan.Users) error { - fields := logger.ContextForMethod(ensureUsersAreEnabled) - fields.AddAny("population", len(users)) - logger.Info(">> active des utilisateurs réinscrits", fields) + logContext := logger.ContextForMethod(ensureUsersAreEnabled) + logger.Info(">> active des utilisateurs réinscrits", logContext.Clone().AddInt("population", len(users))) if err := wekan.AssertPrivileged(ctx); err != nil { return err } for _, user := range users { - fields.AddAny("username", user.Username) - logger.Debug(">>> examine le statut de l'utilisateur", fields) + logger.Debug(">>> examine le statut de l'utilisateur", logContext.AddAny("username", user.Username)) err := wekan.EnableUser(ctx, user) if err == (libwekan.NothingDoneError{}) { continue } if err != nil { - logger.Error("erreur Wekan pendant la radiation des utilisateurs", fields, err) + logger.Error("erreur Wekan pendant la radiation d'un utilisateur", logContext, err) return err } - logger.Info(">>> active l'utilisateur", fields) + logger.Notice(">>> active l'utilisateur", logContext) } return nil } func ensureUsersAreDisabled(ctx context.Context, wekan libwekan.Wekan, users libwekan.Users) error { - fields := logger.ContextForMethod(ensureUsersAreDisabled) - fields.AddAny("population", len(users)) - logger.Info(">> radie les utilisateurs absents", fields) + logContext := logger.ContextForMethod(ensureUsersAreDisabled) + logger.Info(">> radie les utilisateurs absents", logContext.Clone().AddInt("population", len(users))) for _, user := range users { - fields.AddAny("username", user.Username) - logger.Debug(">>> examine le statut de l'utilisateur", fields) + logContext.AddAny("username", user.Username) + logger.Debug(">>> examine le statut de l'utilisateur", logContext) err := wekan.DisableUser(ctx, user) if err == (libwekan.NothingDoneError{}) { continue } if err != nil { - logger.Error("erreur Wekan pendant l'examen du statut des utilisateurs", fields, err) + logger.Error("erreur Wekan pendant l'examen du statut des utilisateurs", logContext, err) return err } - logger.Info(">>> désactive l'utilisateur", fields) + logger.Notice(">>> désactive l'utilisateur", logContext) } return nil } From e544df0e9176a2134f0f7d6ec29fb57678a20d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Wed, 13 Sep 2023 23:52:30 +0200 Subject: [PATCH 33/41] =?UTF-8?q?am=C3=A9liore=20les=20logs=20wekan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wekanTaskforce.go | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/wekanTaskforce.go b/wekanTaskforce.go index c204171..8e3d4b7 100644 --- a/wekanTaskforce.go +++ b/wekanTaskforce.go @@ -67,7 +67,7 @@ func EnsureRuleAddTaskforceMemberExists(wekan libwekan.Wekan, wekanUser libwekan if modified, err := wekan.EnsureRuleAddTaskforceMemberExists(context.Background(), wekanUser, board, label); err != nil { return 0, err } else if modified { - logger.Notice(">>> crée de la règle d'ajout à la taskforce", logContext) + logger.Notice(">>> crée la règle d'ajout à la taskforce", logContext) return 1, nil } return 0, nil @@ -140,7 +140,7 @@ func removeExtraRulesAndCardsMembership(wekan libwekan.Wekan, users Users) error if deleted == 0 { logContext.Remove("board") logContext.Remove("rule") - logger.Notice("> aucune règle à supprimer", logContext) + logger.Info("> aucune règle à supprimer", logContext) } return nil } @@ -165,7 +165,6 @@ func removeCardMembership(wekan libwekan.Wekan, wekanUsername libwekan.Username, return err } var occurences int - cardsToBeRemoved := make([]string, 0) for _, card := range boardCards { if contains(card.LabelIDs, label.ID) { modified, err := wekan.EnsureMemberOutOfCard(context.Background(), card.ID, wekanUser.ID) @@ -173,7 +172,6 @@ func removeCardMembership(wekan libwekan.Wekan, wekanUsername libwekan.Username, return err } if modified { - cardsToBeRemoved = append(cardsToBeRemoved, card.Title) occurences += 1 } } @@ -181,8 +179,8 @@ func removeCardMembership(wekan libwekan.Wekan, wekanUsername libwekan.Username, if occurences > 0 { logContext.AddAny("occurences", occurences) logger.Info( - ">>> radie l'utilisateur des cartes", - logContext.AddInt("occurences", occurences).AddArray("cards", cardsToBeRemoved), + ">>> radie l'utilisateur des cartes du board", + logContext.AddInt("occurences", occurences), ) } return nil @@ -202,7 +200,6 @@ func addCardMemberShip(wekan libwekan.Wekan, wekanUser libwekan.User, board libw return err } var occurences int - cardsToBeAdded := make([]string, 0) for _, card := range boardCards { if contains(card.LabelIDs, label.ID) { modified, err := wekan.EnsureMemberInCard(context.Background(), card.ID, wekanUser.ID) @@ -210,15 +207,14 @@ func addCardMemberShip(wekan libwekan.Wekan, wekanUser libwekan.User, board libw return err } if modified { - cardsToBeAdded = append(cardsToBeAdded, card.Title) occurences++ } } } if occurences > 0 { logger.Notice( - ">>> inscrit l'utilisateur sur les cartes", - logContext.AddInt("occurences", occurences).AddArray("cards", cardsToBeAdded), + ">>> inscrit l'utilisateur sur les cartes du board", + logContext.AddInt("occurences", occurences), ) } return nil From e5817936ffcd3ea1856284922b73fb1a8689c7b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Thu, 14 Sep 2023 09:19:47 +0200 Subject: [PATCH 34/41] =?UTF-8?q?am=C3=A9liore=20les=20logs=20wekan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wekanBoardsMembers.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wekanBoardsMembers.go b/wekanBoardsMembers.go index 360e40d..ff71e27 100644 --- a/wekanBoardsMembers.go +++ b/wekanBoardsMembers.go @@ -85,7 +85,7 @@ func ensureUserIsActiveBoardMember(wekan libwekan.Wekan, user libwekan.User, boa return err } if modified { - logger.Notice(">>> inscrit l'utilisateur", logContext) + logger.Notice(">>> inscrit l'utilisateur sur le board", logContext) } return nil } @@ -100,7 +100,7 @@ func ensureUserIsInactiveBoardMember(wekan libwekan.Wekan, user libwekan.User, b return err } if modified { - logger.Notice(">>> désinscrit l'utilisateur", logContext) + logger.Notice(">>> désinscrit l'utilisateur du board", logContext) } return nil } From 5eb5b1cd3ec96b6d91c3a2546b636346dceb2026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Fri, 15 Sep 2023 13:10:40 +0200 Subject: [PATCH 35/41] corrige un bug pour retirer les espaces des adresses email --- excel.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/excel.go b/excel.go index d2864ba..4262917 100644 --- a/excel.go +++ b/excel.go @@ -66,7 +66,7 @@ func loadExcel(excelFileName string) (Users, map[string]Roles, error) { for _, userRow := range table[1:] { niveau := userRow[fields["NIVEAU HABILITATION"]] - email := Username(strings.Trim(strings.ToLower(userRow[fields["ADRESSE MAIL"]]), " ")) + email := Username(strings.TrimSpace(strings.ToLower(userRow[fields["ADRESSE MAIL"]]))) if email != "" && len(userRow[fields["PRENOM"]]) > 1 { user := User{ From e3bd39777503be2a1fd127be3f01e4f0a8e1e170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Fri, 15 Sep 2023 13:27:37 +0200 Subject: [PATCH 36/41] =?UTF-8?q?ajoute=20un=20espace=20insecable=20dans?= =?UTF-8?q?=20l'email=20dans=20le=20fichier=20excel=20pour=20am=C3=A9liore?= =?UTF-8?q?r=20le=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/sample/userBase.xlsx | Bin 12923 -> 13777 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/test/sample/userBase.xlsx b/test/sample/userBase.xlsx index 10f6e9151be26ae79333ea419196b4861e0360c8..3be4ec096c8f7a558d0a4c04d99640a98fd4e008 100644 GIT binary patch delta 9003 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 YWdSR&0Z~z2gwCX@ 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 Date: Fri, 15 Sep 2023 13:46:06 +0200 Subject: [PATCH 37/41] passe l'image docker en go 1.21 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ca3672b..187dee5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ ############################ # STEP 1 build executable binary ############################ -FROM golang:1.20-alpine AS builder +FROM golang:1.21-alpine AS builder # Install git. # Git is required for fetching the dependencies. From e64dce15790d70cd32c5e2cca3c1c8fbf882f376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Fri, 15 Sep 2023 14:38:43 +0200 Subject: [PATCH 38/41] =?UTF-8?q?corrige=20la=20remont=C3=A9e=20d'erreur?= =?UTF-8?q?=20en=20cas=20d'erreur=20de=20cr=C3=A9ation=20de=20compte=20key?= =?UTF-8?q?cloak?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- keycloakContext.go | 1 + main.go | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/keycloakContext.go b/keycloakContext.go index e0f8653..e80e28b 100644 --- a/keycloakContext.go +++ b/keycloakContext.go @@ -198,6 +198,7 @@ func (kc *KeycloakContext) CreateUsers(users []gocloak.User, userMap Users, clie u, err := kc.API.CreateUser(context.Background(), kc.JWT.AccessToken, kc.getRealmName(), user) if err != nil { logger.Error("erreur keycloak pendant la création de l'utilisateur", userLogContext, err) + return err } configRoles := userMap[Username(*user.Username)].getRoles() diff --git a/main.go b/main.go index c953a5b..6c2090d 100644 --- a/main.go +++ b/main.go @@ -77,9 +77,9 @@ func main() { logger.Error("le traitement s'est terminé de façon anormale", logContext, err) fmt.Println("======= Détail de l'erreur") printErrChain(err, 0) - } else { - logger.Notice("le traitement s'est terminé correctement", logContext) + return } + logger.Notice("le traitement s'est terminé correctement", logContext) } func printErrChain(err error, i int) { From e83812ee87d4d1996664f84b7fd3c8a62c5348de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Fri, 15 Sep 2023 15:58:04 +0200 Subject: [PATCH 39/41] un peu de pimp --- main.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 6c2090d..cb4bd22 100644 --- a/main.go +++ b/main.go @@ -42,8 +42,9 @@ func main() { if err != nil { logger.Panic("erreur pendant la lecture du fichier Excel", logContext, err) } - if conf.Keycloak != nil { + keycloakLogContext := logContext.Clone() + logger.Notice("mise à jour des habilitations Keycloak", keycloakLogContext.AddString("status", "START")) clientId := conf.Stock.ClientForRoles kc, err := NewKeycloakContext(conf.Keycloak) if err != nil { @@ -62,8 +63,11 @@ func main() { ); err != nil { logger.Error("erreur pendant la mise à jour de Keycloak", logContext, err) } + logger.Notice("mise à jour des habilitations Keycloak", keycloakLogContext.AddString("status", "END")) } if conf.Mongo != nil && conf.Wekan != nil { + wekanLogContext := logContext.Clone() + logger.Notice("mise à jour des habilitations Wekan", wekanLogContext.AddString("status", "START")) err = WekanUpdate( conf.Mongo.Url, conf.Mongo.Database, @@ -71,6 +75,10 @@ func main() { users, conf.Wekan.SlugDomainRegexp, ) + if err != nil { + logger.Error("erreur pendant la mise à jour de Keycloak", logContext, err) + } + logger.Notice("mise à jour des habilitations Wekan", wekanLogContext.AddString("status", "END")) } if err != nil { From 171388df289196eed99c55b7c1cc0defbdbaa0b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Mon, 18 Sep 2023 12:27:33 +0200 Subject: [PATCH 40/41] =?UTF-8?q?permet=20de=20pousser=20dans=20le=20repo?= =?UTF-8?q?=20des=20containers=20keycloak=20updater=20=C3=A0=20chaque=20co?= =?UTF-8?q?mmit=20sur=20une=20branche?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/dependabot.yml | 5 +++++ .github/workflows/publish.yml | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 26da661..5d5b020 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,3 +9,8 @@ updates: directory: / schedule: interval: daily + + - package-ecosystem: docker + directory: / + schedule: + interval: daily diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index dda2e5a..375c017 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,8 +1,10 @@ name: CI - Publication on: + push: + branches: release: - types: [ published, edited ] + types: [published] env: GOFLAGS: -mod=readonly @@ -55,7 +57,7 @@ jobs: tags: | type=ref,event=branch type=ref,event=tag - type=ref,event=pr + type=sha,format=short flavor: | latest=true From d6112c8764ca901ccc5ee2698dd41d1b2bd51f5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raphae=CC=88l=20Squelbut?= Date: Mon, 18 Sep 2023 14:06:58 +0200 Subject: [PATCH 41/41] baisse le niveau de log d'un message --- wekanUsers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wekanUsers.go b/wekanUsers.go index b7f354f..a3129b8 100644 --- a/wekanUsers.go +++ b/wekanUsers.go @@ -36,7 +36,7 @@ func checkNativeUsers(wekan libwekan.Wekan, _ Users) error { activeUserBoards := selectSlice(boards, func(board libwekan.Board) bool { return board.UserIsActiveMember(user) && board.Slug != "templates" }) activeUserBoardSlugs := mapSlice(activeUserBoards, func(board libwekan.Board) libwekan.BoardSlug { return board.Slug }) logContext.AddAny("boards", activeUserBoardSlugs) - logger.Warn("utilisateur standard actif", logContext) + logger.Info("utilisateur standard actif", logContext) } } return nil