osbuild-composer: support setting distro_aliases via ENV variable

This will allow us to configure the distro aliases in the service by
setting ENV variable.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
This commit is contained in:
Tomáš Hozza 2024-02-02 17:34:40 +01:00 committed by Ondřej Budai
parent 218a784778
commit f57e88d034
2 changed files with 74 additions and 3 deletions

View file

@ -6,6 +6,7 @@ import (
"os"
"reflect"
"strconv"
"strings"
"github.com/BurntSushi/toml"
)
@ -14,7 +15,7 @@ type ComposerConfigFile struct {
Koji KojiAPIConfig `toml:"koji"`
Worker WorkerAPIConfig `toml:"worker"`
WeldrAPI WeldrAPIConfig `toml:"weldr_api"`
DistroAliases map[string]string `toml:"distro_aliases"`
DistroAliases map[string]string `toml:"distro_aliases" env:"DISTRO_ALIASES"`
LogLevel string `toml:"log_level"`
LogFormat string `toml:"log_format"`
DNFJson string `toml:"dnf-json"`
@ -143,6 +144,24 @@ func LoadConfig(name string) (*ComposerConfigFile, error) {
return c, nil
}
// envStrToMap converts map string to map[string]string
func envStrToMap(s string) (map[string]string, error) {
result := map[string]string{}
if s == "" {
return result, nil
}
parts := strings.Split(s, ",")
for _, part := range parts {
keyValue := strings.Split(part, "=")
if len(keyValue) != 2 {
return nil, fmt.Errorf("Invalid key-value pair in map string: %s", part)
}
result[keyValue[0]] = keyValue[1]
}
return result, nil
}
func loadConfigFromEnv(intf interface{}) error {
t := reflect.TypeOf(intf).Elem()
v := reflect.ValueOf(intf).Elem()
@ -184,8 +203,23 @@ func loadConfigFromEnv(intf interface{}) error {
// no-op
continue
case reflect.Map:
// no-op
continue
key, ok := fieldT.Tag.Lookup("env")
if !ok {
continue
}
// handle only map[string]string
if fieldV.Type().Key().Kind() != reflect.String || fieldV.Type().Elem().Kind() != reflect.String {
return fmt.Errorf("Unsupported map type for loading from ENV: %s", kind)
}
confV, ok := os.LookupEnv(key)
if !ok {
continue
}
value, err := envStrToMap(confV)
if err != nil {
return err
}
fieldV.Set(reflect.ValueOf(value))
case reflect.Struct:
err := loadConfigFromEnv(fieldV.Addr().Interface())
if err != nil {

View file

@ -3,6 +3,7 @@ package main
import (
"bytes"
"os"
"strings"
"testing"
"github.com/stretchr/testify/require"
@ -142,3 +143,39 @@ func TestDumpConfig(t *testing.T) {
// DumpConfig takes a copy
require.Equal(t, "sensitive", config.Worker.PGPassword)
}
func TestEnvStrToMap(t *testing.T) {
env := "key1=value1,key2=value2,key3=value3"
expected := map[string]string{
"key1": "value1",
"key2": "value2",
"key3": "value3",
}
got, err := envStrToMap(env)
require.NoError(t, err)
require.Equal(t, expected, got)
}
func TestConfigFromEnv(t *testing.T) {
// simulate the environment variables
currentEnv := os.Environ()
defer func() {
os.Clearenv()
for _, env := range currentEnv {
pair := strings.SplitN(env, "=", 2)
_ = os.Setenv(pair[0], pair[1])
}
}()
os.Setenv("DISTRO_ALIASES", "rhel-7=rhel-7.9,rhel-8=rhel-8.9,rhel-9=rhel-9.3,rhel-10.0=rhel-9.5")
expectedDistroAliases := map[string]string{
"rhel-7": "rhel-7.9",
"rhel-8": "rhel-8.9",
"rhel-9": "rhel-9.3",
"rhel-10.0": "rhel-9.5",
}
config, err := LoadConfig("")
require.NoError(t, err)
require.Equal(t, expectedDistroAliases, config.DistroAliases)
}