mirror of
				https://github.com/KevinMidboe/traefik-etcd-advertiser.git
				synced 2025-10-29 18:00:19 +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...)
 | |
| }
 | |
| 
 |