mirror of
https://github.com/KevinMidboe/traefik-etcd-advertiser.git
synced 2025-10-29 01:40:20 +00:00
84 lines
1.9 KiB
Go
84 lines
1.9 KiB
Go
package generator
|
|
|
|
import (
|
|
"fmt"
|
|
"log/slog"
|
|
"math"
|
|
"strconv"
|
|
|
|
"github.com/kevinmidboe/traefik-etcd-advertiser/client/etcd"
|
|
"github.com/kevinmidboe/traefik-etcd-advertiser/converter"
|
|
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
|
)
|
|
|
|
const traefikPrefix = "traefik"
|
|
|
|
func isKnownGenericType(value interface{}) bool {
|
|
switch v := value.(type) {
|
|
case string:
|
|
return true
|
|
case float64:
|
|
return true
|
|
case bool:
|
|
return true
|
|
default:
|
|
slog.Debug(fmt.Sprintf("found unknown generic %s\n", v))
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func convertToGeneric(value interface{}) string {
|
|
switch v := value.(type) {
|
|
case string:
|
|
return v
|
|
case float64:
|
|
return fmt.Sprintf("%d", int(math.Floor(v)))
|
|
case bool:
|
|
return strconv.FormatBool(v)
|
|
}
|
|
|
|
return "unknown type"
|
|
}
|
|
|
|
// recursively walks the JSON object and creates internal
|
|
// `etcdPackets` per leaf node, returns list of packets.
|
|
func createPacket(item interface{}, parentKey string) []etcd.EtcdPacket {
|
|
blocks := []etcd.EtcdPacket{}
|
|
|
|
switch itemD := item.(type) {
|
|
// input is JSON object
|
|
case map[string]interface{}:
|
|
for key, value := range itemD {
|
|
// check for generic value type vs nested object,
|
|
// either create block or recursively call obj again
|
|
|
|
if isKnownGenericType(value) {
|
|
blocks = append(blocks, etcd.EtcdPacket{
|
|
Key: parentKey + "/" + key,
|
|
Value: convertToGeneric(value),
|
|
})
|
|
} else {
|
|
blocks = append(blocks, createPacket(itemD[key], fmt.Sprintf("%s/%s", parentKey, key))...)
|
|
}
|
|
}
|
|
// input is JSON list
|
|
case []interface{}:
|
|
for i, item := range itemD {
|
|
blocks = append(blocks, createPacket(item, parentKey+"/"+strconv.Itoa(i))...)
|
|
}
|
|
}
|
|
|
|
return blocks
|
|
}
|
|
|
|
func TraefikToEtcd(config *dynamic.Configuration, packetList *[]etcd.EtcdPacket) {
|
|
// always convert to json before converting to etcd
|
|
data := converter.TraefikToJSON(config)
|
|
|
|
// generate list of etcd commands
|
|
items := createPacket(data, traefikPrefix)
|
|
*packetList = append(*packetList, items...)
|
|
}
|
|
|