diff --git a/cmd/rdpgw/rdp/rdp.go b/cmd/rdpgw/rdp/rdp.go index 9b545a93a18d2d8488aaeae18e8eb02a3d4e27c2..0dde06c8d0128e4dfe8957ff2fcb64f21ea486a4 100644 --- a/cmd/rdpgw/rdp/rdp.go +++ b/cmd/rdpgw/rdp/rdp.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/bolkedebruin/rdpgw/cmd/rdpgw/rdp/koanf/parsers/rdp" "github.com/fatih/structs" + "github.com/go-viper/mapstructure/v2" "github.com/knadh/koanf/providers/file" "github.com/knadh/koanf/v2" "log" @@ -93,6 +94,7 @@ type RdpSettings struct { type Builder struct { Settings RdpSettings + Metadata mapstructure.Metadata } func NewBuilder() *Builder { @@ -102,39 +104,47 @@ func NewBuilder() *Builder { return &Builder{ Settings: c, + Metadata: mapstructure.Metadata{}, } } func NewBuilderFromFile(filename string) (*Builder, error) { c := RdpSettings{} initStruct(&c) + metadata := mapstructure.Metadata{} + + decoderConfig := &mapstructure.DecoderConfig{ + Result: &c, + Metadata: &metadata, + } var k = koanf.New(".") if err := k.Load(file.Provider(filename), rdp.Parser()); err != nil { return nil, err } - t := koanf.UnmarshalConf{Tag: "rdp"} + t := koanf.UnmarshalConf{Tag: "rdp", DecoderConfig: decoderConfig} if err := k.UnmarshalWithConf("", &c, t); err != nil { return nil, err } return &Builder{ Settings: c, + Metadata: metadata, }, nil } func (rb *Builder) String() string { var sb strings.Builder - addStructToString(rb.Settings, &sb) + addStructToString(rb.Settings, rb.Metadata, &sb) return sb.String() } -func addStructToString(st interface{}, sb *strings.Builder) { +func addStructToString(st interface{}, metadata mapstructure.Metadata, sb *strings.Builder) { s := structs.New(st) for _, f := range s.Fields() { - if isZero(f) { + if isZero(f) && !isSet(f, metadata) { continue } sb.WriteString(f.Tag("rdp")) @@ -195,6 +205,16 @@ func isZero(f *structs.Field) bool { return f.IsZero() } +func isSet(f *structs.Field, metadata mapstructure.Metadata) bool { + for _, v := range metadata.Unset { + if v == f.Name() { + log.Printf("field %s is unset", f.Name()) + return true + } + } + return false +} + func initStruct(st interface{}) { s := structs.New(st) for _, f := range s.Fields() { diff --git a/cmd/rdpgw/rdp/rdp_test.go b/cmd/rdpgw/rdp/rdp_test.go index 8efb70e73222cddedb7e2831efdcecb51e0c2a78..19743c697cfa66343f4800b5c11b3c46b0a8a07a 100644 --- a/cmd/rdpgw/rdp/rdp_test.go +++ b/cmd/rdpgw/rdp/rdp_test.go @@ -21,7 +21,7 @@ func TestRdpBuilder(t *testing.T) { t.Fatalf("%s does not contain `gatewayhostname:s:%s", s, GatewayHostName) } if strings.Contains(s, "autoreconnectionenabled") { - t.Fatalf("autoreconnectionenabled is in %s, but is default value", s) + t.Fatalf("autoreconnectionenabled is in %s, but it's default value", s) } if !strings.Contains(s, "smart sizing:i:1"+CRLF) { t.Fatalf("%s does not contain smart sizing:i:1", s)