Merge branch 'main' into oss-125-postgresql-state-store-add-separate-metadata-options-for

This commit is contained in:
Nelson Parente 2025-05-22 15:40:00 +01:00 committed by GitHub
commit 4d2a1de355
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 157 additions and 50 deletions

View File

@ -12,7 +12,7 @@ require (
)
require (
github.com/dapr/kit v0.13.1-0.20240909215017-3823663aa4bb // indirect
github.com/dapr/kit v0.15.3-0.20250516121556-bc7dc566c45d // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect

View File

@ -1,6 +1,6 @@
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/dapr/kit v0.13.1-0.20240909215017-3823663aa4bb h1:ahLO7pMmX6HAuT6/RxYWBY4AN2fXQJcYlU1msY6Kt7U=
github.com/dapr/kit v0.13.1-0.20240909215017-3823663aa4bb/go.mod h1:Hz1W2LmWfA4UX/12MdA+brsf+np6f/1dJt6C6F63cjI=
github.com/dapr/kit v0.15.3-0.20250516121556-bc7dc566c45d h1:v+kZn9ami23xBsruyZmKErIOSlCdW9pR8wfHUg5+jys=
github.com/dapr/kit v0.15.3-0.20250516121556-bc7dc566c45d/go.mod h1:6w2Pr38zOAtBn+ld/jknwI4kgMfwanCIcFVnPykdPZQ=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

View File

@ -40,7 +40,7 @@ import (
"github.com/dapr/kit/logger"
kitmd "github.com/dapr/kit/metadata"
"github.com/dapr/kit/ptr"
"github.com/dapr/kit/utils"
kitstrings "github.com/dapr/kit/strings"
)
const (
@ -455,11 +455,11 @@ func (metadata s3Metadata) mergeWithRequestMetadata(req *bindings.InvokeRequest)
merged := metadata
if val, ok := req.Metadata[metadataDecodeBase64]; ok && val != "" {
merged.DecodeBase64 = utils.IsTruthy(val)
merged.DecodeBase64 = kitstrings.IsTruthy(val)
}
if val, ok := req.Metadata[metadataEncodeBase64]; ok && val != "" {
merged.EncodeBase64 = utils.IsTruthy(val)
merged.EncodeBase64 = kitstrings.IsTruthy(val)
}
if val, ok := req.Metadata[metadataFilePath]; ok && val != "" {

View File

@ -25,10 +25,12 @@ import (
"net/url"
"reflect"
"strconv"
"sync"
"time"
"cloud.google.com/go/storage"
"github.com/google/uuid"
"go.uber.org/multierr"
"google.golang.org/api/googleapi"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
@ -37,7 +39,7 @@ import (
"github.com/dapr/components-contrib/metadata"
"github.com/dapr/kit/logger"
kitmd "github.com/dapr/kit/metadata"
"github.com/dapr/kit/utils"
"github.com/dapr/kit/strings"
)
const (
@ -49,8 +51,9 @@ const (
metadataKey = "key"
maxResults = 1000
metadataKeyBC = "name"
signOperation = "sign"
metadataKeyBC = "name"
signOperation = "sign"
bulkGetOperation = "bulkGet"
)
// GCPStorage allows saving data to GCP bucket storage.
@ -138,6 +141,7 @@ func (g *GCPStorage) Operations() []bindings.OperationKind {
bindings.DeleteOperation,
bindings.ListOperation,
signOperation,
bulkGetOperation,
}
}
@ -155,6 +159,8 @@ func (g *GCPStorage) Invoke(ctx context.Context, req *bindings.InvokeRequest) (*
return g.list(ctx, req)
case signOperation:
return g.sign(ctx, req)
case bulkGetOperation:
return g.bulkGet(ctx, req)
default:
return nil, fmt.Errorf("unsupported operation %s", req.Operation)
}
@ -325,11 +331,11 @@ func (metadata gcpMetadata) mergeWithRequestMetadata(req *bindings.InvokeRequest
merged := metadata
if val, ok := req.Metadata[metadataDecodeBase64]; ok && val != "" {
merged.DecodeBase64 = utils.IsTruthy(val)
merged.DecodeBase64 = strings.IsTruthy(val)
}
if val, ok := req.Metadata[metadataEncodeBase64]; ok && val != "" {
merged.EncodeBase64 = utils.IsTruthy(val)
merged.EncodeBase64 = strings.IsTruthy(val)
}
if val, ok := req.Metadata[metadataSignTTL]; ok && val != "" {
merged.SignTTL = val
@ -404,3 +410,91 @@ func (g *GCPStorage) signObject(bucket, object, ttl string) (string, error) {
}
return u, nil
}
type objectData struct {
Name string `json:"name"`
Data []byte `json:"data"`
Attrs storage.ObjectAttrs `json:"attrs"`
}
func (g *GCPStorage) bulkGet(ctx context.Context, req *bindings.InvokeRequest) (*bindings.InvokeResponse, error) {
metadata, err := g.metadata.mergeWithRequestMetadata(req)
if err != nil {
return nil, fmt.Errorf("gcp binding error while merging metadata : %w", err)
}
if g.metadata.Bucket == "" {
return nil, errors.New("gcp bucket binding error: bucket is required")
}
var allObjs []*storage.ObjectAttrs
it := g.client.Bucket(g.metadata.Bucket).Objects(ctx, nil)
for {
attrs, err2 := it.Next()
if err2 == iterator.Done {
break
}
allObjs = append(allObjs, attrs)
}
var wg sync.WaitGroup
objectsCh := make(chan objectData, len(allObjs))
errCh := make(chan error, len(allObjs))
for i, obj := range allObjs {
wg.Add(1)
go func(idx int, object *storage.ObjectAttrs) {
defer wg.Done()
rc, err3 := g.client.Bucket(g.metadata.Bucket).Object(object.Name).NewReader(ctx)
if err3 != nil {
errCh <- err3
return
}
defer rc.Close()
data, readErr := io.ReadAll(rc)
if readErr != nil {
errCh <- readErr
return
}
if metadata.EncodeBase64 {
encoded := b64.StdEncoding.EncodeToString(data)
data = []byte(encoded)
}
objectsCh <- objectData{
Name: object.Name,
Data: data,
Attrs: *object,
}
}(i, obj)
}
wg.Wait()
close(errCh)
var multiErr error
for err := range errCh {
multierr.AppendInto(&multiErr, err)
}
if multiErr != nil {
return nil, multiErr
}
response := make([]objectData, 0, len(allObjs))
for obj := range objectsCh {
response = append(response, obj)
}
jsonResponse, err := json.Marshal(response)
if err != nil {
return nil, fmt.Errorf("gcp bucket binding error while marshalling bulk get response: %w", err)
}
return &bindings.InvokeResponse{
Data: jsonResponse,
}, nil
}

View File

@ -254,3 +254,14 @@ func TestDeleteOption(t *testing.T) {
require.Error(t, err)
})
}
func TestBulkGetOption(t *testing.T) {
gs := GCPStorage{logger: logger.NewLogger("test")}
gs.metadata = &gcpMetadata{}
t.Run("return error if bucket is missing", func(t *testing.T) {
r := bindings.InvokeRequest{}
_, err := gs.bulkGet(t.Context(), &r)
require.Error(t, err)
})
}

View File

@ -34,7 +34,7 @@ import (
"github.com/dapr/components-contrib/metadata"
"github.com/dapr/kit/logger"
kitmd "github.com/dapr/kit/metadata"
"github.com/dapr/kit/utils"
kitstrings "github.com/dapr/kit/strings"
)
const (
@ -137,7 +137,7 @@ func (h *HTTPSource) Init(_ context.Context, meta bindings.Metadata) error {
}
if val := meta.Properties["errorIfNot2XX"]; val != "" {
h.errorIfNot2XX = utils.IsTruthy(val)
h.errorIfNot2XX = kitstrings.IsTruthy(val)
} else {
// Default behavior
h.errorIfNot2XX = true
@ -252,7 +252,7 @@ func (h *HTTPSource) Invoke(parentCtx context.Context, req *bindings.InvokeReque
u = strings.TrimRight(u, "/") + "/" + strings.TrimLeft(req.Metadata["path"], "/")
}
if req.Metadata["errorIfNot2XX"] != "" {
errorIfNot2XX = utils.IsTruthy(req.Metadata["errorIfNot2XX"])
errorIfNot2XX = kitstrings.IsTruthy(req.Metadata["errorIfNot2XX"])
}
var body io.Reader

View File

@ -34,7 +34,7 @@ import (
"github.com/dapr/components-contrib/metadata"
"github.com/dapr/kit/logger"
kitmd "github.com/dapr/kit/metadata"
"github.com/dapr/kit/utils"
"github.com/dapr/kit/strings"
)
const (
@ -313,7 +313,7 @@ func (r *RabbitMQ) parseMetadata(meta bindings.Metadata) error {
}
if val, ok := meta.Properties[externalSasl]; ok && val != "" {
m.ExternalSasl = utils.IsTruthy(val)
m.ExternalSasl = strings.IsTruthy(val)
}
if val, ok := meta.Properties[caCert]; ok && val != "" {
@ -336,7 +336,7 @@ func (r *RabbitMQ) parseMetadata(meta bindings.Metadata) error {
}
if val, ok := meta.Properties[externalSasl]; ok && val != "" {
m.ExternalSasl = utils.IsTruthy(val)
m.ExternalSasl = strings.IsTruthy(val)
}
ttl, ok, err := metadata.TryGetTTL(meta.Properties)

View File

@ -92,9 +92,11 @@ func TestGetX509Client(t *testing.T) {
var fetches atomic.Int32
s := spiffe.New(spiffe.Options{
Log: logger.NewLogger("test"),
RequestSVIDFn: func(context.Context, []byte) ([]*cryptoX509.Certificate, error) {
RequestSVIDFn: func(context.Context, []byte) (*spiffe.SVIDResponse, error) {
fetches.Add(1)
return respCert, respErr
return &spiffe.SVIDResponse{
X509Certificates: respCert,
}, respErr
},
})

2
go.mod
View File

@ -60,7 +60,7 @@ require (
github.com/cohesion-org/deepseek-go v1.2.0
github.com/cyphar/filepath-securejoin v0.2.4
github.com/dancannon/gorethink v4.0.0+incompatible
github.com/dapr/kit v0.13.1-0.20240909215017-3823663aa4bb
github.com/dapr/kit v0.15.3-0.20250516121556-bc7dc566c45d
github.com/didip/tollbooth/v7 v7.0.1
github.com/eclipse/paho.mqtt.golang v1.4.3
github.com/fasthttp-contrib/sessions v0.0.0-20160905201309-74f6ac73d5d5

4
go.sum
View File

@ -509,8 +509,8 @@ github.com/dancannon/gorethink v4.0.0+incompatible h1:KFV7Gha3AuqT+gr0B/eKvGhbjm
github.com/dancannon/gorethink v4.0.0+incompatible/go.mod h1:BLvkat9KmZc1efyYwhz3WnybhRZtgF1K929FD8z1avU=
github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0=
github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0=
github.com/dapr/kit v0.13.1-0.20240909215017-3823663aa4bb h1:ahLO7pMmX6HAuT6/RxYWBY4AN2fXQJcYlU1msY6Kt7U=
github.com/dapr/kit v0.13.1-0.20240909215017-3823663aa4bb/go.mod h1:Hz1W2LmWfA4UX/12MdA+brsf+np6f/1dJt6C6F63cjI=
github.com/dapr/kit v0.15.3-0.20250516121556-bc7dc566c45d h1:v+kZn9ami23xBsruyZmKErIOSlCdW9pR8wfHUg5+jys=
github.com/dapr/kit v0.15.3-0.20250516121556-bc7dc566c45d/go.mod h1:6w2Pr38zOAtBn+ld/jknwI4kgMfwanCIcFVnPykdPZQ=
github.com/dave/jennifer v1.4.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

View File

@ -22,7 +22,7 @@ import (
"time"
kitmd "github.com/dapr/kit/metadata"
"github.com/dapr/kit/utils"
kitstrings "github.com/dapr/kit/strings"
)
const (
@ -253,10 +253,10 @@ func GetMetadataInfoFromStructType(t reflect.Type, metadataMap *MetadataMap, com
}
// If there's a mdignore tag and that's truthy, the field should be ignored by the metadata analyzer
mdField.Ignored = utils.IsTruthy(currentField.Tag.Get("mdignore"))
mdField.Ignored = kitstrings.IsTruthy(currentField.Tag.Get("mdignore"))
// If there's a "mddeprecated" tag, the field may be deprecated
mdField.Deprecated = utils.IsTruthy(currentField.Tag.Get("mddeprecated"))
mdField.Deprecated = kitstrings.IsTruthy(currentField.Tag.Get("mddeprecated"))
// If there's a "mdaliases" tag, the field contains aliases
// The value is a comma-separated string

View File

@ -29,7 +29,7 @@ import (
"github.com/dapr/components-contrib/middleware"
"github.com/dapr/kit/logger"
kitmd "github.com/dapr/kit/metadata"
"github.com/dapr/kit/utils"
kitstrings "github.com/dapr/kit/strings"
)
// Metadata is the oAuth middleware config.
@ -70,7 +70,7 @@ func (m *Middleware) GetHandler(ctx context.Context, metadata middleware.Metadat
return nil, err
}
forceHTTPS := utils.IsTruthy(meta.ForceHTTPS)
forceHTTPS := kitstrings.IsTruthy(meta.ForceHTTPS)
conf := &oauth2.Config{
ClientID: meta.ClientID,
ClientSecret: meta.ClientSecret,

View File

@ -36,7 +36,7 @@ import (
"github.com/dapr/components-contrib/middleware"
"github.com/dapr/kit/logger"
kitmd "github.com/dapr/kit/metadata"
"github.com/dapr/kit/utils"
kitstrings "github.com/dapr/kit/strings"
)
type Status int
@ -145,7 +145,7 @@ func (m *Middleware) evalRequest(w http.ResponseWriter, r *http.Request, meta *m
}
var body string
if utils.IsTruthy(meta.ReadBody) {
if kitstrings.IsTruthy(meta.ReadBody) {
buf, _ := io.ReadAll(r.Body)
body = string(buf)

View File

@ -27,7 +27,7 @@ import (
"github.com/dapr/components-contrib/pubsub"
"github.com/dapr/kit/logger"
"github.com/dapr/kit/ptr"
"github.com/dapr/kit/utils"
"github.com/dapr/kit/strings"
)
// AzureEventHubs allows sending/receiving Azure Event Hubs events.
@ -129,7 +129,7 @@ func (aeh *AzureEventHubs) Subscribe(ctx context.Context, req pubsub.SubscribeRe
}
// Check if requireAllProperties is set and is truthy
getAllProperties := utils.IsTruthy(req.Metadata["requireAllProperties"])
getAllProperties := strings.IsTruthy(req.Metadata["requireAllProperties"])
if !getAllProperties {
getAllProperties = aeh.GetAllMessageProperties()
}
@ -158,7 +158,7 @@ func (aeh *AzureEventHubs) BulkSubscribe(ctx context.Context, req pubsub.Subscri
}
// Check if requireAllProperties is set and is truthy
getAllProperties := utils.IsTruthy(req.Metadata["requireAllProperties"])
getAllProperties := strings.IsTruthy(req.Metadata["requireAllProperties"])
if !getAllProperties {
getAllProperties = aeh.GetAllMessageProperties()
}

View File

@ -27,7 +27,7 @@ import (
"github.com/dapr/components-contrib/metadata"
"github.com/dapr/components-contrib/pubsub"
"github.com/dapr/kit/logger"
"github.com/dapr/kit/utils"
"github.com/dapr/kit/strings"
)
const (
@ -85,7 +85,7 @@ func (a *azureServiceBus) Subscribe(subscribeCtx context.Context, req pubsub.Sub
return errors.New("component is closed")
}
requireSessions := utils.IsTruthy(req.Metadata[impl.RequireSessionsMetadataKey])
requireSessions := strings.IsTruthy(req.Metadata[impl.RequireSessionsMetadataKey])
sessionIdleTimeout := time.Duration(commonutils.GetElemOrDefaultFromMap(req.Metadata, impl.SessionIdleTimeoutMetadataKey, impl.DefaultSesssionIdleTimeoutInSec)) * time.Second
maxConcurrentSessions := commonutils.GetElemOrDefaultFromMap(req.Metadata, impl.MaxConcurrentSessionsMetadataKey, impl.DefaultMaxConcurrentSessions)
@ -116,7 +116,7 @@ func (a *azureServiceBus) BulkSubscribe(subscribeCtx context.Context, req pubsub
return errors.New("component is closed")
}
requireSessions := utils.IsTruthy(req.Metadata[impl.RequireSessionsMetadataKey])
requireSessions := strings.IsTruthy(req.Metadata[impl.RequireSessionsMetadataKey])
sessionIdleTimeout := time.Duration(commonutils.GetElemOrDefaultFromMap(req.Metadata, impl.SessionIdleTimeoutMetadataKey, impl.DefaultSesssionIdleTimeoutInSec)) * time.Second
maxConcurrentSessions := commonutils.GetElemOrDefaultFromMap(req.Metadata, impl.MaxConcurrentSessionsMetadataKey, impl.DefaultMaxConcurrentSessions)

View File

@ -31,7 +31,7 @@ import (
"github.com/dapr/components-contrib/metadata"
"github.com/dapr/components-contrib/pubsub"
"github.com/dapr/kit/logger"
"github.com/dapr/kit/utils"
kitstrings "github.com/dapr/kit/strings"
)
const (
@ -139,7 +139,7 @@ func (m *mqttPubSub) Subscribe(ctx context.Context, req pubsub.SubscribeRequest,
if topic == "" {
return errors.New("topic name is empty")
}
unsubscribeOnClose := utils.IsTruthy(req.Metadata[unsubscribeOnCloseKey])
unsubscribeOnClose := kitstrings.IsTruthy(req.Metadata[unsubscribeOnCloseKey])
m.subscribingLock.Lock()
defer m.subscribingLock.Unlock()

View File

@ -31,7 +31,7 @@ import (
"github.com/dapr/components-contrib/metadata"
"github.com/dapr/components-contrib/pubsub"
"github.com/dapr/kit/logger"
"github.com/dapr/kit/utils"
kitstrings "github.com/dapr/kit/strings"
)
const (
@ -435,7 +435,7 @@ func (r *rabbitMQ) prepareSubscription(channel rabbitMQChannelBroker, req pubsub
}
// Applying x-single-active-consumer if defined at subscription level
if val := req.Metadata[reqMetadataSingleActiveConsumerKey]; utils.IsTruthy(val) {
if val := req.Metadata[reqMetadataSingleActiveConsumerKey]; kitstrings.IsTruthy(val) {
args[argSingleActiveConsumer] = true
}

View File

@ -34,7 +34,7 @@ import (
"github.com/dapr/components-contrib/metadata"
"github.com/dapr/components-contrib/pubsub"
"github.com/dapr/kit/logger"
"github.com/dapr/kit/utils"
kitstrings "github.com/dapr/kit/strings"
)
type daprQueueSelector struct {
@ -185,7 +185,7 @@ func (r *rocketMQ) setUpConsumer() (mq.PushConsumer, error) {
opts = append(opts, mqc.WithConsumeTimestamp(r.metadata.ConsumeTimestamp))
}
if r.metadata.ConsumeOrderly != "" {
if utils.IsTruthy(r.metadata.ConsumeOrderly) {
if kitstrings.IsTruthy(r.metadata.ConsumeOrderly) {
opts = append(opts, mqc.WithConsumerOrder(true))
// in orderly message mode, if no value is set of MessageBatchMaxSize, the recommended value [1] is used
if r.metadata.ConsumeMessageBatchMaxSize <= 0 {
@ -205,7 +205,7 @@ func (r *rocketMQ) setUpConsumer() (mq.PushConsumer, error) {
opts = append(opts, mqc.WithMaxReconsumeTimes(r.metadata.MaxReconsumeTimes))
}
if r.metadata.AutoCommit != "" {
opts = append(opts, mqc.WithAutoCommit(utils.IsTruthy(r.metadata.AutoCommit)))
opts = append(opts, mqc.WithAutoCommit(kitstrings.IsTruthy(r.metadata.AutoCommit)))
}
if r.metadata.ConsumeTimeout > 0 {
opts = append(opts, mqc.WithConsumeTimeout(time.Duration(r.metadata.ConsumeTimeout)*time.Minute))
@ -386,7 +386,7 @@ func (r *rocketMQ) Subscribe(ctx context.Context, req pubsub.SubscribeRequest, h
}
var cb func(ctx context.Context, msgs ...*primitive.MessageExt) (mqc.ConsumeResult, error)
if utils.IsTruthy(r.metadata.ConsumeOrderly) {
if kitstrings.IsTruthy(r.metadata.ConsumeOrderly) {
cb = r.consumeMessageOrderly(req.Topic, selector, handler)
} else {
cb = r.consumeMessageConcurrently(req.Topic, selector, handler)

View File

@ -32,7 +32,7 @@ import (
"github.com/dapr/kit/logger"
kitmd "github.com/dapr/kit/metadata"
"github.com/dapr/kit/ptr"
"github.com/dapr/kit/utils"
kitstrings "github.com/dapr/kit/strings"
)
// Etcd is a state store implementation for Etcd.
@ -109,7 +109,7 @@ func (e *Etcd) ParseClientFromConfig(etcdConfig *etcdConfig) (*clientv3.Client,
}
var tlsConfig *tls.Config
if utils.IsTruthy(etcdConfig.TLSEnable) {
if kitstrings.IsTruthy(etcdConfig.TLSEnable) {
if etcdConfig.Cert != "" && etcdConfig.Key != "" && etcdConfig.CA != "" {
var err error
tlsConfig, err = NewTLSConfig(etcdConfig.Cert, etcdConfig.Key, etcdConfig.CA)

View File

@ -27,7 +27,7 @@ import (
"github.com/dapr/components-contrib/metadata"
"github.com/dapr/components-contrib/state"
"github.com/dapr/kit/logger"
"github.com/dapr/kit/utils"
"github.com/dapr/kit/strings"
)
// go test -timeout 30s github.com/dapr/components-contrib/state/rethinkdb -count 1 -run ^TestGetRethinkDBMetadata$.
@ -229,7 +229,7 @@ func testGetTestObj(t *testing.T, resp *state.GetResponse) *testObj {
}
func isLiveTest() bool {
return utils.IsTruthy(os.Getenv("RUN_LIVE_RETHINKDB_TEST"))
return strings.IsTruthy(os.Getenv("RUN_LIVE_RETHINKDB_TEST"))
}
func getTestMetadata() map[string]string {

View File

@ -15,7 +15,7 @@ import (
"github.com/dapr/components-contrib/metadata"
"github.com/dapr/components-contrib/tests/utils/configupdater"
"github.com/dapr/kit/logger"
"github.com/dapr/kit/utils"
kitstrings "github.com/dapr/kit/strings"
)
type ConfigUpdater struct {
@ -92,8 +92,8 @@ func (r *ConfigUpdater) Init(props map[string]string) error {
md := pgauth.PostgresAuthMetadata{
ConnectionString: connString,
UseAzureAD: utils.IsTruthy(useAzureAd),
UseAWSIAM: utils.IsTruthy(useAwsIam),
UseAzureAD: kitstrings.IsTruthy(useAzureAd),
UseAWSIAM: kitstrings.IsTruthy(useAwsIam),
}
err := md.InitWithMetadata(props, pgauth.InitWithMetadataOpts{AzureADEnabled: true, AWSIAMEnabled: true})
if err != nil {