Skip to content

Commit

Permalink
feat: enable dynamic configuration (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
Florian Rusch (cluetec GmbH) authored Nov 3, 2023
1 parent c4ec1e0 commit 7f7180c
Show file tree
Hide file tree
Showing 11 changed files with 312 additions and 15 deletions.
29 changes: 26 additions & 3 deletions cmd/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package cmd

import (
"fmt"

"github.com/cluetec/lifeboat/internal/config"
"github.com/cluetec/lifeboat/internal/destination"
"github.com/cluetec/lifeboat/internal/logging"
"github.com/cluetec/lifeboat/internal/source"
"github.com/spf13/cobra"
"log/slog"
"os"
)

// backupCmd represents the backup command
Expand All @@ -27,6 +32,24 @@ var backupCmd = &cobra.Command{
Short: "Execute the backup.",
Long: "Execute the backup. Used config can be overridden by providing arguments.",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("backup called")
c, err := config.New()
if err != nil {
slog.Error("error while initializing config", "error", err)
os.Exit(1)
}

logging.InitSlog(c.GetLogLevel())

slog.Debug("global config loaded", slog.Any("globalConfig", c))
slog.Debug("log level set", slog.String("logLevel", c.LogLevel))

slog.Debug("start of backup command")

source.Prepare(c.Source)
destination.Prepare(c.Destination)

slog.Info("TODO: Do backup")

slog.Debug("end of backup command")
},
}
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package cmd

import (
Expand Down
9 changes: 9 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
source:
type: filesystem
path: source

destination:
type: filesystem
path: destination

logLevel: debug
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/cluetec/lifeboat
go 1.21

require (
github.com/mitchellh/mapstructure v1.5.0
github.com/spf13/cobra v1.7.0
github.com/spf13/viper v1.17.0
)
Expand All @@ -12,7 +13,6 @@ require (
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
Expand Down
62 changes: 51 additions & 11 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,65 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package config

import (
"github.com/spf13/viper"
"log/slog"
"strings"

"github.com/spf13/viper"
)

func InitViper() error {
viper.AutomaticEnv()
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.AddConfigPath(".")
viper.SetConfigFile("./config.yaml")
type SourceConfig struct {
Type string
ResourceConfig map[string]any `mapstructure:",remain"`
}

type DestinationConfig struct {
Type string
ResourceConfig map[string]any `mapstructure:",remain"`
}

type Config struct {
Source SourceConfig
Destination DestinationConfig
LogLevel string
}

func (c *Config) GetLogLevel() slog.Level {
var level slog.Level

switch strings.ToLower(c.LogLevel) {
case "debug":
level = slog.LevelDebug
case "info":
level = slog.LevelInfo
case "warn":
level = slog.LevelWarn
case "error":
level = slog.LevelError
default:
level = slog.LevelInfo
}

return level
}

func (c *Config) DebugEnabled() bool {
return strings.ToLower(c.LogLevel) == "debug"
}

func New() (*Config, error) {
if err := initViper(); err != nil {
slog.Error("error while initializing viper", "error", err)
return nil, err
}

if err := viper.ReadInConfig(); err != nil {
slog.Error("error while reading in the configs: %w", err)
return err
var c Config
if err := viper.Unmarshal(&c); err != nil {
slog.Error("unable to decode into struct", "error", err)
return nil, err
}

return nil
return &c, nil
}
37 changes: 37 additions & 0 deletions internal/config/viper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2023 cluetec GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package config

import (
"github.com/spf13/viper"
"log/slog"
"strings"
)

func initViper() error {
viper.AutomaticEnv()
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.AddConfigPath(".")
viper.SetConfigFile("./config.yaml")

if err := viper.ReadInConfig(); err != nil {
slog.Error("error while reading in the configs: %w", err)
return err
}

return nil
}
36 changes: 36 additions & 0 deletions internal/destination/destination.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2023 cluetec GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package destination

import (
"github.com/cluetec/lifeboat/internal/config"
"github.com/cluetec/lifeboat/internal/destination/filesystem"
"log/slog"
"os"
)

func Prepare(c config.DestinationConfig) {
if c.Type == filesystem.Type {
filesystemConfig, err := filesystem.New(c.ResourceConfig)
if err != nil {
slog.Error("error while initializing filesystem destination config", "error", err)
os.Exit(1)
}

slog.Debug("filesystem destination config loaded", "config", filesystemConfig)
}
}
41 changes: 41 additions & 0 deletions internal/destination/filesystem/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2023 cluetec GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package filesystem

import (
"github.com/mitchellh/mapstructure"
"log/slog"
)

const Type = "filesystem"

type Config struct {
Path string
}

func New(c map[string]any) (*Config, error) {
var filesystemConfig Config

err := mapstructure.Decode(c, &filesystemConfig)

if err != nil {
slog.Error("unable to decode config into filesystem destination config", "error", err)
return nil, err
}

return &filesystemConfig, nil
}
33 changes: 33 additions & 0 deletions internal/logging/slog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2023 cluetec GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package logging

import (
"log/slog"
"os"
)

func InitSlog(logLevel slog.Level) {
lvl := new(slog.LevelVar)
lvl.Set(logLevel)

logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
Level: lvl,
}))

slog.SetDefault(logger)
}
41 changes: 41 additions & 0 deletions internal/source/filesystem/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2023 cluetec GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package filesystem

import (
"github.com/mitchellh/mapstructure"
"log/slog"
)

const Type = "filesystem"

type Config struct {
Path string
}

func New(c map[string]any) (*Config, error) {
var filesystemConfig Config

err := mapstructure.Decode(c, &filesystemConfig)

if err != nil {
slog.Error("unable to decode config into filesystem source config", "error", err)
return nil, err
}

return &filesystemConfig, nil
}
36 changes: 36 additions & 0 deletions internal/source/source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2023 cluetec GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package source

import (
"github.com/cluetec/lifeboat/internal/config"
"github.com/cluetec/lifeboat/internal/source/filesystem"
"log/slog"
"os"
)

func Prepare(c config.SourceConfig) {
if c.Type == filesystem.Type {
filesystemConfig, err := filesystem.New(c.ResourceConfig)
if err != nil {
slog.Error("error while initializing filesystem source config", "error", err)
os.Exit(1)
}

slog.Debug("filesystem source config loaded", "config", filesystemConfig)
}
}

0 comments on commit 7f7180c

Please sign in to comment.