2023-03-28 22:48:58 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
2023-08-11 13:12:13 +00:00
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
2023-03-28 22:48:58 +00:00
|
|
|
|
2020-07-23 15:24:20 +00:00
|
|
|
package pbcommon
|
2019-09-20 18:37:22 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
2021-06-28 20:25:49 +00:00
|
|
|
|
|
|
|
"github.com/hashicorp/consul/agent/structs"
|
2023-01-11 14:39:10 +00:00
|
|
|
durationpb "google.golang.org/protobuf/types/known/durationpb"
|
2019-09-20 18:37:22 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// IsRead is always true for QueryOption
|
|
|
|
func (q *QueryOptions) IsRead() bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// AllowStaleRead returns whether a stale read should be allowed
|
|
|
|
func (q *QueryOptions) AllowStaleRead() bool {
|
|
|
|
return q.AllowStale
|
|
|
|
}
|
|
|
|
|
|
|
|
func (q *QueryOptions) TokenSecret() string {
|
|
|
|
return q.Token
|
|
|
|
}
|
|
|
|
|
2020-03-10 16:15:22 +00:00
|
|
|
func (q *QueryOptions) SetTokenSecret(s string) {
|
|
|
|
q.Token = s
|
|
|
|
}
|
|
|
|
|
2019-09-26 13:55:02 +00:00
|
|
|
// SetToken is needed to implement the structs.QueryOptionsCompat interface
|
|
|
|
func (q *QueryOptions) SetToken(token string) {
|
|
|
|
q.Token = token
|
2019-09-20 18:37:22 +00:00
|
|
|
}
|
|
|
|
|
2019-09-26 13:55:02 +00:00
|
|
|
// SetMinQueryIndex is needed to implement the structs.QueryOptionsCompat interface
|
|
|
|
func (q *QueryOptions) SetMinQueryIndex(minQueryIndex uint64) {
|
|
|
|
q.MinQueryIndex = minQueryIndex
|
2019-09-20 18:37:22 +00:00
|
|
|
}
|
|
|
|
|
2019-09-26 13:55:02 +00:00
|
|
|
// SetMaxQueryTime is needed to implement the structs.QueryOptionsCompat interface
|
|
|
|
func (q *QueryOptions) SetMaxQueryTime(maxQueryTime time.Duration) {
|
2023-01-11 14:39:10 +00:00
|
|
|
q.MaxQueryTime = durationpb.New(maxQueryTime)
|
2019-09-20 18:37:22 +00:00
|
|
|
}
|
|
|
|
|
2019-09-26 13:55:02 +00:00
|
|
|
// SetAllowStale is needed to implement the structs.QueryOptionsCompat interface
|
|
|
|
func (q *QueryOptions) SetAllowStale(allowStale bool) {
|
|
|
|
q.AllowStale = allowStale
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetRequireConsistent is needed to implement the structs.QueryOptionsCompat interface
|
|
|
|
func (q *QueryOptions) SetRequireConsistent(requireConsistent bool) {
|
|
|
|
q.RequireConsistent = requireConsistent
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetUseCache is needed to implement the structs.QueryOptionsCompat interface
|
|
|
|
func (q *QueryOptions) SetUseCache(useCache bool) {
|
|
|
|
q.UseCache = useCache
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetMaxStaleDuration is needed to implement the structs.QueryOptionsCompat interface
|
|
|
|
func (q *QueryOptions) SetMaxStaleDuration(maxStaleDuration time.Duration) {
|
2023-01-11 14:39:10 +00:00
|
|
|
q.MaxStaleDuration = durationpb.New(maxStaleDuration)
|
2019-09-26 13:55:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetMaxAge is needed to implement the structs.QueryOptionsCompat interface
|
|
|
|
func (q *QueryOptions) SetMaxAge(maxAge time.Duration) {
|
2023-01-11 14:39:10 +00:00
|
|
|
q.MaxAge = durationpb.New(maxAge)
|
2019-09-26 13:55:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetMustRevalidate is needed to implement the structs.QueryOptionsCompat interface
|
|
|
|
func (q *QueryOptions) SetMustRevalidate(mustRevalidate bool) {
|
|
|
|
q.MustRevalidate = mustRevalidate
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetStaleIfError is needed to implement the structs.QueryOptionsCompat interface
|
|
|
|
func (q *QueryOptions) SetStaleIfError(staleIfError time.Duration) {
|
2023-01-11 14:39:10 +00:00
|
|
|
q.StaleIfError = durationpb.New(staleIfError)
|
2019-09-26 13:55:02 +00:00
|
|
|
}
|
|
|
|
|
2022-03-30 16:51:56 +00:00
|
|
|
func (q *QueryOptions) HasTimedOut(start time.Time, rpcHoldTimeout, maxQueryTime, defaultQueryTime time.Duration) (bool, error) {
|
2022-10-18 19:05:09 +00:00
|
|
|
// In addition to BlockingTimeout, allow for an additional rpcHoldTimeout buffer
|
|
|
|
// in case we need to wait for a leader election.
|
|
|
|
return time.Since(start) > rpcHoldTimeout+q.BlockingTimeout(maxQueryTime, defaultQueryTime), nil
|
2022-04-21 20:21:35 +00:00
|
|
|
}
|
|
|
|
|
2022-10-18 19:05:09 +00:00
|
|
|
// BlockingTimeout implements pool.BlockableQuery
|
|
|
|
func (q *QueryOptions) BlockingTimeout(maxQueryTime, defaultQueryTime time.Duration) time.Duration {
|
2023-01-11 14:39:10 +00:00
|
|
|
maxTime := q.MaxQueryTime.AsDuration()
|
2021-07-22 18:58:08 +00:00
|
|
|
o := structs.QueryOptions{
|
2022-03-16 16:12:29 +00:00
|
|
|
MaxQueryTime: maxTime,
|
2021-07-22 18:58:08 +00:00
|
|
|
MinQueryIndex: q.MinQueryIndex,
|
|
|
|
}
|
2022-10-18 19:05:09 +00:00
|
|
|
return o.BlockingTimeout(maxQueryTime, defaultQueryTime)
|
2021-07-22 18:58:08 +00:00
|
|
|
}
|
|
|
|
|
2019-09-26 13:55:02 +00:00
|
|
|
// SetFilter is needed to implement the structs.QueryOptionsCompat interface
|
|
|
|
func (q *QueryOptions) SetFilter(filter string) {
|
|
|
|
q.Filter = filter
|
|
|
|
}
|
|
|
|
|
2019-09-20 18:37:22 +00:00
|
|
|
// WriteRequest only applies to writes, always false
|
2021-09-22 18:14:26 +00:00
|
|
|
//
|
|
|
|
// IsRead implements structs.RPCInfo
|
2022-03-30 16:51:56 +00:00
|
|
|
func (w *WriteRequest) IsRead() bool {
|
2019-09-20 18:37:22 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2021-09-22 18:14:26 +00:00
|
|
|
// SetTokenSecret implements structs.RPCInfo
|
2022-03-30 16:51:56 +00:00
|
|
|
func (w *WriteRequest) TokenSecret() string {
|
2019-09-26 13:55:02 +00:00
|
|
|
return w.Token
|
|
|
|
}
|
|
|
|
|
2021-09-22 18:14:26 +00:00
|
|
|
// SetTokenSecret implements structs.RPCInfo
|
2020-03-10 16:15:22 +00:00
|
|
|
func (w *WriteRequest) SetTokenSecret(s string) {
|
|
|
|
w.Token = s
|
|
|
|
}
|
|
|
|
|
2019-09-20 18:37:22 +00:00
|
|
|
// AllowStaleRead returns whether a stale read should be allowed
|
2021-09-22 18:14:26 +00:00
|
|
|
//
|
|
|
|
// AllowStaleRead implements structs.RPCInfo
|
2022-03-30 16:51:56 +00:00
|
|
|
func (w *WriteRequest) AllowStaleRead() bool {
|
2019-09-20 18:37:22 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2021-09-22 18:14:26 +00:00
|
|
|
// HasTimedOut implements structs.RPCInfo
|
2022-04-21 20:21:35 +00:00
|
|
|
func (w *WriteRequest) HasTimedOut(start time.Time, rpcHoldTimeout, maxQueryTime, defaultQueryTime time.Duration) (bool, error) {
|
2022-10-18 19:05:09 +00:00
|
|
|
return time.Since(start) > rpcHoldTimeout, nil
|
2021-07-22 18:58:08 +00:00
|
|
|
}
|
|
|
|
|
2021-09-22 18:14:26 +00:00
|
|
|
// IsRead implements structs.RPCInfo
|
|
|
|
func (r *ReadRequest) IsRead() bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// AllowStaleRead implements structs.RPCInfo
|
|
|
|
func (r *ReadRequest) AllowStaleRead() bool {
|
|
|
|
// TODO(partitions): plumb this?
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// TokenSecret implements structs.RPCInfo
|
|
|
|
func (r *ReadRequest) TokenSecret() string {
|
|
|
|
return r.Token
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetTokenSecret implements structs.RPCInfo
|
|
|
|
func (r *ReadRequest) SetTokenSecret(token string) {
|
|
|
|
r.Token = token
|
|
|
|
}
|
|
|
|
|
|
|
|
// HasTimedOut implements structs.RPCInfo
|
2022-10-18 19:05:09 +00:00
|
|
|
func (r *ReadRequest) HasTimedOut(start time.Time, rpcHoldTimeout, _, _ time.Duration) (bool, error) {
|
|
|
|
return time.Since(start) > rpcHoldTimeout, nil
|
2021-09-22 18:14:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// RequestDatacenter implements structs.RPCInfo
|
2022-03-30 16:51:56 +00:00
|
|
|
func (td *TargetDatacenter) RequestDatacenter() string {
|
2019-09-20 18:37:22 +00:00
|
|
|
return td.Datacenter
|
|
|
|
}
|
2022-03-28 17:56:44 +00:00
|
|
|
|
|
|
|
// SetLastContact is needed to implement the structs.QueryMetaCompat interface
|
|
|
|
func (q *QueryMeta) SetLastContact(lastContact time.Duration) {
|
2023-01-11 14:39:10 +00:00
|
|
|
q.LastContact = durationpb.New(lastContact)
|
2022-03-28 17:56:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetKnownLeader is needed to implement the structs.QueryMetaCompat interface
|
|
|
|
func (q *QueryMeta) SetKnownLeader(knownLeader bool) {
|
|
|
|
q.KnownLeader = knownLeader
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetIndex is needed to implement the structs.QueryMetaCompat interface
|
|
|
|
func (q *QueryMeta) SetIndex(index uint64) {
|
|
|
|
q.Index = index
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetConsistencyLevel is needed to implement the structs.QueryMetaCompat interface
|
|
|
|
func (q *QueryMeta) SetConsistencyLevel(consistencyLevel string) {
|
|
|
|
q.ConsistencyLevel = consistencyLevel
|
|
|
|
}
|
|
|
|
|
|
|
|
func (q *QueryMeta) GetBackend() structs.QueryBackend {
|
|
|
|
return structs.QueryBackend(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetResultsFilteredByACLs is needed to implement the structs.QueryMetaCompat interface
|
|
|
|
func (q *QueryMeta) SetResultsFilteredByACLs(v bool) {
|
|
|
|
q.ResultsFilteredByACLs = v
|
|
|
|
}
|
2023-03-10 14:36:15 +00:00
|
|
|
|
|
|
|
// IsEmpty returns true if the Locality is unset or contains an empty region and zone.
|
|
|
|
func (l *Locality) IsEmpty() bool {
|
|
|
|
if l == nil {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return l.Region == "" && l.Zone == ""
|
|
|
|
}
|
|
|
|
|
|
|
|
// LocalityFromProto converts a protobuf Locality to a struct Locality.
|
|
|
|
func LocalityFromProto(l *Locality) *structs.Locality {
|
|
|
|
if l == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return &structs.Locality{
|
|
|
|
Region: l.Region,
|
|
|
|
Zone: l.Zone,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// LocalityFromProto converts a struct Locality to a protobuf Locality.
|
|
|
|
func LocalityToProto(l *structs.Locality) *Locality {
|
|
|
|
if l == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return &Locality{
|
|
|
|
Region: l.Region,
|
|
|
|
Zone: l.Zone,
|
|
|
|
}
|
|
|
|
}
|