Consul is a distributed, highly available, and data center aware solution to connect and configure applications across dynamic, distributed infrastructure.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

61 lines
1.4 KiB

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package external
import (
"context"
"fmt"
"github.com/hashicorp/consul/agent/structs"
"github.com/mitchellh/mapstructure"
"google.golang.org/grpc/metadata"
)
// QueryOptionsFromContext returns the query options in the gRPC metadata attached to the
// given context.
func QueryOptionsFromContext(ctx context.Context) (structs.QueryOptions, error) {
options := structs.QueryOptions{}
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return options, nil
}
m := map[string]string{}
for k, v := range md {
m[k] = v[0]
}
config := &mapstructure.DecoderConfig{
Metadata: nil,
Result: &options,
WeaklyTypedInput: true,
DecodeHook: mapstructure.StringToTimeDurationHookFunc(),
}
decoder, err := mapstructure.NewDecoder(config)
if err != nil {
return structs.QueryOptions{}, err
}
err = decoder.Decode(m)
if err != nil {
return structs.QueryOptions{}, err
}
return options, nil
}
// ContextWithQueryOptions returns a context with the given query options attached.
func ContextWithQueryOptions(ctx context.Context, options structs.QueryOptions) (context.Context, error) {
md := metadata.MD{}
m := map[string]interface{}{}
err := mapstructure.Decode(options, &m)
if err != nil {
return nil, err
}
for k, v := range m {
md.Set(k, fmt.Sprintf("%v", v))
}
return metadata.NewOutgoingContext(ctx, md), nil
}