From 73647b618a62747642512434acb8b3c979633c2a Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Tue, 30 May 2023 23:00:03 +0200 Subject: [PATCH 1/6] start migrating to protobuf --- Makefile | 8 +- go.mod | 2 +- pkg/roles/discovery/api_devices_test.go | 8 +- pkg/roles/dns/api_records_test.go | 6 +- pkg/roles/dns/api_zones.go | 22 ++- pkg/roles/dns/api_zones_test.go | 13 +- pkg/roles/dns/dns_handler.go | 6 +- pkg/roles/dns/handler_coredns.go | 7 +- pkg/roles/dns/handler_coredns_test.go | 11 +- pkg/roles/dns/handler_etcd.go | 5 +- pkg/roles/dns/handler_etcd_test.go | 25 ++- pkg/roles/dns/handler_forward_blocky.go | 9 +- pkg/roles/dns/handler_forward_blocky_test.go | 13 +- pkg/roles/dns/handler_forward_ip.go | 15 +- pkg/roles/dns/handler_forward_ip_test.go | 33 ++-- pkg/roles/dns/handler_memory.go | 5 +- pkg/roles/dns/record.go | 6 +- pkg/roles/dns/role.go | 23 ++- pkg/roles/dns/types/role_dns_zone.pb.go | 179 +++++++++++++++++++ pkg/roles/dns/zone.go | 76 ++++---- pkg/roles/dns/zone_test.go | 11 +- protobuf/role_dns_zone.proto | 12 ++ 22 files changed, 373 insertions(+), 122 deletions(-) create mode 100644 pkg/roles/dns/types/role_dns_zone.pb.go create mode 100644 protobuf/role_dns_zone.proto diff --git a/Makefile b/Makefile index 9c9ba85b5..5d9b24e0a 100644 --- a/Makefile +++ b/Makefile @@ -25,8 +25,6 @@ run: export INSTANCE_LISTEN=0.0.0.0 export DEBUG=true export LISTEN_ONLY=true - export SENTRY_ENVIRONMENT=testing - export SENTRY_ENABLED=true $(eval LD_FLAGS := -X beryju.io/gravity/pkg/extconfig.Version=${VERSION} -X beryju.io/gravity/pkg/extconfig.BuildHash=dev-$(shell git rev-parse HEAD)) go run ${GO_FLAGS} . server @@ -43,6 +41,12 @@ gen-build: DEBUG=true go run ${GO_FLAGS} . generateSchema ${SCHEMA_FILE} git add ${SCHEMA_FILE} +gen-proto: + protoc \ + --proto_path . \ + --go_out . \ + protobuf/** + gen-clean: rm -rf gen-ts-api/ diff --git a/go.mod b/go.mod index f1b6ff1d5..1aedf2d44 100644 --- a/go.mod +++ b/go.mod @@ -47,6 +47,7 @@ require ( golang.org/x/net v0.10.0 golang.org/x/oauth2 v0.8.0 golang.org/x/term v0.8.0 + google.golang.org/protobuf v1.30.0 ) require ( @@ -204,7 +205,6 @@ require ( google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect google.golang.org/grpc v1.52.3 // indirect - google.golang.org/protobuf v1.30.0 // indirect gopkg.in/DataDog/dd-trace-go.v1 v1.47.0 // indirect gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/pkg/roles/discovery/api_devices_test.go b/pkg/roles/discovery/api_devices_test.go index 44434537f..8a2f393f8 100644 --- a/pkg/roles/discovery/api_devices_test.go +++ b/pkg/roles/discovery/api_devices_test.go @@ -141,7 +141,7 @@ func TestDeviceApplyDHCPWithDNS(t *testing.T) { dnsTypes.KeyZones, "gravity.beryju.io.", ).String(), - tests.MustJSON(dns.Zone{}), + tests.MustJSON(dns.ZoneContext{}), ) inst.KV().Put( ctx, @@ -150,7 +150,7 @@ func TestDeviceApplyDHCPWithDNS(t *testing.T) { dnsTypes.KeyZones, "0.192.in-addr.arpa.", ).String(), - tests.MustJSON(dns.Zone{}), + tests.MustJSON(dns.ZoneContext{}), ) // Create DHCP role to register events @@ -257,7 +257,7 @@ func TestDeviceApplyDNSWithReverse(t *testing.T) { dnsTypes.KeyZones, "gravity.beryju.io.", ).String(), - tests.MustJSON(dns.Zone{}), + tests.MustJSON(dns.ZoneContext{}), ) inst.KV().Put( ctx, @@ -266,7 +266,7 @@ func TestDeviceApplyDNSWithReverse(t *testing.T) { dnsTypes.KeyZones, "0.192.in-addr.arpa.", ).String(), - tests.MustJSON(dns.Zone{}), + tests.MustJSON(dns.ZoneContext{}), ) // Create DNS role to register events diff --git a/pkg/roles/dns/api_records_test.go b/pkg/roles/dns/api_records_test.go index f0e835c3b..155f7d2f7 100644 --- a/pkg/roles/dns/api_records_test.go +++ b/pkg/roles/dns/api_records_test.go @@ -24,7 +24,7 @@ func TestAPIRecordsGet(t *testing.T) { types.KeyZones, zone, ).String(), - tests.MustJSON(dns.Zone{}), + tests.MustJSON(dns.ZoneContext{}), ) inst.KV().Put( ctx, @@ -61,7 +61,7 @@ func TestAPIRecordsPut(t *testing.T) { types.KeyZones, name, ).String(), - tests.MustJSON(dns.Zone{}), + tests.MustJSON(dns.ZoneContext{}), ) assert.NoError(t, role.APIRecordsPut().Interact(ctx, dns.APIRecordsPutInput{ Zone: name, @@ -100,7 +100,7 @@ func TestAPIRecordsDelete(t *testing.T) { types.KeyZones, zone, ).String(), - tests.MustJSON(dns.Zone{}), + tests.MustJSON(dns.ZoneContext{}), ) inst.KV().Put( ctx, diff --git a/pkg/roles/dns/api_zones.go b/pkg/roles/dns/api_zones.go index 6825988fd..dff7ddbc9 100644 --- a/pkg/roles/dns/api_zones.go +++ b/pkg/roles/dns/api_zones.go @@ -10,6 +10,7 @@ import ( "github.com/swaggest/usecase/status" clientv3 "go.etcd.io/etcd/client/v3" "go.uber.org/zap" + "google.golang.org/protobuf/types/known/structpb" ) type APIZonesGetInput struct { @@ -54,11 +55,19 @@ func (r *Role) APIZonesGet() usecase.Interactor { if strings.Contains(_zone.Name, "/") { continue } + handlers := []map[string]string{} + for _, h := range _zone.HandlerConfigs { + hc := map[string]string{} + for key, value := range h.Fields { + hc[key] = value.GetStringValue() + } + handlers = append(handlers, hc) + } output.Zones = append(output.Zones, APIZone{ Name: _zone.Name, Authoritative: _zone.Authoritative, DefaultTTL: _zone.DefaultTTL, - HandlerConfigs: _zone.HandlerConfigs, + HandlerConfigs: handlers, }) } return nil @@ -85,7 +94,16 @@ func (r *Role) APIZonesPut() usecase.Interactor { z.Name += "." } z.Authoritative = input.Authoritative - z.HandlerConfigs = input.HandlerConfigs + z.HandlerConfigs = []*structpb.Struct{} + for _, h := range input.HandlerConfigs { + fields := make(map[string]*structpb.Value) + for key, value := range h { + fields[key] = structpb.NewStringValue(value) + } + z.HandlerConfigs = append(z.HandlerConfigs, &structpb.Struct{ + Fields: fields, + }) + } z.DefaultTTL = input.DefaultTTL err := z.put(ctx) if err != nil { diff --git a/pkg/roles/dns/api_zones_test.go b/pkg/roles/dns/api_zones_test.go index ea65b38b2..3415aef03 100644 --- a/pkg/roles/dns/api_zones_test.go +++ b/pkg/roles/dns/api_zones_test.go @@ -9,6 +9,7 @@ import ( "beryju.io/gravity/pkg/roles/dns/types" "beryju.io/gravity/pkg/tests" "github.com/stretchr/testify/assert" + "google.golang.org/protobuf/types/known/structpb" ) func TestAPIZonesGet(t *testing.T) { @@ -24,7 +25,7 @@ func TestAPIZonesGet(t *testing.T) { types.KeyZones, "test.", ).String(), - tests.MustJSON(dns.Zone{}), + tests.MustJSON(dns.ZoneContext{}), ) var output dns.APIZonesGetOutput @@ -57,11 +58,13 @@ func TestAPIZonesPut(t *testing.T) { types.KeyZones, name, ), - dns.Zone{ + types.Zone{ Authoritative: true, - HandlerConfigs: []map[string]string{ + HandlerConfigs: []*structpb.Struct{ { - "type": "etcd", + Fields: map[string]*structpb.Value{ + "type": structpb.NewStringValue("etcd"), + }, }, }, }, @@ -83,7 +86,7 @@ func TestAPIZonesDelete(t *testing.T) { types.KeyZones, name, ).String(), - tests.MustJSON(dns.Zone{}), + tests.MustJSON(dns.ZoneContext{}), ) assert.NoError(t, role.APIZonesDelete().Interact(ctx, dns.APIZonesDeleteInput{ diff --git a/pkg/roles/dns/dns_handler.go b/pkg/roles/dns/dns_handler.go index f7277c682..4b6f58d99 100644 --- a/pkg/roles/dns/dns_handler.go +++ b/pkg/roles/dns/dns_handler.go @@ -12,9 +12,9 @@ import ( ) // Find a zone for the given fqdn -func (r *Role) FindZone(fqdn string) *Zone { +func (r *Role) FindZone(fqdn string) *ZoneContext { lastLongest := 0 - var longestZone *Zone + var longestZone *ZoneContext for name, zone := range r.zones { // Zone doesn't have the correct suffix for the question if !strings.HasSuffix(fqdn, name) { @@ -30,7 +30,7 @@ func (r *Role) FindZone(fqdn string) *Zone { func (ro *Role) Handler(w dns.ResponseWriter, r *dns.Msg) { lastLongest := 0 - var longestZone *Zone + var longestZone *ZoneContext span := sentry.StartTransaction( context.TODO(), diff --git a/pkg/roles/dns/handler_coredns.go b/pkg/roles/dns/handler_coredns.go index e323da43e..399d16328 100644 --- a/pkg/roles/dns/handler_coredns.go +++ b/pkg/roles/dns/handler_coredns.go @@ -12,25 +12,26 @@ import ( "github.com/miekg/dns" _ "github.com/ori-edge/k8s_gateway" "go.uber.org/zap" + "google.golang.org/protobuf/types/known/structpb" ) const CoreDNSType = "coredns" type CoreDNS struct { - c map[string]string + c map[string]*structpb.Value log *zap.Logger instance *caddy.Instance srv *dnsserver.Server } -func NewCoreDNS(z *Zone, rawConfig map[string]string) *CoreDNS { +func NewCoreDNS(z *ZoneContext, rawConfig map[string]*structpb.Value) *CoreDNS { core := &CoreDNS{ c: rawConfig, } core.log = z.log.With(zap.String("handler", core.Identifier())) dnsserver.Quiet = true corefile := caddy.CaddyfileInput{ - Contents: []byte(core.c["config"]), + Contents: []byte(core.c["config"].GetStringValue()), Filepath: "in-memory", ServerTypeName: "dns", } diff --git a/pkg/roles/dns/handler_coredns_test.go b/pkg/roles/dns/handler_coredns_test.go index f1c44a93b..90e7a28b4 100644 --- a/pkg/roles/dns/handler_coredns_test.go +++ b/pkg/roles/dns/handler_coredns_test.go @@ -9,6 +9,7 @@ import ( "beryju.io/gravity/pkg/roles/dns/types" "beryju.io/gravity/pkg/tests" "github.com/stretchr/testify/assert" + "google.golang.org/protobuf/types/known/structpb" ) const CoreDNSConfig = `.:1342 { @@ -29,11 +30,13 @@ func TestRoleDNSHandlerCoreDNS(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(dns.Zone{ - HandlerConfigs: []map[string]string{ + tests.MustJSON(types.Zone{ + HandlerConfigs: []*structpb.Struct{ { - "type": "coredns", - "config": CoreDNSConfig, + Fields: map[string]*structpb.Value{ + "type": structpb.NewStringValue("coredns"), + "config": structpb.NewStringValue(CoreDNSConfig), + }, }, }, }), diff --git a/pkg/roles/dns/handler_etcd.go b/pkg/roles/dns/handler_etcd.go index be179436f..f9cad2faa 100644 --- a/pkg/roles/dns/handler_etcd.go +++ b/pkg/roles/dns/handler_etcd.go @@ -10,16 +10,17 @@ import ( "github.com/miekg/dns" clientv3 "go.etcd.io/etcd/client/v3" "go.uber.org/zap" + "google.golang.org/protobuf/types/known/structpb" ) const EtcdType = "etcd" type EtcdHandler struct { log *zap.Logger - z *Zone + z *ZoneContext } -func NewEtcdHandler(z *Zone, config map[string]string) *EtcdHandler { +func NewEtcdHandler(z *ZoneContext, config map[string]*structpb.Value) *EtcdHandler { eh := &EtcdHandler{ z: z, } diff --git a/pkg/roles/dns/handler_etcd_test.go b/pkg/roles/dns/handler_etcd_test.go index f599db1fd..117253a8f 100644 --- a/pkg/roles/dns/handler_etcd_test.go +++ b/pkg/roles/dns/handler_etcd_test.go @@ -9,6 +9,7 @@ import ( "beryju.io/gravity/pkg/roles/dns/types" "beryju.io/gravity/pkg/tests" "github.com/stretchr/testify/assert" + "google.golang.org/protobuf/types/known/structpb" ) func TestRoleDNS_Etcd(t *testing.T) { @@ -23,10 +24,12 @@ func TestRoleDNS_Etcd(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(dns.Zone{ - HandlerConfigs: []map[string]string{ + tests.MustJSON(types.Zone{ + HandlerConfigs: []*structpb.Struct{ { - "type": "etcd", + Fields: map[string]*structpb.Value{ + "type": structpb.NewStringValue("etcd"), + }, }, }, }), @@ -67,10 +70,12 @@ func TestRoleDNS_Etcd_Wildcard(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(dns.Zone{ - HandlerConfigs: []map[string]string{ + tests.MustJSON(types.Zone{ + HandlerConfigs: []*structpb.Struct{ { - "type": "etcd", + Fields: map[string]*structpb.Value{ + "type": structpb.NewStringValue("etcd"), + }, }, }, }), @@ -111,10 +116,12 @@ func TestRoleDNS_Etcd_WildcardNested(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(dns.Zone{ - HandlerConfigs: []map[string]string{ + tests.MustJSON(types.Zone{ + HandlerConfigs: []*structpb.Struct{ { - "type": "etcd", + Fields: map[string]*structpb.Value{ + "type": structpb.NewStringValue("etcd"), + }, }, }, }), diff --git a/pkg/roles/dns/handler_forward_blocky.go b/pkg/roles/dns/handler_forward_blocky.go index 73e01f904..f4a3f3813 100644 --- a/pkg/roles/dns/handler_forward_blocky.go +++ b/pkg/roles/dns/handler_forward_blocky.go @@ -12,6 +12,7 @@ import ( "github.com/creasty/defaults" "github.com/getsentry/sentry-go" "go.uber.org/zap" + "google.golang.org/protobuf/types/known/structpb" "github.com/0xERR0R/blocky/config" blockylog "github.com/0xERR0R/blocky/log" @@ -23,13 +24,13 @@ const BlockyForwarderType = "forward_blocky" type BlockyForwarder struct { *IPForwarderHandler - c map[string]string + c map[string]*structpb.Value b *server.Server log *zap.Logger st time.Time } -func NewBlockyForwarder(z *Zone, rawConfig map[string]string) *BlockyForwarder { +func NewBlockyForwarder(z *ZoneContext, rawConfig map[string]*structpb.Value) *BlockyForwarder { bfwd := &BlockyForwarder{ IPForwarderHandler: NewIPForwarderHandler(z, rawConfig), c: rawConfig, @@ -56,7 +57,7 @@ func (bfwd *BlockyForwarder) Identifier() string { } func (bfwd *BlockyForwarder) setup() error { - forwarders := strings.Split(bfwd.c["to"], ";") + forwarders := strings.Split(bfwd.c["to"].GetStringValue(), ";") upstreams := make([]config.Upstream, len(forwarders)) for idx, fwd := range forwarders { us, err := config.ParseUpstream(fwd) @@ -76,7 +77,7 @@ func (bfwd *BlockyForwarder) setup() error { "https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt", } if bll, ok := bfwd.c["blocklists"]; ok { - lists := strings.Split(bll, ";") + lists := strings.Split(bll.GetStringValue(), ";") blockLists = lists } diff --git a/pkg/roles/dns/handler_forward_blocky_test.go b/pkg/roles/dns/handler_forward_blocky_test.go index 006d62842..d5069b6ec 100644 --- a/pkg/roles/dns/handler_forward_blocky_test.go +++ b/pkg/roles/dns/handler_forward_blocky_test.go @@ -10,6 +10,7 @@ import ( "beryju.io/gravity/pkg/tests" "github.com/stretchr/testify/assert" clientv3 "go.etcd.io/etcd/client/v3" + "google.golang.org/protobuf/types/known/structpb" ) func TestRoleDNS_BlockyForwarder(t *testing.T) { @@ -31,12 +32,14 @@ func TestRoleDNS_BlockyForwarder(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(dns.Zone{ - HandlerConfigs: []map[string]string{ + tests.MustJSON(types.Zone{ + HandlerConfigs: []*structpb.Struct{ { - "type": "forward_blocky", - "blocklists": "http://127.0.0.1:9005/blocky_file.txt", - "to": "127.0.0.1:1053", + Fields: map[string]*structpb.Value{ + "type": structpb.NewStringValue("forward_blocky"), + "blocklists": structpb.NewStringValue("http://127.0.0.1:9005/blocky_file.txt"), + "to": structpb.NewStringValue("127.0.0.1:1053"), + }, }, }, }), diff --git a/pkg/roles/dns/handler_forward_ip.go b/pkg/roles/dns/handler_forward_ip.go index af89ca91c..dd0aacdb8 100644 --- a/pkg/roles/dns/handler_forward_ip.go +++ b/pkg/roles/dns/handler_forward_ip.go @@ -10,6 +10,7 @@ import ( "github.com/getsentry/sentry-go" "github.com/miekg/dns" "go.uber.org/zap" + "google.golang.org/protobuf/types/known/structpb" ) const IPForwarderType = "forward_ip" @@ -18,30 +19,30 @@ type IPForwarderHandler struct { c *dns.Client resolvers []string - z *Zone + z *ZoneContext log *zap.Logger CacheTTL int } -func NewIPForwarderHandler(z *Zone, config map[string]string) *IPForwarderHandler { +func NewIPForwarderHandler(z *ZoneContext, config map[string]*structpb.Value) *IPForwarderHandler { net, ok := config["net"] if !ok { - net = "" + net = structpb.NewStringValue("") } ipf := &IPForwarderHandler{ z: z, c: &dns.Client{ - Net: net, + Net: net.GetStringValue(), Timeout: types.DefaultUpstreamTimeout, }, - resolvers: strings.Split(config["to"], ";"), + resolvers: strings.Split(config["to"].GetStringValue(), ";"), } ipf.log = z.log.With(zap.String("handler", ipf.Identifier())) rawTtl := config["cache_ttl"] - cacheTtl, err := strconv.Atoi(rawTtl) - if err != nil && rawTtl != "" { + cacheTtl, err := strconv.Atoi(rawTtl.GetStringValue()) + if err != nil && rawTtl.GetStringValue() != "" { ipf.log.Warn("failed to parse cache_ttl, defaulting to 0", zap.Error(err), zap.Any("config", config)) cacheTtl = 0 } diff --git a/pkg/roles/dns/handler_forward_ip_test.go b/pkg/roles/dns/handler_forward_ip_test.go index a2607c401..eaee2ec80 100644 --- a/pkg/roles/dns/handler_forward_ip_test.go +++ b/pkg/roles/dns/handler_forward_ip_test.go @@ -11,6 +11,7 @@ import ( "beryju.io/gravity/pkg/tests" "github.com/stretchr/testify/assert" clientv3 "go.etcd.io/etcd/client/v3" + "google.golang.org/protobuf/types/known/structpb" ) func TestRoleDNS_IPForwarder_v4(t *testing.T) { @@ -24,11 +25,13 @@ func TestRoleDNS_IPForwarder_v4(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(dns.Zone{ - HandlerConfigs: []map[string]string{ + tests.MustJSON(types.Zone{ + HandlerConfigs: []*structpb.Struct{ { - "type": "forward_ip", - "to": "127.0.0.1:1053", + Fields: map[string]*structpb.Value{ + "type": structpb.NewStringValue("forward_ip"), + "to": structpb.NewStringValue("127.0.0.1:1053"), + }, }, }, }), @@ -62,12 +65,14 @@ func TestRoleDNS_IPForwarder_v4_Cache(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(dns.Zone{ - HandlerConfigs: []map[string]string{ + tests.MustJSON(types.Zone{ + HandlerConfigs: []*structpb.Struct{ { - "type": "forward_ip", - "to": "127.0.0.1:1053", - "cache_ttl": "-2", + Fields: map[string]*structpb.Value{ + "type": structpb.NewStringValue("forward_ip"), + "to": structpb.NewStringValue("127.0.0.1:1053"), + "cache_ttl": structpb.NewStringValue("-2"), + }, }, }, }), @@ -107,11 +112,13 @@ func TestRoleDNS_IPForwarder_v6(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(dns.Zone{ - HandlerConfigs: []map[string]string{ + tests.MustJSON(types.Zone{ + HandlerConfigs: []*structpb.Struct{ { - "type": "forward_ip", - "to": "127.0.0.1:1053", + Fields: map[string]*structpb.Value{ + "type": structpb.NewStringValue("forward_ip"), + "to": structpb.NewStringValue("127.0.0.1:1053"), + }, }, }, }), diff --git a/pkg/roles/dns/handler_memory.go b/pkg/roles/dns/handler_memory.go index 21c1f876c..19b89e14f 100644 --- a/pkg/roles/dns/handler_memory.go +++ b/pkg/roles/dns/handler_memory.go @@ -7,16 +7,17 @@ import ( "github.com/getsentry/sentry-go" "github.com/miekg/dns" "go.uber.org/zap" + "google.golang.org/protobuf/types/known/structpb" ) const MemoryType = "memory" type MemoryHandler struct { log *zap.Logger - z *Zone + z *ZoneContext } -func NewMemoryHandler(z *Zone, config map[string]string) *MemoryHandler { +func NewMemoryHandler(z *ZoneContext, config map[string]*structpb.Value) *MemoryHandler { eh := &MemoryHandler{ z: z, } diff --git a/pkg/roles/dns/record.go b/pkg/roles/dns/record.go index d7661da32..da86acf68 100644 --- a/pkg/roles/dns/record.go +++ b/pkg/roles/dns/record.go @@ -17,7 +17,7 @@ const TXTSeparator = "\n" type Record struct { inst roles.Instance - zone *Zone + zone *ZoneContext Name string `json:"-"` Type string `json:"-"` @@ -32,7 +32,7 @@ type Record struct { SRVWeight uint16 `json:"srvWeight,omitempty"` } -func (z *Zone) recordFromKV(kv *mvccpb.KeyValue) (*Record, error) { +func (z *ZoneContext) recordFromKV(kv *mvccpb.KeyValue) (*Record, error) { fullRecordKey := string(kv.Key) // Relative key compared to zone, format of // host/A[/...] @@ -55,7 +55,7 @@ func (z *Zone) recordFromKV(kv *mvccpb.KeyValue) (*Record, error) { return rec, nil } -func (z *Zone) newRecord(name string, t string) *Record { +func (z *ZoneContext) newRecord(name string, t string) *Record { return &Record{ Name: strings.ToLower(name), Type: t, diff --git a/pkg/roles/dns/role.go b/pkg/roles/dns/role.go index 86fbd08e8..091e020c4 100644 --- a/pkg/roles/dns/role.go +++ b/pkg/roles/dns/role.go @@ -16,12 +16,13 @@ import ( "github.com/miekg/dns" "github.com/swaggest/rest/web" "go.uber.org/zap" + "google.golang.org/protobuf/types/known/structpb" ) type Role struct { i roles.Instance ctx context.Context - zones map[string]*Zone + zones map[string]*ZoneContext cfg *RoleConfig log *zap.Logger @@ -32,7 +33,7 @@ type Role struct { func New(instance roles.Instance) *Role { r := &Role{ servers: make([]*dns.Server, 0), - zones: make(map[string]*Zone, 0), + zones: make(map[string]*ZoneContext, 0), zonesM: sync.RWMutex{}, log: instance.Log(), i: instance, @@ -44,17 +45,23 @@ func New(instance roles.Instance) *Role { r.i.AddEventListener(instanceTypes.EventTopicInstanceFirstStart, func(ev *roles.Event) { // On first start create a zone that'll forward to a reasonable default zone := r.newZone(".") - zone.HandlerConfigs = []map[string]string{ + zone.HandlerConfigs = []*structpb.Struct{ { - "type": "memory", + Fields: map[string]*structpb.Value{ + "type": structpb.NewStringValue("memory"), + }, }, { - "type": "etcd", + Fields: map[string]*structpb.Value{ + "type": structpb.NewStringValue("etcd"), + }, }, { - "type": "forward_ip", - "to": extconfig.Get().FallbackDNS, - "cache_ttl": "3600", + Fields: map[string]*structpb.Value{ + "type": structpb.NewStringValue("forward_ip"), + "to": structpb.NewStringValue(extconfig.Get().FallbackDNS), + "cache_ttl": structpb.NewStringValue("3600"), + }, }, } zone.put(ev.Context) diff --git a/pkg/roles/dns/types/role_dns_zone.pb.go b/pkg/roles/dns/types/role_dns_zone.pb.go new file mode 100644 index 000000000..de3e3abb2 --- /dev/null +++ b/pkg/roles/dns/types/role_dns_zone.pb.go @@ -0,0 +1,179 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.21.12 +// source: protobuf/role_dns_zone.proto + +package types + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + structpb "google.golang.org/protobuf/types/known/structpb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Zone struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + HandlerConfigs []*structpb.Struct `protobuf:"bytes,2,rep,name=handlerConfigs,proto3" json:"handlerConfigs,omitempty"` + DefaultTTL uint32 `protobuf:"varint,3,opt,name=defaultTTL,proto3" json:"defaultTTL,omitempty"` + Authoritative bool `protobuf:"varint,4,opt,name=authoritative,proto3" json:"authoritative,omitempty"` +} + +func (x *Zone) Reset() { + *x = Zone{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_role_dns_zone_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Zone) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Zone) ProtoMessage() {} + +func (x *Zone) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_role_dns_zone_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Zone.ProtoReflect.Descriptor instead. +func (*Zone) Descriptor() ([]byte, []int) { + return file_protobuf_role_dns_zone_proto_rawDescGZIP(), []int{0} +} + +func (x *Zone) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Zone) GetHandlerConfigs() []*structpb.Struct { + if x != nil { + return x.HandlerConfigs + } + return nil +} + +func (x *Zone) GetDefaultTTL() uint32 { + if x != nil { + return x.DefaultTTL + } + return 0 +} + +func (x *Zone) GetAuthoritative() bool { + if x != nil { + return x.Authoritative + } + return false +} + +var File_protobuf_role_dns_zone_proto protoreflect.FileDescriptor + +var file_protobuf_role_dns_zone_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, + 0x64, 0x6e, 0x73, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa1, 0x01, 0x0a, + 0x04, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x0e, 0x68, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0e, 0x68, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x54, 0x4c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x54, 0x4c, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x42, 0x15, 0x5a, 0x13, 0x70, 0x6b, 0x67, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x64, 0x6e, + 0x73, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_protobuf_role_dns_zone_proto_rawDescOnce sync.Once + file_protobuf_role_dns_zone_proto_rawDescData = file_protobuf_role_dns_zone_proto_rawDesc +) + +func file_protobuf_role_dns_zone_proto_rawDescGZIP() []byte { + file_protobuf_role_dns_zone_proto_rawDescOnce.Do(func() { + file_protobuf_role_dns_zone_proto_rawDescData = protoimpl.X.CompressGZIP(file_protobuf_role_dns_zone_proto_rawDescData) + }) + return file_protobuf_role_dns_zone_proto_rawDescData +} + +var file_protobuf_role_dns_zone_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_protobuf_role_dns_zone_proto_goTypes = []interface{}{ + (*Zone)(nil), // 0: Zone + (*structpb.Struct)(nil), // 1: google.protobuf.Struct +} +var file_protobuf_role_dns_zone_proto_depIdxs = []int32{ + 1, // 0: Zone.handlerConfigs:type_name -> google.protobuf.Struct + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_protobuf_role_dns_zone_proto_init() } +func file_protobuf_role_dns_zone_proto_init() { + if File_protobuf_role_dns_zone_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_protobuf_role_dns_zone_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Zone); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_protobuf_role_dns_zone_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_protobuf_role_dns_zone_proto_goTypes, + DependencyIndexes: file_protobuf_role_dns_zone_proto_depIdxs, + MessageInfos: file_protobuf_role_dns_zone_proto_msgTypes, + }.Build() + File_protobuf_role_dns_zone_proto = out.File + file_protobuf_role_dns_zone_proto_rawDesc = nil + file_protobuf_role_dns_zone_proto_goTypes = nil + file_protobuf_role_dns_zone_proto_depIdxs = nil +} diff --git a/pkg/roles/dns/zone.go b/pkg/roles/dns/zone.go index 48ff8a5e5..00131bdd0 100644 --- a/pkg/roles/dns/zone.go +++ b/pkg/roles/dns/zone.go @@ -17,33 +17,25 @@ import ( "go.etcd.io/etcd/api/v3/mvccpb" clientv3 "go.etcd.io/etcd/client/v3" "go.uber.org/zap" + "google.golang.org/protobuf/proto" ) const ( DefaultTTL = 3600 ) -type Zone struct { - inst roles.Instance - +type ZoneContext struct { + *types.Zone + inst roles.Instance records map[string]map[string]*Record recordsWatchCtx context.CancelFunc - - log *zap.Logger - Name string `json:"-"` - - etcdKey string - HandlerConfigs []map[string]string `json:"handlerConfigs"` - - h []Handler - - recordsSync sync.RWMutex - DefaultTTL uint32 `json:"defaultTTL"` - - Authoritative bool `json:"authoritative"` + log *zap.Logger + etcdKey string + h []Handler + recordsSync sync.RWMutex } -func (z *Zone) soa() *dns.Msg { +func (z *ZoneContext) soa() *dns.Msg { m := new(dns.Msg) m.Authoritative = z.Authoritative m.Ns = []dns.RR{ @@ -66,7 +58,7 @@ func (z *Zone) soa() *dns.Msg { return m } -func (z *Zone) resolveUpdateMetrics(dur time.Duration, q *utils.DNSRequest, h Handler, rep *dns.Msg) { +func (z *ZoneContext) resolveUpdateMetrics(dur time.Duration, q *utils.DNSRequest, h Handler, rep *dns.Msg) { for _, question := range q.Question { dnsQueries.WithLabelValues( dns.TypeToString[question.Qtype], @@ -93,7 +85,7 @@ func (z *Zone) resolveUpdateMetrics(dur time.Duration, q *utils.DNSRequest, h Ha } } -func (z *Zone) resolve(w dns.ResponseWriter, r *utils.DNSRequest, span *sentry.Span) { +func (z *ZoneContext) resolve(w dns.ResponseWriter, r *utils.DNSRequest, span *sentry.Span) { for _, handler := range z.h { ss := span.StartChild("gravity.dns.request.handler") ss.Description = handler.Identifier() @@ -127,10 +119,12 @@ func (z *Zone) resolve(w dns.ResponseWriter, r *utils.DNSRequest, span *sentry.S w.WriteMsg(fallback) } -func (r *Role) newZone(name string) *Zone { - return &Zone{ - Name: strings.ToLower(name), - DefaultTTL: DefaultTTL, +func (r *Role) newZone(name string) *ZoneContext { + return &ZoneContext{ + Zone: &types.Zone{ + Name: strings.ToLower(name), + DefaultTTL: DefaultTTL, + }, inst: r.i, h: make([]Handler, 0), records: make(map[string]map[string]*Record), @@ -138,34 +132,41 @@ func (r *Role) newZone(name string) *Zone { } } -func (r *Role) zoneFromKV(raw *mvccpb.KeyValue) (*Zone, error) { +func (r *Role) zoneFromKV(raw *mvccpb.KeyValue) (*ZoneContext, error) { prefix := r.i.KV().Key(types.KeyRole, types.KeyZones).Prefix(true).String() name := strings.TrimPrefix(string(raw.Key), prefix) z := r.newZone(name) + z.log = r.log.With(zap.String("zone", name)) z.etcdKey = string(raw.Key) - err := json.Unmarshal(raw.Value, &z) + + // Try loading protobuf first + err := proto.Unmarshal(raw.Value, z.Zone) + if err == nil { + return z, nil + } + // Otherwise try json + err = json.Unmarshal(raw.Value, &z) if err != nil { return nil, err } - z.log = r.log.With(zap.String("zone", z.Name)) return z, nil } -func (z *Zone) Init(ctx context.Context) { +func (z *ZoneContext) Init(ctx context.Context) { for _, handlerCfg := range z.HandlerConfigs { - t := handlerCfg["type"] + t := handlerCfg.Fields["type"].GetStringValue() var handler Handler switch t { case CoreDNSType: - handler = NewCoreDNS(z, handlerCfg) + handler = NewCoreDNS(z, handlerCfg.Fields) case BlockyForwarderType: - handler = NewBlockyForwarder(z, handlerCfg) + handler = NewBlockyForwarder(z, handlerCfg.Fields) case IPForwarderType: - handler = NewIPForwarderHandler(z, handlerCfg) + handler = NewIPForwarderHandler(z, handlerCfg.Fields) case EtcdType: - handler = NewEtcdHandler(z, handlerCfg) + handler = NewEtcdHandler(z, handlerCfg.Fields) case MemoryType: - handler = NewMemoryHandler(z, handlerCfg) + handler = NewMemoryHandler(z, handlerCfg.Fields) default: z.log.Warn("invalid forwarder type", zap.String("type", t)) } @@ -176,7 +177,7 @@ func (z *Zone) Init(ctx context.Context) { go z.watchZoneRecords(ctx) } -func (z *Zone) watchZoneRecords(ctx context.Context) { +func (z *ZoneContext) watchZoneRecords(ctx context.Context) { evtHandler := func(ev *clientv3.Event) { z.recordsSync.Lock() defer z.recordsSync.Unlock() @@ -231,18 +232,17 @@ func (z *Zone) watchZoneRecords(ctx context.Context) { } } -func (z *Zone) StopWatchingRecords() { +func (z *ZoneContext) StopWatchingRecords() { if z.recordsWatchCtx != nil { z.recordsWatchCtx() } } -func (z *Zone) put(ctx context.Context) error { - raw, err := json.Marshal(&z) +func (z *ZoneContext) put(ctx context.Context) error { + raw, err := proto.Marshal(z.Zone) if err != nil { return err } - _, err = z.inst.KV().Put( ctx, z.inst.KV().Key( diff --git a/pkg/roles/dns/zone_test.go b/pkg/roles/dns/zone_test.go index 33e926d96..b38b7874c 100644 --- a/pkg/roles/dns/zone_test.go +++ b/pkg/roles/dns/zone_test.go @@ -8,6 +8,7 @@ import ( "beryju.io/gravity/pkg/roles/dns/types" "beryju.io/gravity/pkg/tests" "github.com/stretchr/testify/assert" + "google.golang.org/protobuf/types/known/structpb" ) func TestRoleDNSZoneFind(t *testing.T) { @@ -21,11 +22,13 @@ func TestRoleDNSZoneFind(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(dns.Zone{ - HandlerConfigs: []map[string]string{ + tests.MustJSON(types.Zone{ + HandlerConfigs: []*structpb.Struct{ { - "type": "forward_ip", - "to": "127.0.0.1:1053", + Fields: map[string]*structpb.Value{ + "type": structpb.NewStringValue("forward_ip"), + "to": structpb.NewStringValue("127.0.0.1:1053"), + }, }, }, }), diff --git a/protobuf/role_dns_zone.proto b/protobuf/role_dns_zone.proto new file mode 100644 index 000000000..3004294a4 --- /dev/null +++ b/protobuf/role_dns_zone.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +option go_package = "pkg/roles/dns/types"; + +import "google/protobuf/struct.proto"; + +message Zone { + string name = 1; + repeated google.protobuf.Struct handlerConfigs = 2; + uint32 defaultTTL = 3; + bool authoritative = 4; +} From 334c6afa4100d442c5c7d5c40fb70f316020ea7d Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Tue, 30 May 2023 23:06:32 +0200 Subject: [PATCH 2/6] migrate DNS record --- pkg/roles/dns/api_records.go | 16 +- pkg/roles/dns/api_records_test.go | 6 +- pkg/roles/dns/event_handler.go | 4 +- pkg/roles/dns/handler_etcd_test.go | 6 +- pkg/roles/dns/handler_forward_ip.go | 8 +- pkg/roles/dns/handler_forward_ip_test.go | 2 +- pkg/roles/dns/record.go | 39 ++-- pkg/roles/dns/types/role_dns_record.pb.go | 210 ++++++++++++++++++++++ protobuf/role_dns_record.proto | 15 ++ 9 files changed, 267 insertions(+), 39 deletions(-) create mode 100644 pkg/roles/dns/types/role_dns_record.pb.go create mode 100644 protobuf/role_dns_record.proto diff --git a/pkg/roles/dns/api_records.go b/pkg/roles/dns/api_records.go index f10759ee2..b176b7103 100644 --- a/pkg/roles/dns/api_records.go +++ b/pkg/roles/dns/api_records.go @@ -73,10 +73,10 @@ func (r *Role) APIRecordsGet() usecase.Interactor { FQDN: rec.Name + "." + zone.Name, Type: rec.Type, Data: rec.Data, - MXPreference: rec.MXPreference, - SRVPort: rec.SRVPort, - SRVPriority: rec.SRVPriority, - SRVWeight: rec.SRVWeight, + MXPreference: uint16(rec.MxPreference), + SRVPort: uint16(rec.SrvPort), + SRVPriority: uint16(rec.SrvPriority), + SRVWeight: uint16(rec.SrvWeight), }) } return nil @@ -122,10 +122,10 @@ func (r *Role) APIRecordsPut() usecase.Interactor { input.Data = utils.EnsureTrailingPeriod(input.Data) } rec.Data = input.Data - rec.MXPreference = input.MXPreference - rec.SRVPort = input.SRVPort - rec.SRVPriority = input.SRVPriority - rec.SRVWeight = input.SRVWeight + rec.MxPreference = uint32(input.MXPreference) + rec.SrvPort = uint32(input.SRVPort) + rec.SrvPriority = uint32(input.SRVPriority) + rec.SrvWeight = uint32(input.SRVWeight) err = rec.put(ctx, -1) if err != nil { return status.Wrap(err, status.Internal) diff --git a/pkg/roles/dns/api_records_test.go b/pkg/roles/dns/api_records_test.go index 155f7d2f7..4448b4127 100644 --- a/pkg/roles/dns/api_records_test.go +++ b/pkg/roles/dns/api_records_test.go @@ -35,7 +35,7 @@ func TestAPIRecordsGet(t *testing.T) { "test", "A", ).String(), - tests.MustJSON(dns.Record{ + tests.MustJSON(types.Record{ Data: "192.0.2.1", }), ) @@ -80,7 +80,7 @@ func TestAPIRecordsPut(t *testing.T) { "test", "A", ), - dns.Record{ + types.Record{ Data: "192.0.2.1", }, ) @@ -111,7 +111,7 @@ func TestAPIRecordsDelete(t *testing.T) { "test", "A", ).String(), - tests.MustJSON(dns.Record{ + tests.MustJSON(types.Record{ Data: "192.0.2.1", }), ) diff --git a/pkg/roles/dns/event_handler.go b/pkg/roles/dns/event_handler.go index 5a7a7c182..803271e01 100644 --- a/pkg/roles/dns/event_handler.go +++ b/pkg/roles/dns/event_handler.go @@ -43,7 +43,7 @@ func (r *Role) eventCreateForward(ev *roles.Event) { rec = forwardZone.newRecord(hostname, types.DNSRecordTypeA) } rec.Data = ip.String() - rec.TTL = forwardZone.DefaultTTL + rec.Ttl = forwardZone.DefaultTTL err = rec.put(ev.Context, 0, ev.Payload.RelatedObjectOptions...) if err != nil { r.log.Warn("failed to save dns record", zap.Error(err)) @@ -74,7 +74,7 @@ func (r *Role) eventCreateReverse(ev *roles.Event) { relName := strings.TrimSuffix(rev, utils.EnsureLeadingPeriod(forwardZone.Name)) rec := forwardZone.newRecord(relName, types.DNSRecordTypePTR) rec.Data = fqdn - rec.TTL = forwardZone.DefaultTTL + rec.Ttl = forwardZone.DefaultTTL err = rec.put(ev.Context, 0, ev.Payload.RelatedObjectOptions...) if err != nil { r.log.Warn("failed to save dns record", zap.Error(err)) diff --git a/pkg/roles/dns/handler_etcd_test.go b/pkg/roles/dns/handler_etcd_test.go index 117253a8f..9f7ea225d 100644 --- a/pkg/roles/dns/handler_etcd_test.go +++ b/pkg/roles/dns/handler_etcd_test.go @@ -44,7 +44,7 @@ func TestRoleDNS_Etcd(t *testing.T) { types.DNSRecordTypeA, "0", ).String(), - tests.MustJSON(dns.Record{ + tests.MustJSON(types.Record{ Data: "10.1.2.3", }), ) @@ -90,7 +90,7 @@ func TestRoleDNS_Etcd_Wildcard(t *testing.T) { types.DNSRecordTypeA, "0", ).String(), - tests.MustJSON(dns.Record{ + tests.MustJSON(types.Record{ Data: "10.1.2.3", }), ) @@ -136,7 +136,7 @@ func TestRoleDNS_Etcd_WildcardNested(t *testing.T) { types.DNSRecordTypeA, "0", ).String(), - tests.MustJSON(dns.Record{ + tests.MustJSON(types.Record{ Data: "10.1.2.3", }), ) diff --git a/pkg/roles/dns/handler_forward_ip.go b/pkg/roles/dns/handler_forward_ip.go index dd0aacdb8..8cc00f2c9 100644 --- a/pkg/roles/dns/handler_forward_ip.go +++ b/pkg/roles/dns/handler_forward_ip.go @@ -98,12 +98,12 @@ func (ipf *IPForwarderHandler) cacheToEtcd(r *utils.DNSRequest, query dns.Questi record.Data = v.Target case *dns.MX: record.Data = v.Mx - record.MXPreference = v.Preference + record.MxPreference = uint32(v.Preference) case *dns.SRV: record.Data = v.Target - record.SRVPort = v.Port - record.SRVPriority = v.Priority - record.SRVWeight = v.Weight + record.SrvPort = uint32(v.Port) + record.SrvPriority = uint32(v.Priority) + record.SrvWeight = uint32(v.Weight) } record.uid = strconv.Itoa(idx) err := record.put(r.Context(), int64(cacheTtl)) diff --git a/pkg/roles/dns/handler_forward_ip_test.go b/pkg/roles/dns/handler_forward_ip_test.go index eaee2ec80..8647ab5fb 100644 --- a/pkg/roles/dns/handler_forward_ip_test.go +++ b/pkg/roles/dns/handler_forward_ip_test.go @@ -95,7 +95,7 @@ func TestRoleDNS_IPForwarder_v4_Cache(t *testing.T) { types.DNSRecordTypeA, "0", ), - dns.Record{ + types.Record{ Data: "10.0.0.1", }, ) diff --git a/pkg/roles/dns/record.go b/pkg/roles/dns/record.go index da86acf68..d1a079f38 100644 --- a/pkg/roles/dns/record.go +++ b/pkg/roles/dns/record.go @@ -11,25 +11,19 @@ import ( "github.com/miekg/dns" "go.etcd.io/etcd/api/v3/mvccpb" clientv3 "go.etcd.io/etcd/client/v3" + "google.golang.org/protobuf/proto" ) const TXTSeparator = "\n" type Record struct { + *types.Record + inst roles.Instance zone *ZoneContext - Name string `json:"-"` - Type string `json:"-"` - Data string `json:"data"` uid string recordKey string - TTL uint32 `json:"ttl,omitempty"` - - MXPreference uint16 `json:"mxPreference,omitempty"` - SRVPort uint16 `json:"srvPort,omitempty"` - SRVPriority uint16 `json:"srvPriority,omitempty"` - SRVWeight uint16 `json:"srvWeight,omitempty"` } func (z *ZoneContext) recordFromKV(kv *mvccpb.KeyValue) (*Record, error) { @@ -48,7 +42,14 @@ func (z *ZoneContext) recordFromKV(kv *mvccpb.KeyValue) (*Record, error) { rec.uid = parts[2] } rec.recordKey = strings.TrimSuffix(fullRecordKey, "/"+rec.uid) - err := json.Unmarshal(kv.Value, &rec) + + // Try loading protobuf first + err := proto.Unmarshal(kv.Value, rec.Record) + if err == nil { + return rec, nil + } + // Otherwise try json + err = json.Unmarshal(kv.Value, &rec) if err != nil { return rec, err } @@ -57,8 +58,10 @@ func (z *ZoneContext) recordFromKV(kv *mvccpb.KeyValue) (*Record, error) { func (z *ZoneContext) newRecord(name string, t string) *Record { return &Record{ - Name: strings.ToLower(name), - Type: t, + Record: &types.Record{ + Name: strings.ToLower(name), + Type: t, + }, inst: z.inst, zone: z, } @@ -69,7 +72,7 @@ func (r *Record) ToDNS(qname string, t uint16) dns.RR { Name: qname, Rrtype: t, Class: dns.ClassINET, - Ttl: r.TTL, + Ttl: r.Ttl, } var rr dns.RR switch t { @@ -89,14 +92,14 @@ func (r *Record) ToDNS(qname string, t uint16) dns.RR { rr = &dns.SRV{} rr.(*dns.SRV).Hdr = hdr rr.(*dns.SRV).Target = r.Data - rr.(*dns.SRV).Port = r.SRVPort - rr.(*dns.SRV).Priority = r.SRVPriority - rr.(*dns.SRV).Weight = r.SRVWeight + rr.(*dns.SRV).Port = uint16(r.SrvPort) + rr.(*dns.SRV).Priority = uint16(r.SrvPriority) + rr.(*dns.SRV).Weight = uint16(r.SrvWeight) case dns.TypeMX: rr = &dns.MX{} rr.(*dns.MX).Hdr = hdr rr.(*dns.MX).Mx = r.Data - rr.(*dns.MX).Preference = r.MXPreference + rr.(*dns.MX).Preference = uint16(r.MxPreference) case dns.TypeCNAME: rr = &dns.CNAME{} rr.(*dns.CNAME).Hdr = hdr @@ -109,7 +112,7 @@ func (r *Record) ToDNS(qname string, t uint16) dns.RR { } func (r *Record) put(ctx context.Context, expiry int64, opts ...clientv3.OpOption) error { - raw, err := json.Marshal(&r) + raw, err := proto.Marshal(r.Record) if err != nil { return err } diff --git a/pkg/roles/dns/types/role_dns_record.pb.go b/pkg/roles/dns/types/role_dns_record.pb.go new file mode 100644 index 000000000..9be8f03ba --- /dev/null +++ b/pkg/roles/dns/types/role_dns_record.pb.go @@ -0,0 +1,210 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.21.12 +// source: protobuf/role_dns_record.proto + +package types + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Record struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Ttl uint32 `protobuf:"varint,3,opt,name=ttl,proto3" json:"ttl,omitempty"` + Data string `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` + MxPreference uint32 `protobuf:"varint,10,opt,name=mxPreference,proto3" json:"mxPreference,omitempty"` + SrvPort uint32 `protobuf:"varint,11,opt,name=srvPort,proto3" json:"srvPort,omitempty"` + SrvPriority uint32 `protobuf:"varint,12,opt,name=srvPriority,proto3" json:"srvPriority,omitempty"` + SrvWeight uint32 `protobuf:"varint,13,opt,name=srvWeight,proto3" json:"srvWeight,omitempty"` +} + +func (x *Record) Reset() { + *x = Record{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_role_dns_record_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Record) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Record) ProtoMessage() {} + +func (x *Record) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_role_dns_record_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Record.ProtoReflect.Descriptor instead. +func (*Record) Descriptor() ([]byte, []int) { + return file_protobuf_role_dns_record_proto_rawDescGZIP(), []int{0} +} + +func (x *Record) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Record) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Record) GetTtl() uint32 { + if x != nil { + return x.Ttl + } + return 0 +} + +func (x *Record) GetData() string { + if x != nil { + return x.Data + } + return "" +} + +func (x *Record) GetMxPreference() uint32 { + if x != nil { + return x.MxPreference + } + return 0 +} + +func (x *Record) GetSrvPort() uint32 { + if x != nil { + return x.SrvPort + } + return 0 +} + +func (x *Record) GetSrvPriority() uint32 { + if x != nil { + return x.SrvPriority + } + return 0 +} + +func (x *Record) GetSrvWeight() uint32 { + if x != nil { + return x.SrvWeight + } + return 0 +} + +var File_protobuf_role_dns_record_proto protoreflect.FileDescriptor + +var file_protobuf_role_dns_record_proto_rawDesc = []byte{ + 0x0a, 0x1e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, + 0x64, 0x6e, 0x73, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0xd4, 0x01, 0x0a, 0x06, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x03, 0x74, 0x74, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x78, 0x50, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0c, 0x6d, 0x78, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x73, 0x72, 0x76, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, + 0x73, 0x72, 0x76, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x72, 0x76, 0x50, 0x72, + 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x72, + 0x76, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x72, 0x76, + 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x73, 0x72, + 0x76, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x42, 0x15, 0x5a, 0x13, 0x70, 0x6b, 0x67, 0x2f, 0x72, + 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x64, 0x6e, 0x73, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_protobuf_role_dns_record_proto_rawDescOnce sync.Once + file_protobuf_role_dns_record_proto_rawDescData = file_protobuf_role_dns_record_proto_rawDesc +) + +func file_protobuf_role_dns_record_proto_rawDescGZIP() []byte { + file_protobuf_role_dns_record_proto_rawDescOnce.Do(func() { + file_protobuf_role_dns_record_proto_rawDescData = protoimpl.X.CompressGZIP(file_protobuf_role_dns_record_proto_rawDescData) + }) + return file_protobuf_role_dns_record_proto_rawDescData +} + +var file_protobuf_role_dns_record_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_protobuf_role_dns_record_proto_goTypes = []interface{}{ + (*Record)(nil), // 0: Record +} +var file_protobuf_role_dns_record_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_protobuf_role_dns_record_proto_init() } +func file_protobuf_role_dns_record_proto_init() { + if File_protobuf_role_dns_record_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_protobuf_role_dns_record_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Record); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_protobuf_role_dns_record_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_protobuf_role_dns_record_proto_goTypes, + DependencyIndexes: file_protobuf_role_dns_record_proto_depIdxs, + MessageInfos: file_protobuf_role_dns_record_proto_msgTypes, + }.Build() + File_protobuf_role_dns_record_proto = out.File + file_protobuf_role_dns_record_proto_rawDesc = nil + file_protobuf_role_dns_record_proto_goTypes = nil + file_protobuf_role_dns_record_proto_depIdxs = nil +} diff --git a/protobuf/role_dns_record.proto b/protobuf/role_dns_record.proto new file mode 100644 index 000000000..7607ea233 --- /dev/null +++ b/protobuf/role_dns_record.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +option go_package = "pkg/roles/dns/types"; + +message Record { + string name = 1; + string type = 2; + uint32 ttl = 3; + string data = 4; + + uint32 mxPreference = 10; + uint32 srvPort = 11; + uint32 srvPriority = 12; + uint32 srvWeight = 13; +} From b2369bd2aeb051d05967df3548d48916659f8488 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Tue, 30 May 2023 23:13:11 +0200 Subject: [PATCH 3/6] fix --- .github/workflows/test.yml | 1 + pkg/roles/discovery/api_devices_test.go | 8 ++++---- pkg/roles/dns/event_handler.go | 2 +- pkg/roles/dns/record.go | 12 ++++++------ pkg/roles/dns/zone.go | 6 +++--- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a50dfff0f..399a4c3b7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -62,3 +62,4 @@ jobs: uses: golangci/golangci-lint-action@v3 with: args: --timeout 5000s + skip-cache: true diff --git a/pkg/roles/discovery/api_devices_test.go b/pkg/roles/discovery/api_devices_test.go index 8a2f393f8..7abb95d8d 100644 --- a/pkg/roles/discovery/api_devices_test.go +++ b/pkg/roles/discovery/api_devices_test.go @@ -210,7 +210,7 @@ func TestDeviceApplyDHCPWithDNS(t *testing.T) { "test", "A", ), - dns.Record{ + dnsTypes.Record{ Data: "192.0.2.1", }, ) @@ -224,7 +224,7 @@ func TestDeviceApplyDHCPWithDNS(t *testing.T) { "1.2", "PTR", ), - dns.Record{ + dnsTypes.Record{ Data: "test.gravity.beryju.io.", }, ) @@ -291,7 +291,7 @@ func TestDeviceApplyDNSWithReverse(t *testing.T) { "test", "A", ), - dns.Record{ + dnsTypes.Record{ Data: "192.0.2.1", }, ) @@ -305,7 +305,7 @@ func TestDeviceApplyDNSWithReverse(t *testing.T) { "1.2", "PTR", ), - dns.Record{ + dnsTypes.Record{ Data: "test.gravity.beryju.io.", }, ) diff --git a/pkg/roles/dns/event_handler.go b/pkg/roles/dns/event_handler.go index 803271e01..1ba0beccc 100644 --- a/pkg/roles/dns/event_handler.go +++ b/pkg/roles/dns/event_handler.go @@ -36,7 +36,7 @@ func (r *Role) eventCreateForward(ev *roles.Event) { r.log.Warn("failed to parse address to add dns record", zap.Error(err)) return } - var rec *Record + var rec *RecordContext if ip.Is4() { rec = forwardZone.newRecord(hostname, types.DNSRecordTypeA) } else { diff --git a/pkg/roles/dns/record.go b/pkg/roles/dns/record.go index d1a079f38..a4a79c138 100644 --- a/pkg/roles/dns/record.go +++ b/pkg/roles/dns/record.go @@ -16,7 +16,7 @@ import ( const TXTSeparator = "\n" -type Record struct { +type RecordContext struct { *types.Record inst roles.Instance @@ -26,7 +26,7 @@ type Record struct { recordKey string } -func (z *ZoneContext) recordFromKV(kv *mvccpb.KeyValue) (*Record, error) { +func (z *ZoneContext) recordFromKV(kv *mvccpb.KeyValue) (*RecordContext, error) { fullRecordKey := string(kv.Key) // Relative key compared to zone, format of // host/A[/...] @@ -56,8 +56,8 @@ func (z *ZoneContext) recordFromKV(kv *mvccpb.KeyValue) (*Record, error) { return rec, nil } -func (z *ZoneContext) newRecord(name string, t string) *Record { - return &Record{ +func (z *ZoneContext) newRecord(name string, t string) *RecordContext { + return &RecordContext{ Record: &types.Record{ Name: strings.ToLower(name), Type: t, @@ -67,7 +67,7 @@ func (z *ZoneContext) newRecord(name string, t string) *Record { } } -func (r *Record) ToDNS(qname string, t uint16) dns.RR { +func (r *RecordContext) ToDNS(qname string, t uint16) dns.RR { hdr := dns.RR_Header{ Name: qname, Rrtype: t, @@ -111,7 +111,7 @@ func (r *Record) ToDNS(qname string, t uint16) dns.RR { return rr } -func (r *Record) put(ctx context.Context, expiry int64, opts ...clientv3.OpOption) error { +func (r *RecordContext) put(ctx context.Context, expiry int64, opts ...clientv3.OpOption) error { raw, err := proto.Marshal(r.Record) if err != nil { return err diff --git a/pkg/roles/dns/zone.go b/pkg/roles/dns/zone.go index 00131bdd0..bc38f37d2 100644 --- a/pkg/roles/dns/zone.go +++ b/pkg/roles/dns/zone.go @@ -27,7 +27,7 @@ const ( type ZoneContext struct { *types.Zone inst roles.Instance - records map[string]map[string]*Record + records map[string]map[string]*RecordContext recordsWatchCtx context.CancelFunc log *zap.Logger etcdKey string @@ -127,7 +127,7 @@ func (r *Role) newZone(name string) *ZoneContext { }, inst: r.i, h: make([]Handler, 0), - records: make(map[string]map[string]*Record), + records: make(map[string]map[string]*RecordContext), recordsSync: sync.RWMutex{}, } } @@ -183,7 +183,7 @@ func (z *ZoneContext) watchZoneRecords(ctx context.Context) { defer z.recordsSync.Unlock() rec, err := z.recordFromKV(ev.Kv) if _, ok := z.records[rec.recordKey]; !ok { - z.records[rec.recordKey] = make(map[string]*Record) + z.records[rec.recordKey] = make(map[string]*RecordContext) } if ev.Type == clientv3.EventTypeDelete { delete(z.records[rec.recordKey], rec.uid) From cbaebfa316da2df5892dad802b57fe5b89c1a827 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 1 Jun 2023 00:30:22 +0200 Subject: [PATCH 4/6] write protobuf in tests --- pkg/roles/dns/api_records_test.go | 10 +++++----- pkg/roles/dns/api_zones_test.go | 4 ++-- pkg/roles/dns/handler_coredns_test.go | 2 +- pkg/roles/dns/handler_etcd_test.go | 12 ++++++------ pkg/roles/dns/handler_forward_blocky_test.go | 2 +- pkg/roles/dns/handler_forward_ip_test.go | 6 +++--- pkg/roles/dns/zone_test.go | 2 +- pkg/tests/utils.go | 10 ++++++++++ 8 files changed, 29 insertions(+), 19 deletions(-) diff --git a/pkg/roles/dns/api_records_test.go b/pkg/roles/dns/api_records_test.go index 4448b4127..93691989e 100644 --- a/pkg/roles/dns/api_records_test.go +++ b/pkg/roles/dns/api_records_test.go @@ -24,7 +24,7 @@ func TestAPIRecordsGet(t *testing.T) { types.KeyZones, zone, ).String(), - tests.MustJSON(dns.ZoneContext{}), + tests.MustPB(&types.Zone{}), ) inst.KV().Put( ctx, @@ -35,7 +35,7 @@ func TestAPIRecordsGet(t *testing.T) { "test", "A", ).String(), - tests.MustJSON(types.Record{ + tests.MustPB(&types.Record{ Data: "192.0.2.1", }), ) @@ -61,7 +61,7 @@ func TestAPIRecordsPut(t *testing.T) { types.KeyZones, name, ).String(), - tests.MustJSON(dns.ZoneContext{}), + tests.MustPB(&types.Zone{}), ) assert.NoError(t, role.APIRecordsPut().Interact(ctx, dns.APIRecordsPutInput{ Zone: name, @@ -100,7 +100,7 @@ func TestAPIRecordsDelete(t *testing.T) { types.KeyZones, zone, ).String(), - tests.MustJSON(dns.ZoneContext{}), + tests.MustPB(&types.Zone{}), ) inst.KV().Put( ctx, @@ -111,7 +111,7 @@ func TestAPIRecordsDelete(t *testing.T) { "test", "A", ).String(), - tests.MustJSON(types.Record{ + tests.MustPB(&types.Record{ Data: "192.0.2.1", }), ) diff --git a/pkg/roles/dns/api_zones_test.go b/pkg/roles/dns/api_zones_test.go index 3415aef03..2a4e8e71f 100644 --- a/pkg/roles/dns/api_zones_test.go +++ b/pkg/roles/dns/api_zones_test.go @@ -25,7 +25,7 @@ func TestAPIZonesGet(t *testing.T) { types.KeyZones, "test.", ).String(), - tests.MustJSON(dns.ZoneContext{}), + tests.MustPB(&types.Zone{}), ) var output dns.APIZonesGetOutput @@ -86,7 +86,7 @@ func TestAPIZonesDelete(t *testing.T) { types.KeyZones, name, ).String(), - tests.MustJSON(dns.ZoneContext{}), + tests.MustPB(&types.Zone{}), ) assert.NoError(t, role.APIZonesDelete().Interact(ctx, dns.APIZonesDeleteInput{ diff --git a/pkg/roles/dns/handler_coredns_test.go b/pkg/roles/dns/handler_coredns_test.go index 90e7a28b4..acea8b83e 100644 --- a/pkg/roles/dns/handler_coredns_test.go +++ b/pkg/roles/dns/handler_coredns_test.go @@ -30,7 +30,7 @@ func TestRoleDNSHandlerCoreDNS(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(types.Zone{ + tests.MustPB(&types.Zone{ HandlerConfigs: []*structpb.Struct{ { Fields: map[string]*structpb.Value{ diff --git a/pkg/roles/dns/handler_etcd_test.go b/pkg/roles/dns/handler_etcd_test.go index 9f7ea225d..b5a204d93 100644 --- a/pkg/roles/dns/handler_etcd_test.go +++ b/pkg/roles/dns/handler_etcd_test.go @@ -24,7 +24,7 @@ func TestRoleDNS_Etcd(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(types.Zone{ + tests.MustPB(&types.Zone{ HandlerConfigs: []*structpb.Struct{ { Fields: map[string]*structpb.Value{ @@ -44,7 +44,7 @@ func TestRoleDNS_Etcd(t *testing.T) { types.DNSRecordTypeA, "0", ).String(), - tests.MustJSON(types.Record{ + tests.MustPB(&types.Record{ Data: "10.1.2.3", }), ) @@ -70,7 +70,7 @@ func TestRoleDNS_Etcd_Wildcard(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(types.Zone{ + tests.MustPB(&types.Zone{ HandlerConfigs: []*structpb.Struct{ { Fields: map[string]*structpb.Value{ @@ -90,7 +90,7 @@ func TestRoleDNS_Etcd_Wildcard(t *testing.T) { types.DNSRecordTypeA, "0", ).String(), - tests.MustJSON(types.Record{ + tests.MustPB(&types.Record{ Data: "10.1.2.3", }), ) @@ -116,7 +116,7 @@ func TestRoleDNS_Etcd_WildcardNested(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(types.Zone{ + tests.MustPB(&types.Zone{ HandlerConfigs: []*structpb.Struct{ { Fields: map[string]*structpb.Value{ @@ -136,7 +136,7 @@ func TestRoleDNS_Etcd_WildcardNested(t *testing.T) { types.DNSRecordTypeA, "0", ).String(), - tests.MustJSON(types.Record{ + tests.MustPB(&types.Record{ Data: "10.1.2.3", }), ) diff --git a/pkg/roles/dns/handler_forward_blocky_test.go b/pkg/roles/dns/handler_forward_blocky_test.go index d5069b6ec..65e5b4838 100644 --- a/pkg/roles/dns/handler_forward_blocky_test.go +++ b/pkg/roles/dns/handler_forward_blocky_test.go @@ -32,7 +32,7 @@ func TestRoleDNS_BlockyForwarder(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(types.Zone{ + tests.MustPB(&types.Zone{ HandlerConfigs: []*structpb.Struct{ { Fields: map[string]*structpb.Value{ diff --git a/pkg/roles/dns/handler_forward_ip_test.go b/pkg/roles/dns/handler_forward_ip_test.go index 8647ab5fb..9a4ada4b0 100644 --- a/pkg/roles/dns/handler_forward_ip_test.go +++ b/pkg/roles/dns/handler_forward_ip_test.go @@ -25,7 +25,7 @@ func TestRoleDNS_IPForwarder_v4(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(types.Zone{ + tests.MustPB(&types.Zone{ HandlerConfigs: []*structpb.Struct{ { Fields: map[string]*structpb.Value{ @@ -65,7 +65,7 @@ func TestRoleDNS_IPForwarder_v4_Cache(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(types.Zone{ + tests.MustPB(&types.Zone{ HandlerConfigs: []*structpb.Struct{ { Fields: map[string]*structpb.Value{ @@ -112,7 +112,7 @@ func TestRoleDNS_IPForwarder_v6(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(types.Zone{ + tests.MustPB(&types.Zone{ HandlerConfigs: []*structpb.Struct{ { Fields: map[string]*structpb.Value{ diff --git a/pkg/roles/dns/zone_test.go b/pkg/roles/dns/zone_test.go index b38b7874c..7332bf1f0 100644 --- a/pkg/roles/dns/zone_test.go +++ b/pkg/roles/dns/zone_test.go @@ -22,7 +22,7 @@ func TestRoleDNSZoneFind(t *testing.T) { types.KeyZones, ".", ).String(), - tests.MustJSON(types.Zone{ + tests.MustPB(&types.Zone{ HandlerConfigs: []*structpb.Struct{ { Fields: map[string]*structpb.Value{ diff --git a/pkg/tests/utils.go b/pkg/tests/utils.go index 7de529cdb..45f423b2c 100644 --- a/pkg/tests/utils.go +++ b/pkg/tests/utils.go @@ -16,6 +16,8 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" clientv3 "go.etcd.io/etcd/client/v3" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" ) func MustJSON(in interface{}) string { @@ -26,6 +28,14 @@ func MustJSON(in interface{}) string { return string(j) } +func MustPB(m protoreflect.ProtoMessage) string { + raw, err := proto.Marshal(m) + if err != nil { + panic(err) + } + return string(raw) +} + func Context() context.Context { ctx, _ := context.WithTimeout(context.Background(), 3*time.Second) //nolint return sentry.StartTransaction(ctx, "test").Context() From ab64c780182fe3fe13ad9c00e99010b91a3ddf85 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 1 Jun 2023 00:41:41 +0200 Subject: [PATCH 5/6] fully migrate DNS to proto --- pkg/roles/dns/record.go | 10 +- pkg/roles/dns/role.go | 2 +- pkg/roles/dns/role_config.go | 23 ++-- pkg/roles/dns/role_config_test.go | 3 +- pkg/roles/dns/role_test.go | 3 +- pkg/roles/dns/types/role_dns_config.pb.go | 143 ++++++++++++++++++++++ pkg/roles/dns/zone.go | 10 +- pkg/storage/utils.go | 23 ++++ protobuf/role_dns_config.proto | 7 ++ 9 files changed, 192 insertions(+), 32 deletions(-) create mode 100644 pkg/roles/dns/types/role_dns_config.pb.go create mode 100644 pkg/storage/utils.go create mode 100644 protobuf/role_dns_config.proto diff --git a/pkg/roles/dns/record.go b/pkg/roles/dns/record.go index a4a79c138..2895ab4dc 100644 --- a/pkg/roles/dns/record.go +++ b/pkg/roles/dns/record.go @@ -2,12 +2,12 @@ package dns import ( "context" - "encoding/json" "net" "strings" "beryju.io/gravity/pkg/roles" "beryju.io/gravity/pkg/roles/dns/types" + "beryju.io/gravity/pkg/storage" "github.com/miekg/dns" "go.etcd.io/etcd/api/v3/mvccpb" clientv3 "go.etcd.io/etcd/client/v3" @@ -43,13 +43,7 @@ func (z *ZoneContext) recordFromKV(kv *mvccpb.KeyValue) (*RecordContext, error) } rec.recordKey = strings.TrimSuffix(fullRecordKey, "/"+rec.uid) - // Try loading protobuf first - err := proto.Unmarshal(kv.Value, rec.Record) - if err == nil { - return rec, nil - } - // Otherwise try json - err = json.Unmarshal(kv.Value, &rec) + _, err := storage.Parse(kv.Value, rec.Record) if err != nil { return rec, err } diff --git a/pkg/roles/dns/role.go b/pkg/roles/dns/role.go index 091e020c4..fe320f9dd 100644 --- a/pkg/roles/dns/role.go +++ b/pkg/roles/dns/role.go @@ -24,7 +24,7 @@ type Role struct { ctx context.Context zones map[string]*ZoneContext - cfg *RoleConfig + cfg *types.DNSRoleConfig log *zap.Logger servers []*dns.Server zonesM sync.RWMutex diff --git a/pkg/roles/dns/role_config.go b/pkg/roles/dns/role_config.go index bbf9e7f4a..e4f6c566f 100644 --- a/pkg/roles/dns/role_config.go +++ b/pkg/roles/dns/role_config.go @@ -2,41 +2,38 @@ package dns import ( "context" - "encoding/json" instanceTypes "beryju.io/gravity/pkg/instance/types" + "beryju.io/gravity/pkg/storage" "go.uber.org/zap" + "google.golang.org/protobuf/proto" "beryju.io/gravity/pkg/roles/dns/types" "github.com/swaggest/usecase" "github.com/swaggest/usecase/status" ) -type RoleConfig struct { - Port int32 `json:"port"` -} - -func (r *Role) decodeRoleConfig(raw []byte) *RoleConfig { - def := RoleConfig{ +func (r *Role) decodeRoleConfig(raw []byte) *types.DNSRoleConfig { + def := types.DNSRoleConfig{ Port: 53, } if len(raw) < 1 { return &def } - err := json.Unmarshal(raw, &def) + conf, err := storage.Parse(raw, &def) if err != nil { r.log.Warn("failed to decode role config", zap.Error(err)) } - return &def + return conf } type APIRoleConfigOutput struct { - Config RoleConfig `json:"config" required:"true"` + Config *types.DNSRoleConfig `json:"config" required:"true"` } func (r *Role) APIRoleConfigGet() usecase.Interactor { u := usecase.NewInteractor(func(ctx context.Context, input struct{}, output *APIRoleConfigOutput) error { - output.Config = *r.cfg + output.Config = r.cfg return nil }) u.SetName("dns.get_role_config") @@ -46,12 +43,12 @@ func (r *Role) APIRoleConfigGet() usecase.Interactor { } type APIRoleConfigInput struct { - Config RoleConfig `json:"config" required:"true"` + Config *types.DNSRoleConfig `json:"config" required:"true"` } func (r *Role) APIRoleConfigPut() usecase.Interactor { u := usecase.NewInteractor(func(ctx context.Context, input APIRoleConfigInput, output *struct{}) error { - jc, err := json.Marshal(input.Config) + jc, err := proto.Marshal(input.Config) if err != nil { return status.Wrap(err, status.InvalidArgument) } diff --git a/pkg/roles/dns/role_config_test.go b/pkg/roles/dns/role_config_test.go index 6a20a4c77..8dc373583 100644 --- a/pkg/roles/dns/role_config_test.go +++ b/pkg/roles/dns/role_config_test.go @@ -5,6 +5,7 @@ import ( "beryju.io/gravity/pkg/instance" "beryju.io/gravity/pkg/roles/dns" + "beryju.io/gravity/pkg/roles/dns/types" "beryju.io/gravity/pkg/tests" "github.com/stretchr/testify/assert" ) @@ -31,7 +32,7 @@ func TestAPIRoleConfigPut(t *testing.T) { defer role.Stop() assert.NoError(t, role.APIRoleConfigPut().Interact(ctx, dns.APIRoleConfigInput{ - Config: dns.RoleConfig{ + Config: &types.DNSRoleConfig{ Port: 1054, }, }, &struct{}{})) diff --git a/pkg/roles/dns/role_test.go b/pkg/roles/dns/role_test.go index 70b3ae867..47945dfa8 100644 --- a/pkg/roles/dns/role_test.go +++ b/pkg/roles/dns/role_test.go @@ -5,12 +5,13 @@ import ( "beryju.io/gravity/pkg/instance" "beryju.io/gravity/pkg/roles/dns" + "beryju.io/gravity/pkg/roles/dns/types" "beryju.io/gravity/pkg/tests" "github.com/stretchr/testify/assert" ) func RoleConfig() []byte { - return []byte(tests.MustJSON(dns.RoleConfig{ + return []byte(tests.MustPB(&types.DNSRoleConfig{ Port: 1054, })) } diff --git a/pkg/roles/dns/types/role_dns_config.pb.go b/pkg/roles/dns/types/role_dns_config.pb.go new file mode 100644 index 000000000..a8ab55816 --- /dev/null +++ b/pkg/roles/dns/types/role_dns_config.pb.go @@ -0,0 +1,143 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.21.12 +// source: protobuf/role_dns_config.proto + +package types + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type DNSRoleConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Port int32 `protobuf:"varint,1,opt,name=port,proto3" json:"port,omitempty"` +} + +func (x *DNSRoleConfig) Reset() { + *x = DNSRoleConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_role_dns_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DNSRoleConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DNSRoleConfig) ProtoMessage() {} + +func (x *DNSRoleConfig) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_role_dns_config_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DNSRoleConfig.ProtoReflect.Descriptor instead. +func (*DNSRoleConfig) Descriptor() ([]byte, []int) { + return file_protobuf_role_dns_config_proto_rawDescGZIP(), []int{0} +} + +func (x *DNSRoleConfig) GetPort() int32 { + if x != nil { + return x.Port + } + return 0 +} + +var File_protobuf_role_dns_config_proto protoreflect.FileDescriptor + +var file_protobuf_role_dns_config_proto_rawDesc = []byte{ + 0x0a, 0x1e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, + 0x64, 0x6e, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x23, 0x0a, 0x0d, 0x44, 0x4e, 0x53, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x04, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x15, 0x5a, 0x13, 0x70, 0x6b, 0x67, 0x2f, 0x72, 0x6f, 0x6c, + 0x65, 0x73, 0x2f, 0x64, 0x6e, 0x73, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_protobuf_role_dns_config_proto_rawDescOnce sync.Once + file_protobuf_role_dns_config_proto_rawDescData = file_protobuf_role_dns_config_proto_rawDesc +) + +func file_protobuf_role_dns_config_proto_rawDescGZIP() []byte { + file_protobuf_role_dns_config_proto_rawDescOnce.Do(func() { + file_protobuf_role_dns_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_protobuf_role_dns_config_proto_rawDescData) + }) + return file_protobuf_role_dns_config_proto_rawDescData +} + +var file_protobuf_role_dns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_protobuf_role_dns_config_proto_goTypes = []interface{}{ + (*DNSRoleConfig)(nil), // 0: DNSRoleConfig +} +var file_protobuf_role_dns_config_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_protobuf_role_dns_config_proto_init() } +func file_protobuf_role_dns_config_proto_init() { + if File_protobuf_role_dns_config_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_protobuf_role_dns_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DNSRoleConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_protobuf_role_dns_config_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_protobuf_role_dns_config_proto_goTypes, + DependencyIndexes: file_protobuf_role_dns_config_proto_depIdxs, + MessageInfos: file_protobuf_role_dns_config_proto_msgTypes, + }.Build() + File_protobuf_role_dns_config_proto = out.File + file_protobuf_role_dns_config_proto_rawDesc = nil + file_protobuf_role_dns_config_proto_goTypes = nil + file_protobuf_role_dns_config_proto_depIdxs = nil +} diff --git a/pkg/roles/dns/zone.go b/pkg/roles/dns/zone.go index bc38f37d2..7494ce120 100644 --- a/pkg/roles/dns/zone.go +++ b/pkg/roles/dns/zone.go @@ -2,7 +2,6 @@ package dns import ( "context" - "encoding/json" "fmt" "strings" "sync" @@ -12,6 +11,7 @@ import ( "beryju.io/gravity/pkg/roles/dns/types" "beryju.io/gravity/pkg/roles/dns/utils" tsdbTypes "beryju.io/gravity/pkg/roles/tsdb/types" + "beryju.io/gravity/pkg/storage" "github.com/getsentry/sentry-go" "github.com/miekg/dns" "go.etcd.io/etcd/api/v3/mvccpb" @@ -139,13 +139,7 @@ func (r *Role) zoneFromKV(raw *mvccpb.KeyValue) (*ZoneContext, error) { z.log = r.log.With(zap.String("zone", name)) z.etcdKey = string(raw.Key) - // Try loading protobuf first - err := proto.Unmarshal(raw.Value, z.Zone) - if err == nil { - return z, nil - } - // Otherwise try json - err = json.Unmarshal(raw.Value, &z) + _, err := storage.Parse(raw.Value, z.Zone) if err != nil { return nil, err } diff --git a/pkg/storage/utils.go b/pkg/storage/utils.go new file mode 100644 index 000000000..4dc00be44 --- /dev/null +++ b/pkg/storage/utils.go @@ -0,0 +1,23 @@ +package storage + +import ( + "encoding/json" + + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" +) + +// Parse Attempt to parse data as protobuf first, otherwise try json +func Parse[T protoreflect.ProtoMessage](raw []byte, v T) (T, error) { + // Try loading protobuf first + err := proto.Unmarshal(raw, v) + if err == nil { + return v, nil + } + // Otherwise try json + err = json.Unmarshal(raw, &v) + if err == nil { + return v, nil + } + return v, err +} diff --git a/protobuf/role_dns_config.proto b/protobuf/role_dns_config.proto new file mode 100644 index 000000000..c526f1264 --- /dev/null +++ b/protobuf/role_dns_config.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +option go_package = "pkg/roles/dns/types"; + +message DNSRoleConfig { + int32 port = 1; +} From 5ce76a0eef5aad17cc6847d47696f0075152058c Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 1 Jun 2023 01:02:45 +0200 Subject: [PATCH 6/6] migrate tsdb --- pkg/roles/tsdb/role.go | 2 +- pkg/roles/tsdb/role_config.go | 22 ++- pkg/roles/tsdb/role_config_test.go | 3 +- pkg/roles/tsdb/role_test.go | 4 +- pkg/roles/tsdb/types/role_tsdb_config.pb.go | 162 ++++++++++++++++++++ protobuf/role_tsdb_config.proto | 9 ++ 6 files changed, 185 insertions(+), 17 deletions(-) create mode 100644 pkg/roles/tsdb/types/role_tsdb_config.pb.go create mode 100644 protobuf/role_tsdb_config.proto diff --git a/pkg/roles/tsdb/role.go b/pkg/roles/tsdb/role.go index bd2b7a2c3..08ccb6dfe 100644 --- a/pkg/roles/tsdb/role.go +++ b/pkg/roles/tsdb/role.go @@ -25,7 +25,7 @@ import ( type Role struct { log *zap.Logger i roles.Instance - cfg *RoleConfig + cfg *types.TSDBRoleConfig ctx context.Context m map[string]types.Metric ms sync.RWMutex diff --git a/pkg/roles/tsdb/role_config.go b/pkg/roles/tsdb/role_config.go index e5105657a..080b291f5 100644 --- a/pkg/roles/tsdb/role_config.go +++ b/pkg/roles/tsdb/role_config.go @@ -5,6 +5,8 @@ import ( "encoding/json" instanceTypes "beryju.io/gravity/pkg/instance/types" + "beryju.io/gravity/pkg/roles/tsdb/types" + "beryju.io/gravity/pkg/storage" "go.uber.org/zap" "github.com/swaggest/usecase" @@ -15,14 +17,8 @@ const ( KeyRole = "tsdb" ) -type RoleConfig struct { - Enabled bool `json:"enabled"` - Expire int64 `json:"expire"` - Scrape int64 `json:"scrape"` -} - -func (r *Role) decodeRoleConfig(raw []byte) *RoleConfig { - def := RoleConfig{ +func (r *Role) decodeRoleConfig(raw []byte) *types.TSDBRoleConfig { + def := types.TSDBRoleConfig{ Enabled: true, Expire: 60 * 30, Scrape: 30, @@ -30,20 +26,20 @@ func (r *Role) decodeRoleConfig(raw []byte) *RoleConfig { if len(raw) < 1 { return &def } - err := json.Unmarshal(raw, &def) + conf, err := storage.Parse(raw, &def) if err != nil { r.log.Warn("failed to decode role config", zap.Error(err)) } - return &def + return conf } type APIRoleConfigOutput struct { - Config RoleConfig `json:"config" required:"true"` + Config *types.TSDBRoleConfig `json:"config" required:"true"` } func (r *Role) APIRoleConfigGet() usecase.Interactor { u := usecase.NewInteractor(func(ctx context.Context, input struct{}, output *APIRoleConfigOutput) error { - output.Config = *r.cfg + output.Config = r.cfg return nil }) u.SetName("tsdb.get_role_config") @@ -53,7 +49,7 @@ func (r *Role) APIRoleConfigGet() usecase.Interactor { } type APIRoleConfigInput struct { - Config RoleConfig `json:"config" required:"true"` + Config *types.TSDBRoleConfig `json:"config" required:"true"` } func (r *Role) APIRoleConfigPut() usecase.Interactor { diff --git a/pkg/roles/tsdb/role_config_test.go b/pkg/roles/tsdb/role_config_test.go index f537e2629..d43266296 100644 --- a/pkg/roles/tsdb/role_config_test.go +++ b/pkg/roles/tsdb/role_config_test.go @@ -5,6 +5,7 @@ import ( "beryju.io/gravity/pkg/instance" "beryju.io/gravity/pkg/roles/tsdb" + "beryju.io/gravity/pkg/roles/tsdb/types" "beryju.io/gravity/pkg/tests" "github.com/stretchr/testify/assert" ) @@ -31,7 +32,7 @@ func TestAPIRoleConfigPut(t *testing.T) { defer role.Stop() assert.NoError(t, role.APIRoleConfigPut().Interact(ctx, tsdb.APIRoleConfigInput{ - Config: tsdb.RoleConfig{ + Config: &types.TSDBRoleConfig{ Enabled: false, }, }, &struct{}{})) diff --git a/pkg/roles/tsdb/role_test.go b/pkg/roles/tsdb/role_test.go index 184a14139..cb104963d 100644 --- a/pkg/roles/tsdb/role_test.go +++ b/pkg/roles/tsdb/role_test.go @@ -48,7 +48,7 @@ func TestRoleStartNotEnabled(t *testing.T) { inst := rootInst.ForRole("tsdb", ctx) role := tsdb.New(inst) assert.NotNil(t, role) - assert.Error(t, roles.ErrRoleNotConfigured, role.Start(ctx, []byte(tests.MustJSON(tsdb.RoleConfig{ + assert.Error(t, roles.ErrRoleNotConfigured, role.Start(ctx, []byte(tests.MustPB(&types.TSDBRoleConfig{ Enabled: false, })))) defer role.Stop() @@ -60,7 +60,7 @@ func TestRoleWrite(t *testing.T) { ctx := tests.Context() inst := rootInst.ForRole("tsdb", ctx) role := tsdb.New(inst) - assert.NoError(t, role.Start(ctx, []byte(tests.MustJSON(tsdb.RoleConfig{ + assert.NoError(t, role.Start(ctx, []byte(tests.MustPB(&types.TSDBRoleConfig{ Enabled: true, Scrape: 0, })))) diff --git a/pkg/roles/tsdb/types/role_tsdb_config.pb.go b/pkg/roles/tsdb/types/role_tsdb_config.pb.go new file mode 100644 index 000000000..0d76a1ef6 --- /dev/null +++ b/pkg/roles/tsdb/types/role_tsdb_config.pb.go @@ -0,0 +1,162 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc v3.21.12 +// source: protobuf/role_tsdb_config.proto + +package types + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type TSDBRoleConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` + Expire int64 `protobuf:"varint,2,opt,name=expire,proto3" json:"expire,omitempty"` + Scrape int64 `protobuf:"varint,3,opt,name=scrape,proto3" json:"scrape,omitempty"` +} + +func (x *TSDBRoleConfig) Reset() { + *x = TSDBRoleConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_protobuf_role_tsdb_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TSDBRoleConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TSDBRoleConfig) ProtoMessage() {} + +func (x *TSDBRoleConfig) ProtoReflect() protoreflect.Message { + mi := &file_protobuf_role_tsdb_config_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TSDBRoleConfig.ProtoReflect.Descriptor instead. +func (*TSDBRoleConfig) Descriptor() ([]byte, []int) { + return file_protobuf_role_tsdb_config_proto_rawDescGZIP(), []int{0} +} + +func (x *TSDBRoleConfig) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +func (x *TSDBRoleConfig) GetExpire() int64 { + if x != nil { + return x.Expire + } + return 0 +} + +func (x *TSDBRoleConfig) GetScrape() int64 { + if x != nil { + return x.Scrape + } + return 0 +} + +var File_protobuf_role_tsdb_config_proto protoreflect.FileDescriptor + +var file_protobuf_role_tsdb_config_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, + 0x74, 0x73, 0x64, 0x62, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0x5a, 0x0a, 0x0e, 0x54, 0x53, 0x44, 0x42, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x0a, + 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x72, 0x61, 0x70, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x73, 0x63, 0x72, 0x61, 0x70, 0x65, 0x42, 0x16, 0x5a, + 0x14, 0x70, 0x6b, 0x67, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x74, 0x73, 0x64, 0x62, 0x2f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_protobuf_role_tsdb_config_proto_rawDescOnce sync.Once + file_protobuf_role_tsdb_config_proto_rawDescData = file_protobuf_role_tsdb_config_proto_rawDesc +) + +func file_protobuf_role_tsdb_config_proto_rawDescGZIP() []byte { + file_protobuf_role_tsdb_config_proto_rawDescOnce.Do(func() { + file_protobuf_role_tsdb_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_protobuf_role_tsdb_config_proto_rawDescData) + }) + return file_protobuf_role_tsdb_config_proto_rawDescData +} + +var file_protobuf_role_tsdb_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_protobuf_role_tsdb_config_proto_goTypes = []interface{}{ + (*TSDBRoleConfig)(nil), // 0: TSDBRoleConfig +} +var file_protobuf_role_tsdb_config_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_protobuf_role_tsdb_config_proto_init() } +func file_protobuf_role_tsdb_config_proto_init() { + if File_protobuf_role_tsdb_config_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_protobuf_role_tsdb_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TSDBRoleConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_protobuf_role_tsdb_config_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_protobuf_role_tsdb_config_proto_goTypes, + DependencyIndexes: file_protobuf_role_tsdb_config_proto_depIdxs, + MessageInfos: file_protobuf_role_tsdb_config_proto_msgTypes, + }.Build() + File_protobuf_role_tsdb_config_proto = out.File + file_protobuf_role_tsdb_config_proto_rawDesc = nil + file_protobuf_role_tsdb_config_proto_goTypes = nil + file_protobuf_role_tsdb_config_proto_depIdxs = nil +} diff --git a/protobuf/role_tsdb_config.proto b/protobuf/role_tsdb_config.proto new file mode 100644 index 000000000..d743848ff --- /dev/null +++ b/protobuf/role_tsdb_config.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +option go_package = "pkg/roles/tsdb/types"; + +message TSDBRoleConfig { + bool enabled = 1; + int64 expire = 2; + int64 scrape = 3; +}