diff --git a/.github/workflows/test-signalflow.yml b/.github/workflows/test-signalflow.yml
new file mode 100644
index 0000000..cf80758
--- /dev/null
+++ b/.github/workflows/test-signalflow.yml
@@ -0,0 +1,44 @@
+name: build-and-test-signalflow
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ paths:
+ - 'signalflow/**'
+
+jobs:
+ test-signalflow-package:
+ runs-on: ubuntu-22.04
+ strategy:
+ matrix:
+ GO_VERSION: [ "1.19", "1.20" ]
+ steps:
+ - name: Check out the codebase.
+ uses: actions/checkout@v3
+
+ - name: Set up Go
+ uses: actions/setup-go@v4
+ with:
+ go-version: ${{ matrix.GO_VERSION }}
+
+ - name: Caching dependency
+ uses: actions/cache@v3
+ with:
+ path: |
+ ~/.cache/go-build
+ ~/go/pkg/mod
+ ~/go/bin
+ key: ${{ runner.os }}-go-${{ hashFiles('signalflow/go.sum') }}
+
+ - name: golangci-lint
+ uses: golangci/golangci-lint-action@v3
+ with:
+ version: v1.52.2
+ working-directory: signalflow
+
+ - name: Run signalfx-go tests
+ run: |
+ cd signalflow
+ go mod download
+ go test -cover -race ./... -parallel 4 -timeout 5m
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 7442a22..eb02746 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -1,17 +1,18 @@
name: build-and-test
-
on:
push:
branches:
- main
pull_request:
+ paths_ignore:
+ - 'signalflow/**'
jobs:
- test:
+ test-main-package:
runs-on: ubuntu-20.04
strategy:
matrix:
- GO_VERSION: [ "1.17" ]
+ GO_VERSION: [ "1.17", "1.20" ]
steps:
- name: Check out the codebase.
uses: actions/checkout@v3
@@ -28,13 +29,13 @@ jobs:
~/.cache/go-build
~/go/pkg/mod
~/go/bin
- key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
+ key: ${{ runner.os }}-go-${{ hashFiles('go.sum') }}
- - name: Run tests
+ - name: Run signalfx-go tests
run: |
go mod download
# Used for code generation
go install github.com/mauricelam/genny
go install golang.org/x/tools/cmd/goimports
go generate ./...
- go test ./... -parallel 4 -timeout 2m
\ No newline at end of file
+ go test ./... -parallel 4 -timeout 4m
diff --git a/aws_cloudwatch_integration_test.go b/aws_cloudwatch_integration_test.go
index a85373e..fbb5e98 100644
--- a/aws_cloudwatch_integration_test.go
+++ b/aws_cloudwatch_integration_test.go
@@ -40,11 +40,21 @@ func TestUpdateAWSCloudWatchIntegration(t *testing.T) {
mux.HandleFunc("/v2/integration/id", verifyRequest(t, "PUT", true, http.StatusOK, nil, "integration/create_aws_success.json"))
- result, err := client.UpdateAWSCloudWatchIntegration(context.Background(), "id", &integration.AwsCloudWatchIntegration{
- Type: "AWSCloudWatch",
- })
+ cwIntegration := integration.AwsCloudWatchIntegration{
+ NamespaceSyncRules: []*integration.AwsNameSpaceSyncRule{
+ {
+ Namespace: "AWS/SomeNewNamespace",
+ },
+ },
+ Services: []integration.AwsService{"AWS/AnotherNewNamespace"},
+ Type: "AWSCloudWatch",
+ }
+ result, err := client.UpdateAWSCloudWatchIntegration(context.Background(), "id", &cwIntegration)
assert.NoError(t, err, "Unexpected error creating integration")
assert.Equal(t, "string", result.Name, "Name does not match")
+ assert.Equal(t, integration.AwsService("AWS/SomeNewNamespace"), result.NamespaceSyncRules[0].Namespace,
+ "NamespaceSyncRules[0].Namespace does not match")
+ assert.Equal(t, integration.AwsService("AWS/AnotherNewNamespace"), result.Services[0], "Services[0] does not match")
}
func TestUpdateAWSCloudWatchIntegrationMetricStatsToSync(t *testing.T) {
diff --git a/client.go b/client.go
index 1300ec2..375fb4d 100644
--- a/client.go
+++ b/client.go
@@ -7,8 +7,6 @@ import (
"net/url"
stdpath "path"
"time"
-
- "github.com/signalfx/signalfx-go/signalflow"
)
// DefaultAPIURL is the default URL for making API requests
@@ -104,10 +102,3 @@ func (c *Client) doRequestWithToken(ctx context.Context, method string, path str
return c.httpClient.Do(req)
}
-
-// SignalFlow creates and returns a SignalFlow client that can be used to
-// execute streaming jobs.
-func (c *Client) SignalFlow(options ...signalflow.ClientParam) (*signalflow.Client, error) {
- options = append(options, signalflow.AccessToken(c.authToken))
- return signalflow.NewClient(options...)
-}
diff --git a/go.mod b/go.mod
index 0ba89b0..b6d591b 100644
--- a/go.mod
+++ b/go.mod
@@ -1,12 +1,39 @@
module github.com/signalfx/signalfx-go
-go 1.12
+go 1.17
require (
github.com/davecgh/go-spew v1.1.1
- github.com/gorilla/websocket v1.4.2
github.com/mauricelam/genny v0.0.0-20190320071652-0800202903e5
- github.com/signalfx/golib/v3 v3.3.37
- github.com/stretchr/testify v1.6.1
- golang.org/x/tools v0.0.0-20190906203814-12febf440ab1
+ github.com/signalfx/golib/v3 v3.3.47
+ github.com/stretchr/testify v1.8.2
+ golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5
+ golang.org/x/tools v0.1.5
+)
+
+require (
+ github.com/go-logfmt/logfmt v0.5.1 // indirect
+ github.com/go-stack/stack v1.8.1 // indirect
+ github.com/gogo/protobuf v1.3.2 // indirect
+ github.com/golang/protobuf v1.5.2 // indirect
+ github.com/jaegertracing/jaeger v1.38.0 // indirect
+ github.com/josharian/intern v1.0.0 // indirect
+ github.com/mailru/easyjson v0.7.7 // indirect
+ github.com/opentracing/opentracing-go v1.2.0 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/signalfx/com_signalfx_metrics_protobuf v0.0.3 // indirect
+ github.com/signalfx/gohistogram v0.0.0-20160107210732-1ccfd2ff5083 // indirect
+ github.com/signalfx/sapm-proto v0.7.2 // indirect
+ github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
+ github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
+ go.uber.org/atomic v1.9.0 // indirect
+ go.uber.org/multierr v1.8.0 // indirect
+ go.uber.org/zap v1.22.0 // indirect
+ golang.org/x/mod v0.4.2 // indirect
+ golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 // indirect
+ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
+ golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect
+ google.golang.org/appengine v1.6.7 // indirect
+ google.golang.org/protobuf v1.28.1 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
index 6255b97..529b762 100644
--- a/go.sum
+++ b/go.sum
@@ -1,174 +1,1926 @@
+4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
+cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
+cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
+cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
+cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
+cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
+cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
+cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
+cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
+cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
+cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
+cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
+cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
+cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
+cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
+cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
+cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
+cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
+cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
+cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
+cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
+cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
+cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
+cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
+cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
+cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
+cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
+cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
+cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
+cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
+cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
+cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
+cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
+cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
+cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
+cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
+cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
+cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
+cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY=
+cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
+cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
+cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
+cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
+cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
+cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
+cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
+cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
+cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
+cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
+code.cloudfoundry.org/bytefmt v0.0.0-20190710193110-1eb035ffe2b6/go.mod h1:wN/zk7mhREp/oviagqUXY3EwuHhWyOvAdsn5Y4CzOrc=
+contrib.go.opencensus.io/exporter/prometheus v0.4.1/go.mod h1:t9wvfitlUjGXG2IXAZsuFq26mDGid/JwCEXp+gTG/9U=
+dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
+github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
+github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
+github.com/DataDog/zstd v1.4.4/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
+github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
+github.com/HdrHistogram/hdrhistogram-go v0.9.0/go.mod h1:nxrse8/Tzg2tg3DZcZjm6qEclQKK70g0KxO61gFFZD4=
+github.com/HdrHistogram/hdrhistogram-go v1.0.1/go.mod h1:BWJ+nMSHY3L41Zj7CA3uXnloDp7xxV0YvstAE7nKTaM=
+github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
+github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM=
+github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
+github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
+github.com/Shopify/sarama v1.22.2-0.20190604114437-cd910a683f9f/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs=
+github.com/Shopify/sarama v1.32.0/go.mod h1:+EmJJKZWVT/faR9RcOxJerP+LId4iWdQPBGLy1Y1Njs=
+github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
+github.com/Shopify/toxiproxy/v2 v2.3.0/go.mod h1:KvQTtB6RjCJY4zqNJn7C7JDFgsG5uoHYDirfUfpIm0c=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
-github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
+github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
+github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
+github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
+github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
+github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
+github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
+github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
+github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
+github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
+github.com/antonmedv/expr v1.9.0/go.mod h1:5qsM3oLGDND7sDmQGDXHkYfkjYMUX14qsgqmHhwGEk8=
+github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=
+github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
+github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
+github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
+github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
+github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
+github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
+github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
+github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
+github.com/ashanbrown/forbidigo v1.1.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI=
+github.com/ashanbrown/makezero v0.0.0-20201205152432-7b7cdbb3025a/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU=
+github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
+github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go v1.38.68/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
+github.com/aws/aws-sdk-go v1.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
+github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
+github.com/aws/aws-sdk-go-v2 v1.7.0/go.mod h1:tb9wi5s61kTDA5qCkcDbt3KRVV74GGslQkl/DRdX/P4=
+github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
+github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
+github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw=
+github.com/aws/aws-sdk-go-v2/credentials v1.4.3/go.mod h1:FNNC6nQZQUuyhq5aE5c7ata8o9e4ECGmS4lAXC7o1mQ=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.6.0/go.mod h1:gqlclDEZp4aqJOancXK6TN24aKhT0W0Ae9MHk3wzTMM=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.2.4/go.mod h1:ZcBrrI3zBKlhGFNYWvju0I3TR93I7YIgAfy82Fh4lcQ=
+github.com/aws/aws-sdk-go-v2/service/appconfig v1.4.2/go.mod h1:FZ3HkCe+b10uFZZkFdvf98LHW21k49W8o8J366lqVKY=
+github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.5.0/go.mod h1:acH3+MQoiMzozT/ivU+DbRg7Ooo2298RdRaWcOv+4vM=
+github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.2/go.mod h1:72HRZDLMtmVQiLG2tLfQcaWLCssELvGl+Zf2WVxMmR8=
+github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+IkPchKS7p7c2YPKwHmBOk=
+github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g=
+github.com/aws/smithy-go v1.5.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
+github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
+github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
+github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
+github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
+github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
+github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
+github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI=
+github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
+github.com/bombsimon/wsl/v3 v3.2.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc=
+github.com/bsm/sarama-cluster v2.1.13+incompatible/go.mod h1:r7ao+4tTNXvWm+VRpRJchr2kQhqxgmAp2iEX5W96gMM=
+github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
+github.com/casbin/casbin/v2 v2.31.6/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
+github.com/casbin/casbin/v2 v2.37.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
+github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
+github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
+github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/charithe/durationcheck v0.0.6/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg=
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
+github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
+github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
+github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
+github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
+github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
+github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
+github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
+github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
+github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/crossdock/crossdock-go v0.0.0-20160816171116-049aabb0122b/go.mod h1:v9FBN7gdVTpiD/+LZ7Po0UKvROyT87uLVxTHVky/dlQ=
+github.com/daixiang0/gci v0.2.8/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc=
+github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA=
+github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE=
+github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M=
+github.com/dgraph-io/ristretto v0.0.1/go.mod h1:T40EBc7CJke8TkpiYfGGKAeFjSaxuFXhuXRyumBd6RE=
+github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
+github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
+github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dropbox/godropbox v0.0.0-20180512210157-31879d3884b9 h1:NAvZb7gqQfLSNBPzVsvI7eZMosXtg2g2kxXrei90CtU=
github.com/dropbox/godropbox v0.0.0-20180512210157-31879d3884b9/go.mod h1:glr97hP/JuXb+WMYCizc4PIFuzw1lCR97mwbe1VVXhQ=
+github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
+github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
+github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
+github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
+github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/esimonov/ifshort v1.0.1/go.mod h1:yZqNJUrNn20K8Q9n2CrjTKYyVEmX209Hgu+M1LBpeZE=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
github.com/facebookgo/stackerr v0.0.0-20150612192056-c2fcf88613f4 h1:fP04zlkPjAGpsduG7xN3rRkxjAqkJaIQnnkNYYw/pAk=
github.com/facebookgo/stackerr v0.0.0-20150612192056-c2fcf88613f4/go.mod h1:SBHk9aNQtiw4R4bEuzHjVmZikkUKCnO1v3lPQ21HZGk=
-github.com/go-kit/kit v0.7.0 h1:ApufNmWF1H6/wUbAG81hZOHmqwd0zRf8mNfLjYj/064=
-github.com/go-kit/kit v0.7.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
+github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
+github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
+github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
+github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
+github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
+github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
+github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
+github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
+github.com/franela/goblin v0.0.0-20210519012713-85d372ac71e2/go.mod h1:VzmDKDJVZI3aJmnRI9VjAn9nJ8qPPsN1fqzr9dqInIo=
+github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
+github.com/frankban/quicktest v1.4.0/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ=
+github.com/frankban/quicktest v1.7.3/go.mod h1:V1d2J5pfxYH6EjBAgSK7YNXcXlTWxUHdE1sVDXkjnig=
+github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og=
+github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
+github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
+github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
+github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E=
+github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
+github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
+github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
+github.com/go-critic/go-critic v0.5.4/go.mod h1:cjB4YGw+n/+X8gREApej7150Uyy1Tg8If6F2XOAUXNE=
+github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-logfmt/logfmt v0.3.0 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2ic=
+github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
+github.com/go-kit/kit v0.11.0/go.mod h1:73/6Ixaufkvb5Osvkls8C79vuQ49Ba1rUEUYNSf+FUw=
+github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4=
+github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs=
+github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
+github.com/go-kit/log v0.2.0 h1:7i2K3eKTos3Vc0enKCfnVcgHh2olr/MyfboYq7cAcFw=
+github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
+github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
-github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
-github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
+github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
+github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
+github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
-github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
+github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
+github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
+github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
+github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
+github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
+github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
+github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
+github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ=
+github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY=
+github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
+github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
+github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
+github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
+github.com/go-openapi/errors v0.19.4/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
+github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
+github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
+github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
+github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
+github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
+github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
+github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
+github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
+github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
+github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
+github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
+github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
+github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
+github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
+github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
+github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
+github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
+github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI=
+github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk=
+github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY=
+github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g=
+github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
+github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
+github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
+github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo=
+github.com/go-openapi/runtime v0.23.3/go.mod h1:AKurw9fNre+h3ELZfk6ILsfvPN+bvvlaU/M9q/r9hpk=
+github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
+github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
+github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
+github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
+github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
+github.com/go-openapi/spec v0.20.2/go.mod h1:RW6Xcbs6LOyWLU/mXGdzn2Qc+3aj+ASfI7rvSZh1Vls=
+github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
+github.com/go-openapi/spec v0.20.5/go.mod h1:QbfOSIVt3/sac+a1wzmKbbcLXm5NdZnyBZYtCijp43o=
+github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
+github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
+github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
+github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
+github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
+github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
+github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
+github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
+github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg=
+github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k=
+github.com/go-openapi/strfmt v0.21.2/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k=
+github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg=
+github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
+github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
+github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
+github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
+github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
+github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
+github.com/go-openapi/swag v0.22.1/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
+github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
+github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
+github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
+github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
+github.com/go-openapi/validate v0.21.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg=
+github.com/go-openapi/validate v0.22.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg=
+github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/gogo/googleapis v1.3.1 h1:CzMaKrvF6Qa7XtRii064vKBQiyvmY8H8vG1xa1/W1JA=
-github.com/gogo/googleapis v1.3.1/go.mod h1:d+q1s/xVJxZGKWwC/6UfPIF33J+G1Tq4GYv9Y+Tg/EU=
-github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
-github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
-github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
+github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
+github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
+github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
+github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
+github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
+github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ=
+github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
+github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw=
+github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU=
+github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI=
+github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc=
+github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
+github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
+github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
+github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
+github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
+github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
+github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
+github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
+github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
+github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
+github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
+github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
+github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
+github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
+github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
+github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
+github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
+github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
+github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
+github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
+github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
+github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
+github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
+github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
+github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
+github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
+github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
+github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
+github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
+github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
+github.com/gocql/gocql v0.0.0-20200228163523-cd4b606dd2fb/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY=
+github.com/gocql/gocql v0.0.0-20211222173705-d73e6b1002a7/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8=
+github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
+github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
+github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
+github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
+github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
+github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
-github.com/google/addlicense v0.0.0-20190510175307-22550fa7c1b0/go.mod h1:QtPG26W17m+OIQgE6gQ24gC1M6pUaMBAbFrTIDtwG/E=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
+github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4=
+github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
+github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8=
+github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU=
+github.com/golangci/golangci-lint v1.38.0/go.mod h1:Knp/sd5ATrVp7EOzWzwIIFH+c8hUfpW+oOQb8NvdZDo=
+github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg=
+github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o=
+github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA=
+github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY=
+github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
+github.com/google/addlicense v0.0.0-20200906110928-a0294312aa76/go.mod h1:EMjYTRimagHs1FwlIqKyX3wAM0u3rA+McvlIIWmSamA=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
+github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
+github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
+github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
+github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
+github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
+github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
+github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
+github.com/gookit/color v1.3.6/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
-github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
+github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254/go.mod h1:M9mZEtGIsR1oDaZagNPNG9iq9n2HrhZ17dsXk73V3Lw=
+github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
+github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
+github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
+github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
-github.com/jaegertracing/jaeger v1.15.1 h1:7QzNAXq+4ko9GtCjozDNAp2uonoABu+B2Rk94hjQcp4=
-github.com/jaegertracing/jaeger v1.15.1/go.mod h1:LUWPSnzNPGRubM8pk0inANGitpiMOOxihXx0+53llXI=
+github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
+github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
+github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw=
+github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0=
+github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI=
+github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado=
+github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak=
+github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
+github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.14.5/go.mod h1:UJ0EZAp832vCd54Wev9N1BMKEyvcZ5+IM0AwDrnlkEc=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
+github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
+github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
+github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
+github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
+github.com/hashicorp/consul/api v1.8.1/go.mod h1:sDjTOq0yUyv5G4h+BqSea7Fn6BU+XbolEz1952UB+mk=
+github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
+github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
+github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/consul/sdk v0.7.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM=
+github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
+github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
+github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
+github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
+github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
+github.com/hashicorp/go-hclog v0.15.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
+github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
+github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
+github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
+github.com/hashicorp/go-hclog v1.2.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
+github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
+github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
+github.com/hashicorp/go-plugin v1.4.0/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ=
+github.com/hashicorp/go-plugin v1.4.3/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ=
+github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
+github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
+github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
+github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
+github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
+github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
+github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
+github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
+github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
+github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
+github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
+github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
+github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
+github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
+github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
+github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
+github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
+github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
+github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
+github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
+github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q=
+github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
+github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
+github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
+github.com/hashicorp/yamux v0.0.0-20190923154419-df201c70410d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
+github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo=
+github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
+github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
+github.com/jaegertracing/jaeger v1.22.0/go.mod h1:WnwW68MjJEViSLRQhe0nkIsBDaF3CzfFd8wJcpJv24k=
+github.com/jaegertracing/jaeger v1.34.1/go.mod h1:md+YcRcDgMCAgB9qyXl0PdstYiq8fjA8KG5cNuyV2kA=
+github.com/jaegertracing/jaeger v1.35.2/go.mod h1:e7FBVZ14ptsRjwiHEnLyxvOa4bSnZA0BDFE1OcvNiHs=
+github.com/jaegertracing/jaeger v1.36.0/go.mod h1:67uyR2zQgEk7EfguOR3eZOGvGDRzY5Yos6n2aaXxq1Y=
+github.com/jaegertracing/jaeger v1.38.0 h1:rDQ36TnSxUX4gTskMQzEdpieS0BGYdfXXnUJmGnNMGw=
+github.com/jaegertracing/jaeger v1.38.0/go.mod h1:4MBTMxfCp3d4buDLxRlHnESQvTFCkN16OUIeE9BEdl4=
+github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
+github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
+github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
+github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
+github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
+github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
+github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
+github.com/jgautheron/goconst v1.4.0/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=
+github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
+github.com/jingyugao/rowserrcheck v0.0.0-20210130005344-c6a0c12dd98d/go.mod h1:/EZlaYCnEX24i7qdVhT9du5JrtFWYRQr67bVgR7JJC8=
+github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
+github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
+github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
+github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
+github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/juju/errors v0.0.0-20181012004132-a4583d0a56ea h1:g2k+8WR7cHch4g0tBDhfiEvAp7fXxTNBiD1oC1Oxj3E=
github.com/juju/errors v0.0.0-20181012004132-a4583d0a56ea/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
-github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 h1:UUHMLvzt/31azWTN/ifGWef4WUqvXk0iRqdhdy/2uzI=
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
-github.com/juju/testing v0.0.0-20191001232224-ce9dec17d28b h1:Rrp0ByJXEjhREMPGTt3aWYjoIsUGCbt21ekbeJcTWv0=
github.com/juju/testing v0.0.0-20191001232224-ce9dec17d28b/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
+github.com/julz/importas v0.0.0-20210226073942-60b4fa260dd0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0=
+github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
+github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
+github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
+github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.11.12/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
+github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
+github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
+github.com/klauspost/compress v1.14.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
+github.com/klauspost/compress v1.14.4/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
+github.com/klauspost/compress v1.15.4/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
+github.com/klauspost/compress v1.15.6/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
+github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
+github.com/knadh/koanf v1.4.1/go.mod h1:1cfH5223ZeZUOs8FU2UdTmaNfHpqgtjV0+NHjRO43gs=
+github.com/knadh/koanf v1.4.2/go.mod h1:4NCo0q4pmU398vF9vq2jStF9MWQZ8JEDcDMHlDCr4h0=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
-github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
+github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/mailru/easyjson v0.0.0-20180606163543-3fdea8d05856 h1:hOnidOuIWNsFRPcxxStGeN3NNm4n4+w6KJ9cVJIh70o=
-github.com/mailru/easyjson v0.0.0-20180606163543-3fdea8d05856/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kulti/thelper v0.4.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U=
+github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30=
+github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg=
+github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
+github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
+github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
+github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
+github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
+github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
+github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
+github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
+github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
+github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
+github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
+github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
+github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU=
+github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
+github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
+github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
+github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mauricelam/genny v0.0.0-20190320071652-0800202903e5 h1:PnFl95tWh3j7c5DebZG/TGsBJvbnHvPjK4lzltouI4Y=
github.com/mauricelam/genny v0.0.0-20190320071652-0800202903e5/go.mod h1:i2AazGGunAlAR5u0zXGYVmIT7nnwE6j9lwKSMx7N6ko=
-github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
+github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc=
+github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
+github.com/mgechev/revive v1.0.3/go.mod h1:POGGZagSo/0frdr7VeAifzS5Uka0d0GPiM35MsTO8nE=
+github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
+github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
+github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
+github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
+github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
+github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
+github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
+github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
+github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
+github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
+github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
+github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
+github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
+github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
+github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
+github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/mjibson/esc v0.2.0/go.mod h1:9Hw9gxxfHulMF5OJKCyhYD7PzlSdhzXyaGEBRPH1OPs=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
+github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k=
+github.com/mostynb/go-grpc-compression v1.1.16/go.mod h1:xxa6UoYynYS2h+5HB/Hglu81iYAp87ARaNmhhwi0s1s=
+github.com/mostynb/go-grpc-compression v1.1.17/go.mod h1:FUSBr0QjKqQgoDG/e0yiqlR6aqyXC39+g/hFLDfSsEY=
+github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
+github.com/mozilla/tls-observatory v0.0.0-20201209171846-0547674fceff/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c=
+github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
+github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
+github.com/nats-io/jwt v1.2.2/go.mod h1:/xX356yQA6LuXI9xWW7mZNpxgF2mBmGecH+Fj34sP5Q=
+github.com/nats-io/jwt/v2 v2.0.2/go.mod h1:VRP+deawSXyhNjXmxPCHskrR6Mq50BqpEI5SEcNiGlY=
+github.com/nats-io/jwt/v2 v2.0.3/go.mod h1:VRP+deawSXyhNjXmxPCHskrR6Mq50BqpEI5SEcNiGlY=
+github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
+github.com/nats-io/nats-server/v2 v2.2.6/go.mod h1:sEnFaxqe09cDmfMgACxZbziXnhQFhwk+aKkZjBBRYrI=
+github.com/nats-io/nats-server/v2 v2.5.0/go.mod h1:Kj86UtrXAL6LwYRA6H4RqzkHhK0Vcv2ZnKD5WbQ1t3g=
+github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
+github.com/nats-io/nats.go v1.11.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w=
+github.com/nats-io/nats.go v1.12.1/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w=
+github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nkeys v0.2.0/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s=
+github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
+github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
+github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
+github.com/nbutton23/zxcvbn-go v0.0.0-20201221231540-e56b841a3c88/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
+github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ=
+github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE=
+github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnuG+zWp9L0Uk=
+github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
+github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
+github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
+github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
+github.com/olivere/elastic v6.2.35+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8=
+github.com/olivere/elastic v6.2.37+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
+github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
+github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
+github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
+github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
+github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
+github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ=
+github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
+github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
+github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.52.0/go.mod h1:CIX1MWy+2JYdeYhqjK89vrRpCGbz6LTLinp+SM8kZyo=
+github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.54.0/go.mod h1:CSe1wsnLhSAEgAEXLfi8wTyl0VwPVkq7925aV8xm0oM=
+github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.57.2/go.mod h1:xPchY5YNOL9jr6phVkJEvkEakMYr8HMD4uGYEoKXIek=
+github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.52.0/go.mod h1:tU7s/ki/QePSIZ7ExYGWLMb9erCAt66brQHBEHxr8HU=
+github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.54.0/go.mod h1:uWFgO68sLEqWrQxL8rws1CkB8EUNQaedP3FWI1gMJOU=
+github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.57.2/go.mod h1:4rFuWKMbzM9H39RbDvPtJfAp/fxsHydhJhKns6skmK0=
+github.com/opentracing-contrib/go-grpc v0.0.0-20191001143057-db30781987df/go.mod h1:DYR5Eij8rJl8h7gblRrOZ8g0kW1umSpKqYIBTgeDtLo=
+github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
+github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w=
+github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU=
+github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
+github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
-github.com/pavius/impi v0.0.0-20180302134524-c1cbdcb8df2b/go.mod h1:x/hU0bfdWIhuOT1SKwiJg++yvkk6EuOtJk8WtDZqgr8=
+github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
+github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
+github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
+github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
+github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE=
+github.com/ory/go-acc v0.2.6/go.mod h1:4Kb/UnPcT8qRAk3IAxta+hvVapdxTLWtrr7bFLlEgpw=
+github.com/ory/viper v1.7.5/go.mod h1:ypOuyJmEUb3oENywQZRgeAMwqgOyDqwboO1tj3DjTaM=
+github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pavius/impi v0.0.3/go.mod h1:x/hU0bfdWIhuOT1SKwiJg++yvkk6EuOtJk8WtDZqgr8=
+github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
+github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
+github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
+github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
+github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs=
+github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
+github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
+github.com/pelletier/go-toml/v2 v2.0.0-beta.8/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
+github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
+github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
+github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM=
+github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=
+github.com/pierrec/cmdflag v0.0.2/go.mod h1:a3zKGZ3cdQUfxjd0RGMLZr8xI3nvpJOB+m6o/1X5BmU=
+github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
+github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pierrec/lz4/v3 v3.3.4/go.mod h1:280XNCGS8jAcG++AHdd6SeWnzyJ1w9oow2vbORyey8Q=
+github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
+github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
+github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw=
+github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
+github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
+github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
+github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
+github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
+github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
+github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
+github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
+github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
+github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
+github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
+github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
+github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
+github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
+github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
+github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
+github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
+github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
+github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
+github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
+github.com/prometheus/common v0.34.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE=
+github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
+github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
+github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
+github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
+github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
+github.com/prometheus/statsd_exporter v0.21.0/go.mod h1:rbT83sZq2V+p73lHhPZfMc3MLCHmSHelCh9hSGYNLTQ=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
+github.com/quasilyte/go-ruleguard v0.3.0/go.mod h1:p2miAhLp6fERzFNbcuQ4bevXs8rgK//uCHsUDkumITg=
+github.com/quasilyte/go-ruleguard/dsl v0.0.0-20210106184943-e47d54850b18/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
+github.com/quasilyte/go-ruleguard/dsl v0.0.0-20210115110123-c73ee1cbff1f/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
+github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc=
+github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=
+github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA=
+github.com/rivo/tview v0.0.0-20200219210816-cd38d7432498/go.mod h1:6lkG1x+13OShEf0EaOCaTQYyB7d5nSbb181KtjlS+84=
+github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
+github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
-github.com/samuel/go-zookeeper v0.0.0-20190810000440-0ceca61e4d75/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
-github.com/shirou/gopsutil v2.18.10+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
-github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
-github.com/signalfx/com_signalfx_metrics_protobuf v0.0.0-20190222193949-1fb69526e884 h1:KgLGEw137KEUtQnWBGzneCetphBj4+kKHRnhpAkXJC0=
-github.com/signalfx/com_signalfx_metrics_protobuf v0.0.0-20190222193949-1fb69526e884/go.mod h1:muYA2clvwCdj7nzAJ5vJIXYpJsUumhAl4Uu1wUNpWzA=
-github.com/signalfx/com_signalfx_metrics_protobuf v0.0.2 h1:X886QgwZH5qr9HIQkk3mWcNEhUxx6D8rUZumzLV4Wiw=
-github.com/signalfx/com_signalfx_metrics_protobuf v0.0.2/go.mod h1:tCQQqyJAVF1+mxNdqOi18sS/zaSrE6EMyWwRA2QTl70=
+github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0=
+github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
+github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
+github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ryancurrah/gomodguard v1.2.0/go.mod h1:rNqbC4TOIdUDcVMSIpNNAzTbzXAZa6W5lnUepvuMMgQ=
+github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA=
+github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
+github.com/sagikazarmark/crypt v0.5.0/go.mod h1:l+nzl7KWh51rpzp2h7t4MZWyiEWdhNpOAnclKvg+mdA=
+github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8=
+github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
+github.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu9FXAw2W4=
+github.com/sanposhiho/wastedassign v0.1.3/go.mod h1:LGpq5Hsv74QaqM47WtIsRSF/ik9kqk07kchgv66tLVE=
+github.com/schollz/progressbar/v2 v2.13.2/go.mod h1:6YZjqdthH6SCZKv2rqGryrxPtfmRB/DWZxSMfCXPyD8=
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
+github.com/securego/gosec v0.0.0-20200203094520-d13bb6d2420c/go.mod h1:gp0gaHj0WlmPh9BdsTmo1aq6C27yIPWdxCKGFGdVKBE=
+github.com/securego/gosec/v2 v2.6.1/go.mod h1:I76p3NTHBXsGhybUW+cEQ692q2Vp+A0Z6ZLzDIZy+Ao=
+github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
+github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
+github.com/shirou/gopsutil/v3 v3.21.1/go.mod h1:igHnfak0qnw1biGeI2qKQvu0ZkwvEkUcCLlYhZzdr/4=
+github.com/shirou/gopsutil/v3 v3.22.4/go.mod h1:D01hZJ4pVHPpCTZ3m3T2+wDF2YAGfd+H4ifUguaQzHM=
+github.com/shirou/gopsutil/v3 v3.22.5/go.mod h1:so9G9VzeHt/hsd0YwqprnjHnfARAUktauykSbr+y2gA=
+github.com/shirou/gopsutil/v3 v3.22.6/go.mod h1:EdIubSnZhbAvBS1yJ7Xi+AShB/hxwLHOMz4MCYz7yMs=
+github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
+github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/signalfx/com_signalfx_metrics_protobuf v0.0.3 h1:32k2QLgsKhcEs55q4REPKyIadvid5FPy2+VMgvbmKJ0=
+github.com/signalfx/com_signalfx_metrics_protobuf v0.0.3/go.mod h1:gJrXWi7wSGXfiC7+VheQaz+ypdCt5SmZNL+BRxUe7y4=
github.com/signalfx/gohistogram v0.0.0-20160107210732-1ccfd2ff5083 h1:WsShHmu12ZztYPfh9b+I+VjYD1o8iOHhB67WZCMEEE8=
github.com/signalfx/gohistogram v0.0.0-20160107210732-1ccfd2ff5083/go.mod h1:adPDS6s7WaajdFBV9mQ7i0dKfQ8xiDnF9ZNETVPpp7c=
-github.com/signalfx/golib/v3 v3.0.0 h1:7jU1iitxa4qsLMbOlquaHHaUf0GJ86P8ZFxnE5hTUVA=
-github.com/signalfx/golib/v3 v3.0.0/go.mod h1:p+krygP/cDlWvCBEgdkQp3H16rbP4NW7YQa81TDMRe8=
-github.com/signalfx/golib/v3 v3.3.37 h1:CvL6Q8hySjm7D82P039qH2lFWJvBa18IJdAwa4LHoR4=
-github.com/signalfx/golib/v3 v3.3.37/go.mod h1:zH70SVnrzVUqDmUFEwDk1HSwS71Pi2w3bSsNpnOtYuQ=
+github.com/signalfx/golib/v3 v3.3.47 h1:awph3lTi4Yp766nIOUU1bgvaS8BxB4ujW0ZwByaxiYE=
+github.com/signalfx/golib/v3 v3.3.47/go.mod h1:N7bdXqA6fGQQn03WHZRDXvyN/GUFI+BXjoJgidfncZU=
github.com/signalfx/gomemcache v0.0.0-20180823214636-4f7ef64c72a9/go.mod h1:Ytb8KfCSyuwy/VILnROdgCvbQLA5ch0nkbG7lKT0BXw=
-github.com/signalfx/sapm-proto v0.4.0 h1:5lQX++6FeIjUZEIcnSgBqhOpmSjMkRBW3y/4ZiKMo5E=
-github.com/signalfx/sapm-proto v0.4.0/go.mod h1:x3gtwJ1GRejtkghB4nYpwixh2zqJrLbPU959ZNhM0Fk=
-github.com/signalfx/thrift v0.0.0-20181211001559-3838fa316492/go.mod h1:Xv29nl9fxdk0hmeqcUHgAZZwvYrOhduNW+9qk4H+6K0=
+github.com/signalfx/sapm-proto v0.7.2 h1:iM/y3gezQm1/j7JBS0gXhEJ8ROeneb6DY7n0OcnvLks=
+github.com/signalfx/sapm-proto v0.7.2/go.mod h1:HLufOh6Gd2altGxbeve+s6hh0EWCWoOM7MmuYuvs5PI=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
+github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
+github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/assertions v0.0.0-20190215210624-980c5ac6f3ac h1:wbW+Bybf9pXxnCFAOWZTqkRjAc7rAIwo2e1ArUhiHxg=
-github.com/smartystreets/assertions v0.0.0-20190215210624-980c5ac6f3ac/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/goconvey v1.6.4-0.20190306220146-200a235640ff h1:JcVn27VGCEwd33jyNj+3IqEbOmzAX9f9LILt3SoGPHU=
-github.com/smartystreets/goconvey v1.6.4-0.20190306220146-200a235640ff/go.mod h1:KSQcGKpxUMHk3nbYzs/tIBAM2iDooCn0BmttHOJEbLs=
-github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
+github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
+github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
+github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI=
+github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
+github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
+github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
+github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
+github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
+github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
+github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
+github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
+github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
+github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
+github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
+github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
+github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
+github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
+github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
+github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
+github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
+github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
+github.com/spf13/viper v1.11.0/go.mod h1:djo0X/bA5+tYVoCn+C7cAYJGcVn/qYLFTG8gdUsX7Zk=
+github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI=
+github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
+github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
+github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
+github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
+github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs=
+github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM=
+github.com/tetafro/godot v1.4.4/go.mod h1:FVDd4JuKliW3UgjswZfJfHq4vAx0bD/Jd5brJjGeaz4=
+github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
+github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
+github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
+github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0=
+github.com/tommy-muehle/go-mnd/v2 v2.3.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
+github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
+github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
+github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
+github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
+github.com/uber/jaeger-lib v2.4.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
+github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
+github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
+github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
+github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
+github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
+github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
+github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
+github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA=
+github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY=
+github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec/go.mod h1:owBmyHYMLkxyrugmfwE/DLJyW8Ro9mkphwuVErQ0iUw=
+github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
+github.com/vektra/mockery v0.0.0-20181123154057-e78b021dcbb5/go.mod h1:ppEjwdhyy7Y31EnHRDm1JkChoC7LXIJ7Ex0VYLWtZtQ=
+github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad/go.mod h1:Hy8o65+MXnS6EwGElrSRjUzQDLXreJlzYLlWiHtt8hM=
+github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
+github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
+github.com/xdg-go/scram v1.1.0/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
+github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
+github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
+github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
+github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
+github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
+github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
+github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
+github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
+go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
+go.etcd.io/etcd/api/v3 v3.5.2/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
+go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
+go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
+go.etcd.io/etcd/client/pkg/v3 v3.5.2/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
+go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
+go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
+go.etcd.io/etcd/client/v2 v2.305.2/go.mod h1:2D7ZejHVMIfog1221iLSYlQRzrtECw3kz4I4VAQm3qI=
+go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU=
+go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
+go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
+go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
+go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
+go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
+go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
+go.mongodb.org/mongo-driver v1.3.2/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
+go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg=
+go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng=
+go.mongodb.org/mongo-driver v1.8.3/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY=
+go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8=
+go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
+go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
+go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
+go.opentelemetry.io/collector v0.52.0/go.mod h1:a9GvaOhyc0nVOUzqvdv5mxyWghCSso/WRO2GgRl4I1g=
+go.opentelemetry.io/collector v0.54.0/go.mod h1:FgNzyfb4sAGb5cqusB5znETJ8Pz4OQUBGbOeGIZ2rlQ=
+go.opentelemetry.io/collector v0.57.2/go.mod h1:9TwWyMRhbFNzaaGLtm/6poWNDJw+etvQMS6Fy+8/8Xs=
+go.opentelemetry.io/collector/model v0.49.0/go.mod h1:nOYQv9KoFPs6ihJwOi24qB209EOhS9HkwhGj54YiEAw=
+go.opentelemetry.io/collector/pdata v0.49.0/go.mod h1:YwmKuiFhNgtmhRdpi8Q8FAWPa0AwJTCSlssSsAtuRcY=
+go.opentelemetry.io/collector/pdata v0.52.0/go.mod h1:GJUTfTv8mlYpHRjcmHXVbvJr48EW/q/P/HuBvpXAE58=
+go.opentelemetry.io/collector/pdata v0.54.0/go.mod h1:1nSelv/YqGwdHHaIKNW9ZOHSMqicDX7W4/7TjNCm6N8=
+go.opentelemetry.io/collector/pdata v0.56.0/go.mod h1:mYcCREWiIJyHss0dbU+GSiz2tmGZ6u09vtfkKTciog4=
+go.opentelemetry.io/collector/pdata v0.57.2/go.mod h1:RU9I8lwBUxucwOsSYzHEcHi15M9QaX78hgQ2PRdSxV0=
+go.opentelemetry.io/collector/semconv v0.52.0/go.mod h1:SxK0rUnUP7YeDakexzbE/vhimTOHwE6m/4aKKd9e27Q=
+go.opentelemetry.io/collector/semconv v0.54.0/go.mod h1:HAGkPKNMhc4kEHevEqVIEtUuvsRQMIbUWBb8yBrqEwk=
+go.opentelemetry.io/collector/semconv v0.56.0/go.mod h1:EH1wbDvTyqKpKBBpoMIe0KQk2plCcFS66Mo17WtR7CQ=
+go.opentelemetry.io/collector/semconv v0.57.2/go.mod h1:84YnUjmm+nhGu4YTDLnHCbxnL74ooWpismPG79tFD7w=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.32.0/go.mod h1:J0dBVrt7dPS/lKJyQoW0xzQiUr4r2Ik1VwPjAUWnofI=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.33.0/go.mod h1:y/SlJpJQPd2UzfBCj0E9Flk9FDCtTyqUmaCB41qFrWI=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0/go.mod h1:5eCOqeGphOyz6TsY3ZDNjE33SM/TFAK3RGuCL2naTgY=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.33.0/go.mod h1:U5rUt7Rw6zuORsWNfpMRy8XMNKLrmIlv/4HgLVW/d5M=
+go.opentelemetry.io/contrib/zpages v0.32.0/go.mod h1:Jx75I61RDcZU3d/1WrP6UdINlzGGLAwFNdQ3bCTb+qw=
+go.opentelemetry.io/contrib/zpages v0.33.0/go.mod h1:ddmD63NkBVE29GucaBBCR8/b/TRlY+PkpIbF3m2JF7Y=
+go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk=
+go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM=
+go.opentelemetry.io/otel v1.9.0/go.mod h1:np4EoPGzoPs3O67xUVNoPPcmSvsfOxNlNA4F4AC+0Eo=
+go.opentelemetry.io/otel/exporters/prometheus v0.30.0/go.mod h1:qN5feW+0/d661KDtJuATEmHtw5bKBK7NSvNEP927zSs=
+go.opentelemetry.io/otel/exporters/prometheus v0.31.0/go.mod h1:QarXIB8L79IwIPoNgG3A6zNvBgVmcppeFogV1d8612s=
+go.opentelemetry.io/otel/metric v0.30.0/go.mod h1:/ShZ7+TS4dHzDFmfi1kSXMhMVubNoP0oIaBp70J6UXU=
+go.opentelemetry.io/otel/metric v0.31.0/go.mod h1:ohmwj9KTSIeBnDBm/ZwH2PSZxZzoOaG2xZeekTRzL5A=
+go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU=
+go.opentelemetry.io/otel/sdk v1.8.0/go.mod h1:uPSfc+yfDH2StDM/Rm35WE8gXSNdvCg023J6HeGNO0c=
+go.opentelemetry.io/otel/sdk/metric v0.30.0/go.mod h1:8AKFRi5HyvTR0RRty3paN1aMC9HMT+NzcEhw/BLkLX8=
+go.opentelemetry.io/otel/sdk/metric v0.31.0/go.mod h1:fl0SmNnX9mN9xgU6OLYLMBMrNAsaZQi7qBwprwO3abk=
+go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU=
+go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4=
+go.opentelemetry.io/otel/trace v1.9.0/go.mod h1:2737Q0MuG8q1uILYm2YYVkAyLtOofiTNGg6VODnOiPo=
+go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
+go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
+go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q=
+go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66vU6XU=
+go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
+go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
+go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
+go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
+go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
+go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
+go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
+go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
+go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
+go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
+go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
+go.uber.org/zap v1.22.0 h1:Zcye5DUgBloQ9BaT4qc9BnjOFog5TvBSAGkJ3Nf70c0=
+go.uber.org/zap v1.22.0/go.mod h1:H4siCOZOrAolnUPJEkfaSjDqyP+BDS0DdDWzwcgt3+U=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
+golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
+golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
+golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
+golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
+golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
+golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
+golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
+golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
+golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181207154023-610586996380/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
+golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
+golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
+golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 h1:NWy5+hlRbC7HK+PmcXVUmW1IMyFce7to56IUvhUFm7Y=
+golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=
+golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20181112210238-4b1f3b6b1646/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190319232107-3f1ed9edd1b4 h1:4oAPsdy/MJIeaCzEMEhYwYBU/gHkXH52Xa4M+0GBHfA=
+golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190319232107-3f1ed9edd1b4/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190906203814-12febf440ab1 h1:w4Q0TX3lC1NfGcWkzt5wG4ee4E5fUAPqh5myV0efeHI=
-golang.org/x/tools v0.0.0-20190906203814-12febf440ab1/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200203023011-6f24f261dadb/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210102185154-773b96fafca2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210104081019-d8d6ddbec6ee/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
+golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618=
+golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
+gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
+gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
+gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
+gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
+google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
+google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
+google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
+google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
+google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
+google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
+google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
+google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
+google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
+google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
+google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
+google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
+google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
+google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
+google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
+google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
+google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
+google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
+google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
+google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
+google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=
+google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=
+google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
+google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
+google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
+google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
+google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
+google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
+google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
+google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
+google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
+google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
+google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
+google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
+google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
+google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
+google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
+google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
+google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
+google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
+google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
+google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
+google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
+google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
+google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
+google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
+google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
+google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
+google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
+google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
+google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
+google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
+google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
+google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
+google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
+google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
+google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
+google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
+gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.52.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
+gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
+gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
+gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
+gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
+gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.1.1/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
+honnef.co/go/tools v0.1.2/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
+mvdan.cc/gofumpt v0.1.0/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48=
+mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
+mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
+mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7/go.mod h1:hBpJkZE8H/sb+VRFvw2+rBpHNsTBcvSpk61hr8mzXZE=
+rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
+rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
+sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
+sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
diff --git a/go.work b/go.work
new file mode 100644
index 0000000..7b29257
--- /dev/null
+++ b/go.work
@@ -0,0 +1,6 @@
+go 1.20
+
+use (
+ .
+ ./signalflow
+)
diff --git a/go.work.sum b/go.work.sum
new file mode 100644
index 0000000..fd76af8
--- /dev/null
+++ b/go.work.sum
@@ -0,0 +1 @@
+github.com/signalfx/signalfx-go v1.31.0/go.mod h1:IpGZLPvCKNFyspAXoS480jB02mocTpo0KYd8jbl6/T8=
diff --git a/integration/model_aws_cloud_watch_integration_test.go b/integration/model_aws_cloud_watch_integration_test.go
new file mode 100644
index 0000000..02963bd
--- /dev/null
+++ b/integration/model_aws_cloud_watch_integration_test.go
@@ -0,0 +1,33 @@
+package integration
+
+import (
+ "encoding/json"
+ "github.com/stretchr/testify/assert"
+ "testing"
+)
+
+func TestAwsCloudWatchIntegration_MarshallingToAndFromJSON(t *testing.T) {
+ cwIntegration := &AwsCloudWatchIntegration{
+ Name: "abc",
+ Services: []AwsService{"AWS/Foo"},
+ NamespaceSyncRules: []*AwsNameSpaceSyncRule{
+ {Namespace: "AWS/Bar"},
+ },
+ }
+ jsonBytes, err := json.Marshal(cwIntegration)
+ assert.NoError(t, err, "Error marshalling CW integration")
+
+ unmarshalledCwIntegration := &AwsCloudWatchIntegration{}
+ err = json.Unmarshal(jsonBytes, &unmarshalledCwIntegration)
+ assert.NoError(t, err, "Error unmarshalling CW integration")
+ assert.Equal(t, cwIntegration, unmarshalledCwIntegration, "Marshalling and unmarshalling mismatch")
+ assert.Equal(t, AwsService("AWS/Foo"), unmarshalledCwIntegration.Services[0], "Service does not match")
+}
+
+func TestDerivedTypeComparison(t *testing.T) {
+ assert.NotEqual(t, AwsService("AWS/Foo"), "AWS/Foo", "Same value, different types")
+
+ assert.True(t, AwsService("AWS/Foo") == "AWS/Foo", "Golang revolution!")
+ assert.True(t, "AWS/Bar" == AwsService("AWS/Bar"), "Golang revolution!")
+ assert.True(t, "" == AwsService(""), "Golang revolution!")
+}
diff --git a/integration/model_aws_service.go b/integration/model_aws_service.go
index 619f492..0152369 100644
--- a/integration/model_aws_service.go
+++ b/integration/model_aws_service.go
@@ -11,6 +11,9 @@ package integration
type AwsService string
+// Deprecated: the following constants are deprecated and this list is not going to be maintained anymore.
+// Please use regular strings or convert regular strings to the AwsService type as required.
+// For example: AwsService("AWS/FooBar")
const (
AWSACP_PRIVATE_CA AwsService = "AWS/ACMPrivateCA"
AWSAMAZON_MQ AwsService = "AWS/AmazonMQ"
@@ -50,6 +53,7 @@ const (
AWSFIREHOSE AwsService = "AWS/Firehose"
AWSFSX AwsService = "AWS/FSx"
AWSGAME_LIFT AwsService = "AWS/GameLift"
+ AWSGLOBAL_ACCELERATOR AwsService = "AWS/GlobalAccelerator"
AWSINSPECTOR AwsService = "AWS/Inspector"
AWSIO_T AwsService = "AWS/IoT"
AWSIO_T_ANALYTICS AwsService = "AWS/IoTAnalytics"
@@ -103,6 +107,9 @@ const (
WAF AwsService = "WAF"
)
+// Deprecated: the following map is deprecated and it is not going to be maintained anymore.
+// Please use regular strings or convert regular strings to the AwsService type as required.
+// For example: AwsService("AWS/FooBar")
var AWSServiceNames = map[string]AwsService{
"AWS/ACMPrivateCA": AWSACP_PRIVATE_CA,
"AWS/AmazonMQ": AWSAMAZON_MQ,
@@ -142,6 +149,7 @@ var AWSServiceNames = map[string]AwsService{
"AWS/Firehose": AWSFIREHOSE,
"AWS/FSx": AWSFSX,
"AWS/GameLift": AWSGAME_LIFT,
+ "AWS/GlobalAccelerator": AWSGLOBAL_ACCELERATOR,
"AWS/Inspector": AWSINSPECTOR,
"AWS/IoT": AWSIO_T,
"AWS/IoTAnalytics": AWSIO_T_ANALYTICS,
diff --git a/integration/model_azure_service.go b/integration/model_azure_service.go
index a314840..9c8a461 100644
--- a/integration/model_azure_service.go
+++ b/integration/model_azure_service.go
@@ -2,6 +2,9 @@ package integration
type AzureService string
+// Deprecated: the following constants are deprecated and this list is not going to be maintained anymore.
+// Please use regular strings or convert regular strings to the AzureService type as required.
+// For example: AzureService("AWS/FooBar")
const (
AZURE_MICROSOFT_ANALYSISSERVICES_SERVERS AzureService = "microsoft.analysisservices/servers"
AZURE_MICROSOFT_APIMANAGEMENT_SERVICE AzureService = "microsoft.apimanagement/service"
@@ -24,10 +27,12 @@ const (
AZURE_MICROSOFT_DATAFACTORY_FACTORIES AzureService = "microsoft.datafactory/factories"
AZURE_MICROSOFT_DATALAKEANALYTICS_ACCOUNTS AzureService = "microsoft.datalakeanalytics/accounts"
AZURE_MICROSOFT_DATALAKESTORE_ACCOUNTS AzureService = "microsoft.datalakestore/accounts"
+ AZURE_MICROSOFT_DATAPROTECTION_BACKUPVAULTS AzureService = "microsoft.dataprotection/backupvaults"
AZURE_MICROSOFT_DBFORMARIADB_SERVERS AzureService = "microsoft.dbformariadb/servers"
AZURE_MICROSOFT_DBFORMYSQL_SERVERS AzureService = "microsoft.dbformysql/servers"
AZURE_MICROSOFT_DBFORMYSQL_FLEXIBLESERVERS AzureService = "microsoft.dbformysql/flexibleservers"
AZURE_MICROSOFT_DBFORPOSTGRESQL_SERVERS AzureService = "microsoft.dbforpostgresql/servers"
+ AZURE_MICROSOFT_DBFORPOSTGRESQL_FLEXIBLESERVERS AzureService = "microsoft.dbforpostgresql/flexibleservers"
AZURE_DEVICES AzureService = "microsoft.devices"
AZURE_DEVICES_ELASTICPOOLS AzureService = "microsoft.devices/elasticpools"
AZURE_DEVICES_ELASTICPOOLS_IOHUBTENANTS AzureService = "microsoft.devices/elasticpools/iothubtenants"
@@ -60,6 +65,7 @@ const (
AZURE_MICROSOFT_NETWORK_VIRTUALNETWORKGATEWAYS AzureService = "microsoft.network/virtualnetworkgateways"
AZURE_MICROSOFT_NOTIFICATIONHUBS_NAMESPACES_NOTIFICATIONHUBS AzureService = "microsoft.notificationhubs/namespaces/notificationhubs"
AZURE_MICROSOFT_POWERBIDEDICATED_CAPACITIES AzureService = "microsoft.powerbidedicated/capacities"
+ AZURE_MICROSOFT_RECOVERYSERVICES_VAULTS AzureService = "microsoft.recoveryservices/vaults"
AZURE_MICROSOFT_RELAY_NAMESPACES AzureService = "microsoft.relay/namespaces"
AZURE_MICROSOFT_SEARCH_SEARCHSERVICES AzureService = "microsoft.search/searchservices"
AZURE_MICROSOFT_SERVICEBUS_NAMESPACES AzureService = "microsoft.servicebus/namespaces"
@@ -83,6 +89,9 @@ const (
AZURE_MICROSOFT_WEB_SITES_SLOTS AzureService = "microsoft.web/sites/slots"
)
+// Deprecated: the following map is deprecated and it is not going to be maintained anymore.
+// Please use regular strings or convert regular strings to the AzureService type as required.
+// For example: AzureService("microsoft.foo/bar")
var AzureServiceNames = map[string]AzureService{
"microsoft.analysisservices/servers": AZURE_MICROSOFT_ANALYSISSERVICES_SERVERS,
"microsoft.apimanagement/service": AZURE_MICROSOFT_APIMANAGEMENT_SERVICE,
@@ -105,10 +114,12 @@ var AzureServiceNames = map[string]AzureService{
"microsoft.datafactory/factories": AZURE_MICROSOFT_DATAFACTORY_FACTORIES,
"microsoft.datalakeanalytics/accounts": AZURE_MICROSOFT_DATALAKEANALYTICS_ACCOUNTS,
"microsoft.datalakestore/accounts": AZURE_MICROSOFT_DATALAKESTORE_ACCOUNTS,
+ "microsoft.dataprotection/backupvaults": AZURE_MICROSOFT_DATAPROTECTION_BACKUPVAULTS,
"microsoft.dbformariadb/servers": AZURE_MICROSOFT_DBFORMARIADB_SERVERS,
"microsoft.dbformysql/servers": AZURE_MICROSOFT_DBFORMYSQL_SERVERS,
"microsoft.dbformysql/flexibleservers": AZURE_MICROSOFT_DBFORMYSQL_FLEXIBLESERVERS,
"microsoft.dbforpostgresql/servers": AZURE_MICROSOFT_DBFORPOSTGRESQL_SERVERS,
+ "microsoft.dbforpostgresql/flexibleservers": AZURE_MICROSOFT_DBFORPOSTGRESQL_FLEXIBLESERVERS,
"microsoft.devices": AZURE_DEVICES,
"microsoft.devices/elasticpools": AZURE_DEVICES_ELASTICPOOLS,
"microsoft.devices/elasticpools/iothubtenants": AZURE_DEVICES_ELASTICPOOLS_IOHUBTENANTS,
@@ -141,6 +152,7 @@ var AzureServiceNames = map[string]AzureService{
"microsoft.network/virtualnetworkgateways": AZURE_MICROSOFT_NETWORK_VIRTUALNETWORKGATEWAYS,
"microsoft.notificationhubs/namespaces/notificationhubs": AZURE_MICROSOFT_NOTIFICATIONHUBS_NAMESPACES_NOTIFICATIONHUBS,
"microsoft.powerbidedicated/capacities": AZURE_MICROSOFT_POWERBIDEDICATED_CAPACITIES,
+ "microsoft.recoveryservices/vaults": AZURE_MICROSOFT_RECOVERYSERVICES_VAULTS,
"microsoft.relay/namespaces": AZURE_MICROSOFT_RELAY_NAMESPACES,
"microsoft.search/searchservices": AZURE_MICROSOFT_SEARCH_SEARCHSERVICES,
"microsoft.servicebus/namespaces": AZURE_MICROSOFT_SERVICEBUS_NAMESPACES,
diff --git a/integration/model_gcp_service.go b/integration/model_gcp_service.go
index ee5a6ce..d3be228 100644
--- a/integration/model_gcp_service.go
+++ b/integration/model_gcp_service.go
@@ -2,6 +2,9 @@ package integration
type GcpService string
+// Deprecated: the following constants are deprecated and this list is not going to be maintained anymore.
+// Please use regular strings or convert regular strings to the GcpService type as required.
+// For example: GcpService("foo")
const (
GCP_APPENGINE GcpService = "appengine"
GCP_BIGQUERY GcpService = "bigquery"
@@ -36,6 +39,9 @@ const (
GCP_VPN GcpService = "vpn"
)
+// Deprecated: the following map is deprecated and it is not going to be maintained anymore.
+// Please use regular strings or convert regular strings to the GcpService type as required.
+// For example: GcpService("foo")
var GcpServiceNames = map[string]GcpService{
"appengine": GCP_APPENGINE,
"bigquery": GCP_BIGQUERY,
diff --git a/metric_ruleset.go b/metric_ruleset.go
new file mode 100644
index 0000000..fe7f140
--- /dev/null
+++ b/metric_ruleset.go
@@ -0,0 +1,140 @@
+package signalfx
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/http"
+
+ "github.com/signalfx/signalfx-go/metric_ruleset"
+)
+
+// MetricRulesetApiURL is the base URL for interacting with metric rulesets.
+const MetricRulesetApiURL = "/v2/metricruleset"
+
+// GetMetricRuleset gets a metric ruleset.
+func (c *Client) GetMetricRuleset(ctx context.Context, id string) (*metric_ruleset.GetMetricRulesetResponse, error) {
+ resp, err := c.doRequest(ctx, http.MethodGet, MetricRulesetApiURL+"/"+id, nil, nil)
+ if resp != nil {
+ defer resp.Body.Close()
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ if resp.StatusCode != http.StatusOK {
+ message, _ := ioutil.ReadAll(resp.Body)
+ return nil, fmt.Errorf("bad status %d: %s", resp.StatusCode, message)
+ }
+
+ metricRuleset := &metric_ruleset.GetMetricRulesetResponse{}
+ err = json.NewDecoder(resp.Body).Decode(&metricRuleset)
+ io.Copy(ioutil.Discard, resp.Body)
+
+ return metricRuleset, err
+}
+
+// CreateMetricRuleset creates a metric ruleset.
+func (c *Client) CreateMetricRuleset(ctx context.Context, metricRuleset *metric_ruleset.CreateMetricRulesetRequest) (*metric_ruleset.CreateMetricRulesetResponse, error) {
+ payload, err := json.Marshal(metricRuleset)
+ if err != nil {
+ return nil, err
+ }
+
+ resp, err := c.doRequest(ctx, http.MethodPost, MetricRulesetApiURL, nil, bytes.NewReader(payload))
+ if resp != nil {
+ defer resp.Body.Close()
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ if resp.StatusCode != http.StatusOK {
+ message, _ := ioutil.ReadAll(resp.Body)
+ return nil, fmt.Errorf("bad status %d: %s", resp.StatusCode, message)
+ }
+
+ createdMetricRuleset := &metric_ruleset.CreateMetricRulesetResponse{}
+ err = json.NewDecoder(resp.Body).Decode(&createdMetricRuleset)
+ io.Copy(ioutil.Discard, resp.Body)
+
+ return createdMetricRuleset, err
+}
+
+// UpdateMetricRuleset updates a metric ruleset.
+func (c *Client) UpdateMetricRuleset(ctx context.Context, id string, metricRuleset *metric_ruleset.UpdateMetricRulesetRequest) (*metric_ruleset.UpdateMetricRulesetResponse, error) {
+ payload, err := json.Marshal(metricRuleset)
+ if err != nil {
+ return nil, err
+ }
+
+ resp, err := c.doRequest(ctx, http.MethodPut, MetricRulesetApiURL+"/"+id, nil, bytes.NewReader(payload))
+ if resp != nil {
+ defer resp.Body.Close()
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ if resp.StatusCode != http.StatusOK {
+ message, _ := ioutil.ReadAll(resp.Body)
+ return nil, fmt.Errorf("bad status %d: %s", resp.StatusCode, message)
+ }
+
+ updatedMetricRuleset := &metric_ruleset.UpdateMetricRulesetResponse{}
+ err = json.NewDecoder(resp.Body).Decode(&updatedMetricRuleset)
+ io.Copy(ioutil.Discard, resp.Body)
+
+ return updatedMetricRuleset, err
+}
+
+// DeleteMetricRuleset deletes a metric ruleset.
+func (c *Client) DeleteMetricRuleset(ctx context.Context, id string) error {
+ resp, err := c.doRequest(ctx, http.MethodDelete, MetricRulesetApiURL+"/"+id, nil, nil)
+ if resp != nil {
+ defer resp.Body.Close()
+ }
+
+ if err != nil {
+ return err
+ }
+
+ if resp.StatusCode != http.StatusNoContent {
+ message, _ := ioutil.ReadAll(resp.Body)
+ return fmt.Errorf("bad status %d: %s", resp.StatusCode, message)
+ }
+
+ io.Copy(ioutil.Discard, resp.Body)
+
+ return nil
+}
+
+func (c *Client) GenerateAggregationMetricName(ctx context.Context, generateAggregationNameRequest metric_ruleset.GenerateAggregationNameRequest) (string, error) {
+ payload, err := json.Marshal(generateAggregationNameRequest)
+ if err != nil {
+ return "", err
+ }
+
+ resp, err := c.doRequest(ctx, http.MethodPost, MetricRulesetApiURL+"/generateAggregationMetricName", nil, bytes.NewReader(payload))
+ if resp != nil {
+ defer resp.Body.Close()
+ }
+ if err != nil {
+ return "", err
+ }
+
+ if resp.StatusCode != http.StatusOK {
+ message, _ := ioutil.ReadAll(resp.Body)
+ return "", fmt.Errorf("bad status %d: %s", resp.StatusCode, message)
+ }
+
+ respBody, err := ioutil.ReadAll(resp.Body)
+ aggregationMetricName := string(respBody)
+
+ return aggregationMetricName, err
+}
diff --git a/metric_ruleset/client.go b/metric_ruleset/client.go
new file mode 100644
index 0000000..a9a6cb4
--- /dev/null
+++ b/metric_ruleset/client.go
@@ -0,0 +1,580 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "encoding/xml"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "log"
+ "mime/multipart"
+ "net/http"
+ "net/http/httputil"
+ "net/url"
+ "os"
+ "path/filepath"
+ "reflect"
+ "regexp"
+ "strconv"
+ "strings"
+ "time"
+ "unicode/utf8"
+
+ "golang.org/x/oauth2"
+)
+
+var (
+ jsonCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:vnd\.[^;]+\+)?json)`)
+ xmlCheck = regexp.MustCompile(`(?i:(?:application|text)/xml)`)
+)
+
+// APIClient manages communication with the Metric Ruleset API API v3.0.1
+// In most cases there should be only one, shared, APIClient.
+type APIClient struct {
+ cfg *Configuration
+ common service // Reuse a single struct instead of allocating one for each service on the heap.
+
+ // API Services
+}
+
+type service struct {
+ client *APIClient
+}
+
+// NewAPIClient creates a new API client. Requires a userAgent string describing your application.
+// optionally a custom http.Client to allow for advanced features such as caching.
+func NewAPIClient(cfg *Configuration) *APIClient {
+ if cfg.HTTPClient == nil {
+ cfg.HTTPClient = http.DefaultClient
+ }
+
+ c := &APIClient{}
+ c.cfg = cfg
+ c.common.client = c
+
+ // API Services
+
+ return c
+}
+
+func atoi(in string) (int, error) {
+ return strconv.Atoi(in)
+}
+
+// selectHeaderContentType select a content type from the available list.
+func selectHeaderContentType(contentTypes []string) string {
+ if len(contentTypes) == 0 {
+ return ""
+ }
+ if contains(contentTypes, "application/json") {
+ return "application/json"
+ }
+ return contentTypes[0] // use the first content type specified in 'consumes'
+}
+
+// selectHeaderAccept join all accept types and return
+func selectHeaderAccept(accepts []string) string {
+ if len(accepts) == 0 {
+ return ""
+ }
+
+ if contains(accepts, "application/json") {
+ return "application/json"
+ }
+
+ return strings.Join(accepts, ",")
+}
+
+// contains is a case insensitive match, finding needle in a haystack
+func contains(haystack []string, needle string) bool {
+ for _, a := range haystack {
+ if strings.EqualFold(a, needle) {
+ return true
+ }
+ }
+ return false
+}
+
+// Verify optional parameters are of the correct type.
+func typeCheckParameter(obj interface{}, expected string, name string) error {
+ // Make sure there is an object.
+ if obj == nil {
+ return nil
+ }
+
+ // Check the type is as expected.
+ if reflect.TypeOf(obj).String() != expected {
+ return fmt.Errorf("expected %s to be of type %s but received %s", name, expected, reflect.TypeOf(obj).String())
+ }
+ return nil
+}
+
+// parameterToString convert interface{} parameters to string, using a delimiter if format is provided.
+func parameterToString(obj interface{}, collectionFormat string) string {
+ var delimiter string
+
+ switch collectionFormat {
+ case "pipes":
+ delimiter = "|"
+ case "ssv":
+ delimiter = " "
+ case "tsv":
+ delimiter = "\t"
+ case "csv":
+ delimiter = ","
+ }
+
+ if reflect.TypeOf(obj).Kind() == reflect.Slice {
+ return strings.Trim(strings.Replace(fmt.Sprint(obj), " ", delimiter, -1), "[]")
+ } else if t, ok := obj.(time.Time); ok {
+ return t.Format(time.RFC3339)
+ }
+
+ return fmt.Sprintf("%v", obj)
+}
+
+// helper for converting interface{} parameters to json strings
+func parameterToJson(obj interface{}) (string, error) {
+ jsonBuf, err := json.Marshal(obj)
+ if err != nil {
+ return "", err
+ }
+ return string(jsonBuf), err
+}
+
+// callAPI do the request.
+func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) {
+ if c.cfg.Debug {
+ dump, err := httputil.DumpRequestOut(request, true)
+ if err != nil {
+ return nil, err
+ }
+ log.Printf("\n%s\n", string(dump))
+ }
+
+ resp, err := c.cfg.HTTPClient.Do(request)
+ if err != nil {
+ return resp, err
+ }
+
+ if c.cfg.Debug {
+ dump, err := httputil.DumpResponse(resp, true)
+ if err != nil {
+ return resp, err
+ }
+ log.Printf("\n%s\n", string(dump))
+ }
+ return resp, err
+}
+
+// Allow modification of underlying config for alternate implementations and testing
+// Caution: modifying the configuration while live can cause data races and potentially unwanted behavior
+func (c *APIClient) GetConfig() *Configuration {
+ return c.cfg
+}
+
+type formFile struct {
+ fileBytes []byte
+ fileName string
+ formFileName string
+}
+
+// prepareRequest build the request
+func (c *APIClient) prepareRequest(
+ ctx context.Context,
+ path string, method string,
+ postBody interface{},
+ headerParams map[string]string,
+ queryParams url.Values,
+ formParams url.Values,
+ formFiles []formFile) (localVarRequest *http.Request, err error) {
+
+ var body *bytes.Buffer
+
+ // Detect postBody type and post.
+ if postBody != nil {
+ contentType := headerParams["Content-Type"]
+ if contentType == "" {
+ contentType = detectContentType(postBody)
+ headerParams["Content-Type"] = contentType
+ }
+
+ body, err = setBody(postBody, contentType)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ // add form parameters and file if available.
+ if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(formFiles) > 0) {
+ if body != nil {
+ return nil, errors.New("Cannot specify postBody and multipart form at the same time.")
+ }
+ body = &bytes.Buffer{}
+ w := multipart.NewWriter(body)
+
+ for k, v := range formParams {
+ for _, iv := range v {
+ if strings.HasPrefix(k, "@") { // file
+ err = addFile(w, k[1:], iv)
+ if err != nil {
+ return nil, err
+ }
+ } else { // form value
+ w.WriteField(k, iv)
+ }
+ }
+ }
+ for _, formFile := range formFiles {
+ if len(formFile.fileBytes) > 0 && formFile.fileName != "" {
+ w.Boundary()
+ part, err := w.CreateFormFile(formFile.formFileName, filepath.Base(formFile.fileName))
+ if err != nil {
+ return nil, err
+ }
+ _, err = part.Write(formFile.fileBytes)
+ if err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ // Set the Boundary in the Content-Type
+ headerParams["Content-Type"] = w.FormDataContentType()
+
+ // Set Content-Length
+ headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len())
+ w.Close()
+ }
+
+ if strings.HasPrefix(headerParams["Content-Type"], "application/x-www-form-urlencoded") && len(formParams) > 0 {
+ if body != nil {
+ return nil, errors.New("Cannot specify postBody and x-www-form-urlencoded form at the same time.")
+ }
+ body = &bytes.Buffer{}
+ body.WriteString(formParams.Encode())
+ // Set Content-Length
+ headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len())
+ }
+
+ // Setup path and query parameters
+ url, err := url.Parse(path)
+ if err != nil {
+ return nil, err
+ }
+
+ // Override request host, if applicable
+ if c.cfg.Host != "" {
+ url.Host = c.cfg.Host
+ }
+
+ // Override request scheme, if applicable
+ if c.cfg.Scheme != "" {
+ url.Scheme = c.cfg.Scheme
+ }
+
+ // Adding Query Param
+ query := url.Query()
+ for k, v := range queryParams {
+ for _, iv := range v {
+ query.Add(k, iv)
+ }
+ }
+
+ // Encode the parameters.
+ url.RawQuery = query.Encode()
+
+ // Generate a new request
+ if body != nil {
+ localVarRequest, err = http.NewRequest(method, url.String(), body)
+ } else {
+ localVarRequest, err = http.NewRequest(method, url.String(), nil)
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ // add header parameters, if any
+ if len(headerParams) > 0 {
+ headers := http.Header{}
+ for h, v := range headerParams {
+ headers[h] = []string{v}
+ }
+ localVarRequest.Header = headers
+ }
+
+ // Add the user agent to the request.
+ localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent)
+
+ if ctx != nil {
+ // add context to the request
+ localVarRequest = localVarRequest.WithContext(ctx)
+
+ // Walk through any authentication.
+
+ // OAuth2 authentication
+ if tok, ok := ctx.Value(ContextOAuth2).(oauth2.TokenSource); ok {
+ // We were able to grab an oauth2 token from the context
+ var latestToken *oauth2.Token
+ if latestToken, err = tok.Token(); err != nil {
+ return nil, err
+ }
+
+ latestToken.SetAuthHeader(localVarRequest)
+ }
+
+ // Basic HTTP Authentication
+ if auth, ok := ctx.Value(ContextBasicAuth).(BasicAuth); ok {
+ localVarRequest.SetBasicAuth(auth.UserName, auth.Password)
+ }
+
+ // AccessToken Authentication
+ if auth, ok := ctx.Value(ContextAccessToken).(string); ok {
+ localVarRequest.Header.Add("Authorization", "Bearer "+auth)
+ }
+
+ }
+
+ for header, value := range c.cfg.DefaultHeader {
+ localVarRequest.Header.Add(header, value)
+ }
+ return localVarRequest, nil
+}
+
+func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) {
+ if len(b) == 0 {
+ return nil
+ }
+ if s, ok := v.(*string); ok {
+ *s = string(b)
+ return nil
+ }
+ if f, ok := v.(**os.File); ok {
+ *f, err = ioutil.TempFile("", "HttpClientFile")
+ if err != nil {
+ return
+ }
+ _, err = (*f).Write(b)
+ if err != nil {
+ return
+ }
+ _, err = (*f).Seek(0, io.SeekStart)
+ return
+ }
+ if xmlCheck.MatchString(contentType) {
+ if err = xml.Unmarshal(b, v); err != nil {
+ return err
+ }
+ return nil
+ }
+ if jsonCheck.MatchString(contentType) {
+ if actualObj, ok := v.(interface{ GetActualInstance() interface{} }); ok { // oneOf, anyOf schemas
+ if unmarshalObj, ok := actualObj.(interface{ UnmarshalJSON([]byte) error }); ok { // make sure it has UnmarshalJSON defined
+ if err = unmarshalObj.UnmarshalJSON(b); err != nil {
+ return err
+ }
+ } else {
+ return errors.New("Unknown type with GetActualInstance but no unmarshalObj.UnmarshalJSON defined")
+ }
+ } else if err = json.Unmarshal(b, v); err != nil { // simple model
+ return err
+ }
+ return nil
+ }
+ return errors.New("undefined response type")
+}
+
+// Add a file to the multipart request
+func addFile(w *multipart.Writer, fieldName, path string) error {
+ file, err := os.Open(filepath.Clean(path))
+ if err != nil {
+ return err
+ }
+ err = file.Close()
+ if err != nil {
+ return err
+ }
+
+ part, err := w.CreateFormFile(fieldName, filepath.Base(path))
+ if err != nil {
+ return err
+ }
+ _, err = io.Copy(part, file)
+
+ return err
+}
+
+// Prevent trying to import "fmt"
+func reportError(format string, a ...interface{}) error {
+ return fmt.Errorf(format, a...)
+}
+
+// A wrapper for strict JSON decoding
+func newStrictDecoder(data []byte) *json.Decoder {
+ dec := json.NewDecoder(bytes.NewBuffer(data))
+ dec.DisallowUnknownFields()
+ return dec
+}
+
+// Set request body from an interface{}
+func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) {
+ if bodyBuf == nil {
+ bodyBuf = &bytes.Buffer{}
+ }
+
+ if reader, ok := body.(io.Reader); ok {
+ _, err = bodyBuf.ReadFrom(reader)
+ } else if fp, ok := body.(**os.File); ok {
+ _, err = bodyBuf.ReadFrom(*fp)
+ } else if b, ok := body.([]byte); ok {
+ _, err = bodyBuf.Write(b)
+ } else if s, ok := body.(string); ok {
+ _, err = bodyBuf.WriteString(s)
+ } else if s, ok := body.(*string); ok {
+ _, err = bodyBuf.WriteString(*s)
+ } else if jsonCheck.MatchString(contentType) {
+ err = json.NewEncoder(bodyBuf).Encode(body)
+ } else if xmlCheck.MatchString(contentType) {
+ err = xml.NewEncoder(bodyBuf).Encode(body)
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ if bodyBuf.Len() == 0 {
+ err = fmt.Errorf("invalid body type %s\n", contentType)
+ return nil, err
+ }
+ return bodyBuf, nil
+}
+
+// detectContentType method is used to figure out `Request.Body` content type for request header
+func detectContentType(body interface{}) string {
+ contentType := "text/plain; charset=utf-8"
+ kind := reflect.TypeOf(body).Kind()
+
+ switch kind {
+ case reflect.Struct, reflect.Map, reflect.Ptr:
+ contentType = "application/json; charset=utf-8"
+ case reflect.String:
+ contentType = "text/plain; charset=utf-8"
+ default:
+ if b, ok := body.([]byte); ok {
+ contentType = http.DetectContentType(b)
+ } else if kind == reflect.Slice {
+ contentType = "application/json; charset=utf-8"
+ }
+ }
+
+ return contentType
+}
+
+// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go
+type cacheControl map[string]string
+
+func parseCacheControl(headers http.Header) cacheControl {
+ cc := cacheControl{}
+ ccHeader := headers.Get("Cache-Control")
+ for _, part := range strings.Split(ccHeader, ",") {
+ part = strings.Trim(part, " ")
+ if part == "" {
+ continue
+ }
+ if strings.ContainsRune(part, '=') {
+ keyval := strings.Split(part, "=")
+ cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",")
+ } else {
+ cc[part] = ""
+ }
+ }
+ return cc
+}
+
+// CacheExpires helper function to determine remaining time before repeating a request.
+func CacheExpires(r *http.Response) time.Time {
+ // Figure out when the cache expires.
+ var expires time.Time
+ now, err := time.Parse(time.RFC1123, r.Header.Get("date"))
+ if err != nil {
+ return time.Now()
+ }
+ respCacheControl := parseCacheControl(r.Header)
+
+ if maxAge, ok := respCacheControl["max-age"]; ok {
+ lifetime, err := time.ParseDuration(maxAge + "s")
+ if err != nil {
+ expires = now
+ } else {
+ expires = now.Add(lifetime)
+ }
+ } else {
+ expiresHeader := r.Header.Get("Expires")
+ if expiresHeader != "" {
+ expires, err = time.Parse(time.RFC1123, expiresHeader)
+ if err != nil {
+ expires = now
+ }
+ }
+ }
+ return expires
+}
+
+func strlen(s string) int {
+ return utf8.RuneCountInString(s)
+}
+
+// GenericOpenAPIError Provides access to the body, error and model on returned errors.
+type GenericOpenAPIError struct {
+ body []byte
+ error string
+ model interface{}
+}
+
+// Error returns non-empty string if there was an error.
+func (e GenericOpenAPIError) Error() string {
+ return e.error
+}
+
+// Body returns the raw bytes of the response
+func (e GenericOpenAPIError) Body() []byte {
+ return e.body
+}
+
+// Model returns the unpacked model of the error
+func (e GenericOpenAPIError) Model() interface{} {
+ return e.model
+}
+
+// format error message using title and detail when model implements rfc7807
+func formatErrorMessage(status string, v interface{}) string {
+
+ str := ""
+ metaValue := reflect.ValueOf(v).Elem()
+
+ field := metaValue.FieldByName("Title")
+ if field != (reflect.Value{}) {
+ str = fmt.Sprintf("%s", field.Interface())
+ }
+
+ field = metaValue.FieldByName("Detail")
+ if field != (reflect.Value{}) {
+ str = fmt.Sprintf("%s (%s)", str, field.Interface())
+ }
+
+ // status title (detail)
+ return fmt.Sprintf("%s %s", status, str)
+}
diff --git a/metric_ruleset/configuration.go b/metric_ruleset/configuration.go
new file mode 100644
index 0000000..0d0af48
--- /dev/null
+++ b/metric_ruleset/configuration.go
@@ -0,0 +1,230 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "context"
+ "fmt"
+ "net/http"
+ "strings"
+)
+
+// contextKeys are used to identify the type of value in the context.
+// Since these are string, it is possible to get a short description of the
+// context key for logging and debugging using key.String().
+
+type contextKey string
+
+func (c contextKey) String() string {
+ return "auth " + string(c)
+}
+
+var (
+ // ContextOAuth2 takes an oauth2.TokenSource as authentication for the request.
+ ContextOAuth2 = contextKey("token")
+
+ // ContextBasicAuth takes BasicAuth as authentication for the request.
+ ContextBasicAuth = contextKey("basic")
+
+ // ContextAccessToken takes a string oauth2 access token as authentication for the request.
+ ContextAccessToken = contextKey("accesstoken")
+
+ // ContextAPIKeys takes a string apikey as authentication for the request
+ ContextAPIKeys = contextKey("apiKeys")
+
+ // ContextHttpSignatureAuth takes HttpSignatureAuth as authentication for the request.
+ ContextHttpSignatureAuth = contextKey("httpsignature")
+
+ // ContextServerIndex uses a server configuration from the index.
+ ContextServerIndex = contextKey("serverIndex")
+
+ // ContextOperationServerIndices uses a server configuration from the index mapping.
+ ContextOperationServerIndices = contextKey("serverOperationIndices")
+
+ // ContextServerVariables overrides a server configuration variables.
+ ContextServerVariables = contextKey("serverVariables")
+
+ // ContextOperationServerVariables overrides a server configuration variables using operation specific values.
+ ContextOperationServerVariables = contextKey("serverOperationVariables")
+)
+
+// BasicAuth provides basic http authentication to a request passed via context using ContextBasicAuth
+type BasicAuth struct {
+ UserName string `json:"userName,omitempty"`
+ Password string `json:"password,omitempty"`
+}
+
+// APIKey provides API key based authentication to a request passed via context using ContextAPIKey
+type APIKey struct {
+ Key string
+ Prefix string
+}
+
+// ServerVariable stores the information about a server variable
+type ServerVariable struct {
+ Description string
+ DefaultValue string
+ EnumValues []string
+}
+
+// ServerConfiguration stores the information about a server
+type ServerConfiguration struct {
+ URL string
+ Description string
+ Variables map[string]ServerVariable
+}
+
+// ServerConfigurations stores multiple ServerConfiguration items
+type ServerConfigurations []ServerConfiguration
+
+// Configuration stores the configuration of the API client
+type Configuration struct {
+ Host string `json:"host,omitempty"`
+ Scheme string `json:"scheme,omitempty"`
+ DefaultHeader map[string]string `json:"defaultHeader,omitempty"`
+ UserAgent string `json:"userAgent,omitempty"`
+ Debug bool `json:"debug,omitempty"`
+ Servers ServerConfigurations
+ OperationServers map[string]ServerConfigurations
+ HTTPClient *http.Client
+}
+
+// NewConfiguration returns a new Configuration object
+func NewConfiguration() *Configuration {
+ cfg := &Configuration{
+ DefaultHeader: make(map[string]string),
+ UserAgent: "OpenAPI-Generator/1.0.0/go",
+ Debug: false,
+ Servers: ServerConfigurations{
+ {
+ URL: "https://api.{REALM}.signalfx.com/v2",
+ Description: "Base API endpoint URL for metric ruleset ",
+ },
+ },
+ OperationServers: map[string]ServerConfigurations{
+ },
+ }
+ return cfg
+}
+
+// AddDefaultHeader adds a new HTTP header to the default header in the request
+func (c *Configuration) AddDefaultHeader(key string, value string) {
+ c.DefaultHeader[key] = value
+}
+
+// URL formats template on a index using given variables
+func (sc ServerConfigurations) URL(index int, variables map[string]string) (string, error) {
+ if index < 0 || len(sc) <= index {
+ return "", fmt.Errorf("index %v out of range %v", index, len(sc)-1)
+ }
+ server := sc[index]
+ url := server.URL
+
+ // go through variables and replace placeholders
+ for name, variable := range server.Variables {
+ if value, ok := variables[name]; ok {
+ found := bool(len(variable.EnumValues) == 0)
+ for _, enumValue := range variable.EnumValues {
+ if value == enumValue {
+ found = true
+ }
+ }
+ if !found {
+ return "", fmt.Errorf("the variable %s in the server URL has invalid value %v. Must be %v", name, value, variable.EnumValues)
+ }
+ url = strings.Replace(url, "{"+name+"}", value, -1)
+ } else {
+ url = strings.Replace(url, "{"+name+"}", variable.DefaultValue, -1)
+ }
+ }
+ return url, nil
+}
+
+// ServerURL returns URL based on server settings
+func (c *Configuration) ServerURL(index int, variables map[string]string) (string, error) {
+ return c.Servers.URL(index, variables)
+}
+
+func getServerIndex(ctx context.Context) (int, error) {
+ si := ctx.Value(ContextServerIndex)
+ if si != nil {
+ if index, ok := si.(int); ok {
+ return index, nil
+ }
+ return 0, reportError("Invalid type %T should be int", si)
+ }
+ return 0, nil
+}
+
+func getServerOperationIndex(ctx context.Context, endpoint string) (int, error) {
+ osi := ctx.Value(ContextOperationServerIndices)
+ if osi != nil {
+ if operationIndices, ok := osi.(map[string]int); !ok {
+ return 0, reportError("Invalid type %T should be map[string]int", osi)
+ } else {
+ index, ok := operationIndices[endpoint]
+ if ok {
+ return index, nil
+ }
+ }
+ }
+ return getServerIndex(ctx)
+}
+
+func getServerVariables(ctx context.Context) (map[string]string, error) {
+ sv := ctx.Value(ContextServerVariables)
+ if sv != nil {
+ if variables, ok := sv.(map[string]string); ok {
+ return variables, nil
+ }
+ return nil, reportError("ctx value of ContextServerVariables has invalid type %T should be map[string]string", sv)
+ }
+ return nil, nil
+}
+
+func getServerOperationVariables(ctx context.Context, endpoint string) (map[string]string, error) {
+ osv := ctx.Value(ContextOperationServerVariables)
+ if osv != nil {
+ if operationVariables, ok := osv.(map[string]map[string]string); !ok {
+ return nil, reportError("ctx value of ContextOperationServerVariables has invalid type %T should be map[string]map[string]string", osv)
+ } else {
+ variables, ok := operationVariables[endpoint]
+ if ok {
+ return variables, nil
+ }
+ }
+ }
+ return getServerVariables(ctx)
+}
+
+// ServerURLWithContext returns a new server URL given an endpoint
+func (c *Configuration) ServerURLWithContext(ctx context.Context, endpoint string) (string, error) {
+ sc, ok := c.OperationServers[endpoint]
+ if !ok {
+ sc = c.Servers
+ }
+
+ if ctx == nil {
+ return sc.URL(0, nil)
+ }
+
+ index, err := getServerOperationIndex(ctx, endpoint)
+ if err != nil {
+ return "", err
+ }
+
+ variables, err := getServerOperationVariables(ctx, endpoint)
+ if err != nil {
+ return "", err
+ }
+
+ return sc.URL(index, variables)
+}
diff --git a/metric_ruleset/model_aggregation_rule.go b/metric_ruleset/model_aggregation_rule.go
new file mode 100644
index 0000000..5eaf881
--- /dev/null
+++ b/metric_ruleset/model_aggregation_rule.go
@@ -0,0 +1,210 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+)
+
+// AggregationRule A single aggregation rule in a metric ruleset
+type AggregationRule struct {
+ // Name of the aggregation rule
+ Name *string `json:"name,omitempty"`
+ Matcher MetricMatcher `json:"matcher"`
+ // Status of this aggregation rule
+ Enabled bool `json:"enabled"`
+ Aggregator MetricAggregator `json:"aggregator"`
+}
+
+// NewAggregationRule instantiates a new AggregationRule object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed
+func NewAggregationRule(matcher MetricMatcher, enabled bool, aggregator MetricAggregator) *AggregationRule {
+ this := AggregationRule{}
+ var name string = ""
+ this.Name = &name
+ this.Matcher = matcher
+ this.Enabled = enabled
+ this.Aggregator = aggregator
+ return &this
+}
+
+// NewAggregationRuleWithDefaults instantiates a new AggregationRule object
+// This constructor will only assign default values to properties that have it defined,
+// but it doesn't guarantee that properties required by API are set
+func NewAggregationRuleWithDefaults() *AggregationRule {
+ this := AggregationRule{}
+ var name string = ""
+ this.Name = &name
+ var enabled bool = false
+ this.Enabled = enabled
+ return &this
+}
+
+// GetName returns the Name field value if set, zero value otherwise.
+func (o *AggregationRule) GetName() string {
+ if o == nil || isNil(o.Name) {
+ var ret string
+ return ret
+ }
+ return *o.Name
+}
+
+// GetNameOk returns a tuple with the Name field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *AggregationRule) GetNameOk() (*string, bool) {
+ if o == nil || isNil(o.Name) {
+ return nil, false
+ }
+ return o.Name, true
+}
+
+// HasName returns a boolean if a field has been set.
+func (o *AggregationRule) HasName() bool {
+ if o != nil && !isNil(o.Name) {
+ return true
+ }
+
+ return false
+}
+
+// SetName gets a reference to the given string and assigns it to the Name field.
+func (o *AggregationRule) SetName(v string) {
+ o.Name = &v
+}
+
+// GetMatcher returns the Matcher field value
+func (o *AggregationRule) GetMatcher() MetricMatcher {
+ if o == nil {
+ var ret MetricMatcher
+ return ret
+ }
+
+ return o.Matcher
+}
+
+// GetMatcherOk returns a tuple with the Matcher field value
+// and a boolean to check if the value has been set.
+func (o *AggregationRule) GetMatcherOk() (*MetricMatcher, bool) {
+ if o == nil {
+ return nil, false
+ }
+ return &o.Matcher, true
+}
+
+// SetMatcher sets field value
+func (o *AggregationRule) SetMatcher(v MetricMatcher) {
+ o.Matcher = v
+}
+
+// GetEnabled returns the Enabled field value
+func (o *AggregationRule) GetEnabled() bool {
+ if o == nil {
+ var ret bool
+ return ret
+ }
+
+ return o.Enabled
+}
+
+// GetEnabledOk returns a tuple with the Enabled field value
+// and a boolean to check if the value has been set.
+func (o *AggregationRule) GetEnabledOk() (*bool, bool) {
+ if o == nil {
+ return nil, false
+ }
+ return &o.Enabled, true
+}
+
+// SetEnabled sets field value
+func (o *AggregationRule) SetEnabled(v bool) {
+ o.Enabled = v
+}
+
+// GetAggregator returns the Aggregator field value
+func (o *AggregationRule) GetAggregator() MetricAggregator {
+ if o == nil {
+ var ret MetricAggregator
+ return ret
+ }
+
+ return o.Aggregator
+}
+
+// GetAggregatorOk returns a tuple with the Aggregator field value
+// and a boolean to check if the value has been set.
+func (o *AggregationRule) GetAggregatorOk() (*MetricAggregator, bool) {
+ if o == nil {
+ return nil, false
+ }
+ return &o.Aggregator, true
+}
+
+// SetAggregator sets field value
+func (o *AggregationRule) SetAggregator(v MetricAggregator) {
+ o.Aggregator = v
+}
+
+func (o AggregationRule) MarshalJSON() ([]byte, error) {
+ toSerialize := map[string]interface{}{}
+ if !isNil(o.Name) {
+ toSerialize["name"] = o.Name
+ }
+ if true {
+ toSerialize["matcher"] = o.Matcher
+ }
+ if true {
+ toSerialize["enabled"] = o.Enabled
+ }
+ if true {
+ toSerialize["aggregator"] = o.Aggregator
+ }
+ return json.Marshal(toSerialize)
+}
+
+type NullableAggregationRule struct {
+ value *AggregationRule
+ isSet bool
+}
+
+func (v NullableAggregationRule) Get() *AggregationRule {
+ return v.value
+}
+
+func (v *NullableAggregationRule) Set(val *AggregationRule) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableAggregationRule) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableAggregationRule) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableAggregationRule(val *AggregationRule) *NullableAggregationRule {
+ return &NullableAggregationRule{value: val, isSet: true}
+}
+
+func (v NullableAggregationRule) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableAggregationRule) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/model_create_metric_ruleset_request.go b/metric_ruleset/model_create_metric_ruleset_request.go
new file mode 100644
index 0000000..bafaeb1
--- /dev/null
+++ b/metric_ruleset/model_create_metric_ruleset_request.go
@@ -0,0 +1,205 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+)
+
+// CreateMetricRulesetRequest Create metric ruleset request body
+type CreateMetricRulesetRequest struct {
+ // Aggregation rules in the ruleset
+ AggregationRules []AggregationRule `json:"aggregationRules,omitempty"`
+ // Name of the metric
+ MetricName string `json:"metricName"`
+ RoutingRule RoutingRule `json:"routingRule"`
+ // Version of the ruleset
+ Version int64 `json:"version"`
+}
+
+// NewCreateMetricRulesetRequest instantiates a new CreateMetricRulesetRequest object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed
+func NewCreateMetricRulesetRequest(metricName string, routingRule RoutingRule, version int64) *CreateMetricRulesetRequest {
+ this := CreateMetricRulesetRequest{}
+ this.MetricName = metricName
+ this.RoutingRule = routingRule
+ this.Version = version
+ return &this
+}
+
+// NewCreateMetricRulesetRequestWithDefaults instantiates a new CreateMetricRulesetRequest object
+// This constructor will only assign default values to properties that have it defined,
+// but it doesn't guarantee that properties required by API are set
+func NewCreateMetricRulesetRequestWithDefaults() *CreateMetricRulesetRequest {
+ this := CreateMetricRulesetRequest{}
+ return &this
+}
+
+// GetAggregationRules returns the AggregationRules field value if set, zero value otherwise.
+func (o *CreateMetricRulesetRequest) GetAggregationRules() []AggregationRule {
+ if o == nil || isNil(o.AggregationRules) {
+ var ret []AggregationRule
+ return ret
+ }
+ return o.AggregationRules
+}
+
+// GetAggregationRulesOk returns a tuple with the AggregationRules field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetRequest) GetAggregationRulesOk() ([]AggregationRule, bool) {
+ if o == nil || isNil(o.AggregationRules) {
+ return nil, false
+ }
+ return o.AggregationRules, true
+}
+
+// HasAggregationRules returns a boolean if a field has been set.
+func (o *CreateMetricRulesetRequest) HasAggregationRules() bool {
+ if o != nil && !isNil(o.AggregationRules) {
+ return true
+ }
+
+ return false
+}
+
+// SetAggregationRules gets a reference to the given []AggregationRule and assigns it to the AggregationRules field.
+func (o *CreateMetricRulesetRequest) SetAggregationRules(v []AggregationRule) {
+ o.AggregationRules = v
+}
+
+// GetMetricName returns the MetricName field value
+func (o *CreateMetricRulesetRequest) GetMetricName() string {
+ if o == nil {
+ var ret string
+ return ret
+ }
+
+ return o.MetricName
+}
+
+// GetMetricNameOk returns a tuple with the MetricName field value
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetRequest) GetMetricNameOk() (*string, bool) {
+ if o == nil {
+ return nil, false
+ }
+ return &o.MetricName, true
+}
+
+// SetMetricName sets field value
+func (o *CreateMetricRulesetRequest) SetMetricName(v string) {
+ o.MetricName = v
+}
+
+// GetRoutingRule returns the RoutingRule field value
+func (o *CreateMetricRulesetRequest) GetRoutingRule() RoutingRule {
+ if o == nil {
+ var ret RoutingRule
+ return ret
+ }
+
+ return o.RoutingRule
+}
+
+// GetRoutingRuleOk returns a tuple with the RoutingRule field value
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetRequest) GetRoutingRuleOk() (*RoutingRule, bool) {
+ if o == nil {
+ return nil, false
+ }
+ return &o.RoutingRule, true
+}
+
+// SetRoutingRule sets field value
+func (o *CreateMetricRulesetRequest) SetRoutingRule(v RoutingRule) {
+ o.RoutingRule = v
+}
+
+// GetVersion returns the Version field value
+func (o *CreateMetricRulesetRequest) GetVersion() int64 {
+ if o == nil {
+ var ret int64
+ return ret
+ }
+
+ return o.Version
+}
+
+// GetVersionOk returns a tuple with the Version field value
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetRequest) GetVersionOk() (*int64, bool) {
+ if o == nil {
+ return nil, false
+ }
+ return &o.Version, true
+}
+
+// SetVersion sets field value
+func (o *CreateMetricRulesetRequest) SetVersion(v int64) {
+ o.Version = v
+}
+
+func (o CreateMetricRulesetRequest) MarshalJSON() ([]byte, error) {
+ toSerialize := map[string]interface{}{}
+ if !isNil(o.AggregationRules) {
+ toSerialize["aggregationRules"] = o.AggregationRules
+ }
+ if true {
+ toSerialize["metricName"] = o.MetricName
+ }
+ if true {
+ toSerialize["routingRule"] = o.RoutingRule
+ }
+ if true {
+ toSerialize["version"] = o.Version
+ }
+ return json.Marshal(toSerialize)
+}
+
+type NullableCreateMetricRulesetRequest struct {
+ value *CreateMetricRulesetRequest
+ isSet bool
+}
+
+func (v NullableCreateMetricRulesetRequest) Get() *CreateMetricRulesetRequest {
+ return v.value
+}
+
+func (v *NullableCreateMetricRulesetRequest) Set(val *CreateMetricRulesetRequest) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableCreateMetricRulesetRequest) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableCreateMetricRulesetRequest) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableCreateMetricRulesetRequest(val *CreateMetricRulesetRequest) *NullableCreateMetricRulesetRequest {
+ return &NullableCreateMetricRulesetRequest{value: val, isSet: true}
+}
+
+func (v NullableCreateMetricRulesetRequest) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableCreateMetricRulesetRequest) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/model_create_metric_ruleset_response.go b/metric_ruleset/model_create_metric_ruleset_response.go
new file mode 100644
index 0000000..18d7fb6
--- /dev/null
+++ b/metric_ruleset/model_create_metric_ruleset_response.go
@@ -0,0 +1,485 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+)
+
+// CreateMetricRulesetResponse Create metric ruleset response body
+type CreateMetricRulesetResponse struct {
+ // Aggregation rules in the ruleset
+ AggregationRules []AggregationRule `json:"aggregationRules,omitempty"`
+ // User ID of the user who created this metric ruleset
+ Creator *string `json:"creator,omitempty"`
+ // Name of the user who created this metric ruleset
+ CreatorName *string `json:"creatorName,omitempty"`
+ // Date and time when this ruleset was created
+ Created *int64 `json:"created,omitempty"`
+ // Ruleset ID
+ Id *string `json:"id,omitempty"`
+ // ID of the user who last updated the ruleset
+ LastUpdatedBy *string `json:"lastUpdatedBy,omitempty"`
+ // Name of the user who last updated the ruleset
+ LastUpdatedByName *string `json:"lastUpdatedByName,omitempty"`
+ // Time at which this ruleset was last updated
+ LastUpdated *int64 `json:"lastUpdated,omitempty"`
+ // Name of the metric
+ MetricName *string `json:"metricName,omitempty"`
+ RoutingRule *RoutingRule `json:"routingRule,omitempty"`
+ // Version of the ruleset
+ Version *int64 `json:"version,omitempty"`
+}
+
+// NewCreateMetricRulesetResponse instantiates a new CreateMetricRulesetResponse object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed
+func NewCreateMetricRulesetResponse() *CreateMetricRulesetResponse {
+ this := CreateMetricRulesetResponse{}
+ return &this
+}
+
+// NewCreateMetricRulesetResponseWithDefaults instantiates a new CreateMetricRulesetResponse object
+// This constructor will only assign default values to properties that have it defined,
+// but it doesn't guarantee that properties required by API are set
+func NewCreateMetricRulesetResponseWithDefaults() *CreateMetricRulesetResponse {
+ this := CreateMetricRulesetResponse{}
+ return &this
+}
+
+// GetAggregationRules returns the AggregationRules field value if set, zero value otherwise.
+func (o *CreateMetricRulesetResponse) GetAggregationRules() []AggregationRule {
+ if o == nil || isNil(o.AggregationRules) {
+ var ret []AggregationRule
+ return ret
+ }
+ return o.AggregationRules
+}
+
+// GetAggregationRulesOk returns a tuple with the AggregationRules field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetResponse) GetAggregationRulesOk() ([]AggregationRule, bool) {
+ if o == nil || isNil(o.AggregationRules) {
+ return nil, false
+ }
+ return o.AggregationRules, true
+}
+
+// HasAggregationRules returns a boolean if a field has been set.
+func (o *CreateMetricRulesetResponse) HasAggregationRules() bool {
+ if o != nil && !isNil(o.AggregationRules) {
+ return true
+ }
+
+ return false
+}
+
+// SetAggregationRules gets a reference to the given []AggregationRule and assigns it to the AggregationRules field.
+func (o *CreateMetricRulesetResponse) SetAggregationRules(v []AggregationRule) {
+ o.AggregationRules = v
+}
+
+// GetCreator returns the Creator field value if set, zero value otherwise.
+func (o *CreateMetricRulesetResponse) GetCreator() string {
+ if o == nil || isNil(o.Creator) {
+ var ret string
+ return ret
+ }
+ return *o.Creator
+}
+
+// GetCreatorOk returns a tuple with the Creator field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetResponse) GetCreatorOk() (*string, bool) {
+ if o == nil || isNil(o.Creator) {
+ return nil, false
+ }
+ return o.Creator, true
+}
+
+// HasCreator returns a boolean if a field has been set.
+func (o *CreateMetricRulesetResponse) HasCreator() bool {
+ if o != nil && !isNil(o.Creator) {
+ return true
+ }
+
+ return false
+}
+
+// SetCreator gets a reference to the given string and assigns it to the Creator field.
+func (o *CreateMetricRulesetResponse) SetCreator(v string) {
+ o.Creator = &v
+}
+
+// GetCreatorName returns the CreatorName field value if set, zero value otherwise.
+func (o *CreateMetricRulesetResponse) GetCreatorName() string {
+ if o == nil || isNil(o.CreatorName) {
+ var ret string
+ return ret
+ }
+ return *o.CreatorName
+}
+
+// GetCreatorNameOk returns a tuple with the CreatorName field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetResponse) GetCreatorNameOk() (*string, bool) {
+ if o == nil || isNil(o.CreatorName) {
+ return nil, false
+ }
+ return o.CreatorName, true
+}
+
+// HasCreatorName returns a boolean if a field has been set.
+func (o *CreateMetricRulesetResponse) HasCreatorName() bool {
+ if o != nil && !isNil(o.CreatorName) {
+ return true
+ }
+
+ return false
+}
+
+// SetCreatorName gets a reference to the given string and assigns it to the CreatorName field.
+func (o *CreateMetricRulesetResponse) SetCreatorName(v string) {
+ o.CreatorName = &v
+}
+
+// GetCreated returns the Created field value if set, zero value otherwise.
+func (o *CreateMetricRulesetResponse) GetCreated() int64 {
+ if o == nil || isNil(o.Created) {
+ var ret int64
+ return ret
+ }
+ return *o.Created
+}
+
+// GetCreatedOk returns a tuple with the Created field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetResponse) GetCreatedOk() (*int64, bool) {
+ if o == nil || isNil(o.Created) {
+ return nil, false
+ }
+ return o.Created, true
+}
+
+// HasCreated returns a boolean if a field has been set.
+func (o *CreateMetricRulesetResponse) HasCreated() bool {
+ if o != nil && !isNil(o.Created) {
+ return true
+ }
+
+ return false
+}
+
+// SetCreated gets a reference to the given int64 and assigns it to the Created field.
+func (o *CreateMetricRulesetResponse) SetCreated(v int64) {
+ o.Created = &v
+}
+
+// GetId returns the Id field value if set, zero value otherwise.
+func (o *CreateMetricRulesetResponse) GetId() string {
+ if o == nil || isNil(o.Id) {
+ var ret string
+ return ret
+ }
+ return *o.Id
+}
+
+// GetIdOk returns a tuple with the Id field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetResponse) GetIdOk() (*string, bool) {
+ if o == nil || isNil(o.Id) {
+ return nil, false
+ }
+ return o.Id, true
+}
+
+// HasId returns a boolean if a field has been set.
+func (o *CreateMetricRulesetResponse) HasId() bool {
+ if o != nil && !isNil(o.Id) {
+ return true
+ }
+
+ return false
+}
+
+// SetId gets a reference to the given string and assigns it to the Id field.
+func (o *CreateMetricRulesetResponse) SetId(v string) {
+ o.Id = &v
+}
+
+// GetLastUpdatedBy returns the LastUpdatedBy field value if set, zero value otherwise.
+func (o *CreateMetricRulesetResponse) GetLastUpdatedBy() string {
+ if o == nil || isNil(o.LastUpdatedBy) {
+ var ret string
+ return ret
+ }
+ return *o.LastUpdatedBy
+}
+
+// GetLastUpdatedByOk returns a tuple with the LastUpdatedBy field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetResponse) GetLastUpdatedByOk() (*string, bool) {
+ if o == nil || isNil(o.LastUpdatedBy) {
+ return nil, false
+ }
+ return o.LastUpdatedBy, true
+}
+
+// HasLastUpdatedBy returns a boolean if a field has been set.
+func (o *CreateMetricRulesetResponse) HasLastUpdatedBy() bool {
+ if o != nil && !isNil(o.LastUpdatedBy) {
+ return true
+ }
+
+ return false
+}
+
+// SetLastUpdatedBy gets a reference to the given string and assigns it to the LastUpdatedBy field.
+func (o *CreateMetricRulesetResponse) SetLastUpdatedBy(v string) {
+ o.LastUpdatedBy = &v
+}
+
+// GetLastUpdatedByName returns the LastUpdatedByName field value if set, zero value otherwise.
+func (o *CreateMetricRulesetResponse) GetLastUpdatedByName() string {
+ if o == nil || isNil(o.LastUpdatedByName) {
+ var ret string
+ return ret
+ }
+ return *o.LastUpdatedByName
+}
+
+// GetLastUpdatedByNameOk returns a tuple with the LastUpdatedByName field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetResponse) GetLastUpdatedByNameOk() (*string, bool) {
+ if o == nil || isNil(o.LastUpdatedByName) {
+ return nil, false
+ }
+ return o.LastUpdatedByName, true
+}
+
+// HasLastUpdatedByName returns a boolean if a field has been set.
+func (o *CreateMetricRulesetResponse) HasLastUpdatedByName() bool {
+ if o != nil && !isNil(o.LastUpdatedByName) {
+ return true
+ }
+
+ return false
+}
+
+// SetLastUpdatedByName gets a reference to the given string and assigns it to the LastUpdatedByName field.
+func (o *CreateMetricRulesetResponse) SetLastUpdatedByName(v string) {
+ o.LastUpdatedByName = &v
+}
+
+// GetLastUpdated returns the LastUpdated field value if set, zero value otherwise.
+func (o *CreateMetricRulesetResponse) GetLastUpdated() int64 {
+ if o == nil || isNil(o.LastUpdated) {
+ var ret int64
+ return ret
+ }
+ return *o.LastUpdated
+}
+
+// GetLastUpdatedOk returns a tuple with the LastUpdated field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetResponse) GetLastUpdatedOk() (*int64, bool) {
+ if o == nil || isNil(o.LastUpdated) {
+ return nil, false
+ }
+ return o.LastUpdated, true
+}
+
+// HasLastUpdated returns a boolean if a field has been set.
+func (o *CreateMetricRulesetResponse) HasLastUpdated() bool {
+ if o != nil && !isNil(o.LastUpdated) {
+ return true
+ }
+
+ return false
+}
+
+// SetLastUpdated gets a reference to the given int64 and assigns it to the LastUpdated field.
+func (o *CreateMetricRulesetResponse) SetLastUpdated(v int64) {
+ o.LastUpdated = &v
+}
+
+// GetMetricName returns the MetricName field value if set, zero value otherwise.
+func (o *CreateMetricRulesetResponse) GetMetricName() string {
+ if o == nil || isNil(o.MetricName) {
+ var ret string
+ return ret
+ }
+ return *o.MetricName
+}
+
+// GetMetricNameOk returns a tuple with the MetricName field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetResponse) GetMetricNameOk() (*string, bool) {
+ if o == nil || isNil(o.MetricName) {
+ return nil, false
+ }
+ return o.MetricName, true
+}
+
+// HasMetricName returns a boolean if a field has been set.
+func (o *CreateMetricRulesetResponse) HasMetricName() bool {
+ if o != nil && !isNil(o.MetricName) {
+ return true
+ }
+
+ return false
+}
+
+// SetMetricName gets a reference to the given string and assigns it to the MetricName field.
+func (o *CreateMetricRulesetResponse) SetMetricName(v string) {
+ o.MetricName = &v
+}
+
+// GetRoutingRule returns the RoutingRule field value if set, zero value otherwise.
+func (o *CreateMetricRulesetResponse) GetRoutingRule() RoutingRule {
+ if o == nil || isNil(o.RoutingRule) {
+ var ret RoutingRule
+ return ret
+ }
+ return *o.RoutingRule
+}
+
+// GetRoutingRuleOk returns a tuple with the RoutingRule field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetResponse) GetRoutingRuleOk() (*RoutingRule, bool) {
+ if o == nil || isNil(o.RoutingRule) {
+ return nil, false
+ }
+ return o.RoutingRule, true
+}
+
+// HasRoutingRule returns a boolean if a field has been set.
+func (o *CreateMetricRulesetResponse) HasRoutingRule() bool {
+ if o != nil && !isNil(o.RoutingRule) {
+ return true
+ }
+
+ return false
+}
+
+// SetRoutingRule gets a reference to the given RoutingRule and assigns it to the RoutingRule field.
+func (o *CreateMetricRulesetResponse) SetRoutingRule(v RoutingRule) {
+ o.RoutingRule = &v
+}
+
+// GetVersion returns the Version field value if set, zero value otherwise.
+func (o *CreateMetricRulesetResponse) GetVersion() int64 {
+ if o == nil || isNil(o.Version) {
+ var ret int64
+ return ret
+ }
+ return *o.Version
+}
+
+// GetVersionOk returns a tuple with the Version field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *CreateMetricRulesetResponse) GetVersionOk() (*int64, bool) {
+ if o == nil || isNil(o.Version) {
+ return nil, false
+ }
+ return o.Version, true
+}
+
+// HasVersion returns a boolean if a field has been set.
+func (o *CreateMetricRulesetResponse) HasVersion() bool {
+ if o != nil && !isNil(o.Version) {
+ return true
+ }
+
+ return false
+}
+
+// SetVersion gets a reference to the given int64 and assigns it to the Version field.
+func (o *CreateMetricRulesetResponse) SetVersion(v int64) {
+ o.Version = &v
+}
+
+func (o CreateMetricRulesetResponse) MarshalJSON() ([]byte, error) {
+ toSerialize := map[string]interface{}{}
+ if !isNil(o.AggregationRules) {
+ toSerialize["aggregationRules"] = o.AggregationRules
+ }
+ if !isNil(o.Creator) {
+ toSerialize["creator"] = o.Creator
+ }
+ if !isNil(o.CreatorName) {
+ toSerialize["creatorName"] = o.CreatorName
+ }
+ if !isNil(o.Created) {
+ toSerialize["created"] = o.Created
+ }
+ if !isNil(o.Id) {
+ toSerialize["id"] = o.Id
+ }
+ if !isNil(o.LastUpdatedBy) {
+ toSerialize["lastUpdatedBy"] = o.LastUpdatedBy
+ }
+ if !isNil(o.LastUpdatedByName) {
+ toSerialize["lastUpdatedByName"] = o.LastUpdatedByName
+ }
+ if !isNil(o.LastUpdated) {
+ toSerialize["lastUpdated"] = o.LastUpdated
+ }
+ if !isNil(o.MetricName) {
+ toSerialize["metricName"] = o.MetricName
+ }
+ if !isNil(o.RoutingRule) {
+ toSerialize["routingRule"] = o.RoutingRule
+ }
+ if !isNil(o.Version) {
+ toSerialize["version"] = o.Version
+ }
+ return json.Marshal(toSerialize)
+}
+
+type NullableCreateMetricRulesetResponse struct {
+ value *CreateMetricRulesetResponse
+ isSet bool
+}
+
+func (v NullableCreateMetricRulesetResponse) Get() *CreateMetricRulesetResponse {
+ return v.value
+}
+
+func (v *NullableCreateMetricRulesetResponse) Set(val *CreateMetricRulesetResponse) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableCreateMetricRulesetResponse) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableCreateMetricRulesetResponse) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableCreateMetricRulesetResponse(val *CreateMetricRulesetResponse) *NullableCreateMetricRulesetResponse {
+ return &NullableCreateMetricRulesetResponse{value: val, isSet: true}
+}
+
+func (v NullableCreateMetricRulesetResponse) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableCreateMetricRulesetResponse) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/model_destination.go b/metric_ruleset/model_destination.go
new file mode 100644
index 0000000..79849c0
--- /dev/null
+++ b/metric_ruleset/model_destination.go
@@ -0,0 +1,56 @@
+/*
+Metric Ingest Ruleset API
+
+Metric ingest ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+// Destination The routing destination for your data points
+type Destination string
+
+// List of Destination
+const (
+ UNKNOWN Destination = "Unknown"
+ REALTIME_13_MO Destination = "Realtime_13MO"
+ REALTIME_3_MO Destination = "Realtime_3MO"
+ HCM Destination = "HCM"
+ FULL_FIDELITY Destination = "FullFidelity"
+ DROP Destination = "Drop"
+)
+
+// All allowed values of Destination enum
+var AllowedDestinationEnumValues = []Destination{
+ "Unknown",
+ "Realtime_13MO",
+ "Realtime_3MO",
+ "HCM",
+ "FullFidelity",
+ "Drop",
+}
+
+func (v *Destination) UnmarshalJSON(src []byte) error {
+ var value string
+ err := json.Unmarshal(src, &value)
+ if err != nil {
+ return err
+ }
+ enumTypeValue := Destination(value)
+ for _, existing := range AllowedDestinationEnumValues {
+ if existing == enumTypeValue {
+ *v = enumTypeValue
+ return nil
+ }
+ }
+
+ return fmt.Errorf("%+v is not a valid Destination", value)
+}
diff --git a/metric_ruleset/model_dimension_matcher.go b/metric_ruleset/model_dimension_matcher.go
new file mode 100644
index 0000000..a5409e0
--- /dev/null
+++ b/metric_ruleset/model_dimension_matcher.go
@@ -0,0 +1,146 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+)
+
+// DimensionMatcher Dimension metric matcher
+type DimensionMatcher struct {
+ // Matcher rule type
+ Type string `json:"type"`
+ // List of filters you want to apply to your metric
+ Filters []PropertyFilter `json:"filters,omitempty"`
+}
+
+// NewDimensionMatcher instantiates a new DimensionMatcher object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed
+func NewDimensionMatcher(type_ string) *DimensionMatcher {
+ this := DimensionMatcher{}
+ this.Type = type_
+ return &this
+}
+
+// NewDimensionMatcherWithDefaults instantiates a new DimensionMatcher object
+// This constructor will only assign default values to properties that have it defined,
+// but it doesn't guarantee that properties required by API are set
+func NewDimensionMatcherWithDefaults() *DimensionMatcher {
+ this := DimensionMatcher{}
+ return &this
+}
+
+// GetType returns the Type field value
+func (o *DimensionMatcher) GetType() string {
+ if o == nil {
+ var ret string
+ return ret
+ }
+
+ return o.Type
+}
+
+// GetTypeOk returns a tuple with the Type field value
+// and a boolean to check if the value has been set.
+func (o *DimensionMatcher) GetTypeOk() (*string, bool) {
+ if o == nil {
+ return nil, false
+ }
+ return &o.Type, true
+}
+
+// SetType sets field value
+func (o *DimensionMatcher) SetType(v string) {
+ o.Type = v
+}
+
+// GetFilters returns the Filters field value if set, zero value otherwise.
+func (o *DimensionMatcher) GetFilters() []PropertyFilter {
+ if o == nil || isNil(o.Filters) {
+ var ret []PropertyFilter
+ return ret
+ }
+ return o.Filters
+}
+
+// GetFiltersOk returns a tuple with the Filters field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *DimensionMatcher) GetFiltersOk() ([]PropertyFilter, bool) {
+ if o == nil || isNil(o.Filters) {
+ return nil, false
+ }
+ return o.Filters, true
+}
+
+// HasFilters returns a boolean if a field has been set.
+func (o *DimensionMatcher) HasFilters() bool {
+ if o != nil && !isNil(o.Filters) {
+ return true
+ }
+
+ return false
+}
+
+// SetFilters gets a reference to the given []PropertyFilter and assigns it to the Filters field.
+func (o *DimensionMatcher) SetFilters(v []PropertyFilter) {
+ o.Filters = v
+}
+
+func (o DimensionMatcher) MarshalJSON() ([]byte, error) {
+ toSerialize := map[string]interface{}{}
+ if true {
+ toSerialize["type"] = o.Type
+ }
+ if !isNil(o.Filters) {
+ toSerialize["filters"] = o.Filters
+ }
+ return json.Marshal(toSerialize)
+}
+
+type NullableDimensionMatcher struct {
+ value *DimensionMatcher
+ isSet bool
+}
+
+func (v NullableDimensionMatcher) Get() *DimensionMatcher {
+ return v.value
+}
+
+func (v *NullableDimensionMatcher) Set(val *DimensionMatcher) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableDimensionMatcher) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableDimensionMatcher) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableDimensionMatcher(val *DimensionMatcher) *NullableDimensionMatcher {
+ return &NullableDimensionMatcher{value: val, isSet: true}
+}
+
+func (v NullableDimensionMatcher) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableDimensionMatcher) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/model_generate_aggregation_name_request.go b/metric_ruleset/model_generate_aggregation_name_request.go
new file mode 100644
index 0000000..8a997ad
--- /dev/null
+++ b/metric_ruleset/model_generate_aggregation_name_request.go
@@ -0,0 +1,176 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+)
+
+// GenerateAggregationNameRequest Request body for Generate Aggregated Metric Name
+type GenerateAggregationNameRequest struct {
+ // Name of the metric
+ MetricName string `json:"metricName"`
+ // Dimensions you want to keep in the aggregation rule
+ Dimensions []string `json:"dimensions"`
+ // Flag toggling if the dimensions are being dropped
+ DropDimensions *bool `json:"dropDimensions,omitempty"`
+}
+
+// NewGenerateAggregationNameRequest instantiates a new GenerateAggregationNameRequest object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed
+func NewGenerateAggregationNameRequest(metricName string, dimensions []string) *GenerateAggregationNameRequest {
+ this := GenerateAggregationNameRequest{}
+ this.MetricName = metricName
+ this.Dimensions = dimensions
+ return &this
+}
+
+// NewGenerateAggregationNameRequestWithDefaults instantiates a new GenerateAggregationNameRequest object
+// This constructor will only assign default values to properties that have it defined,
+// but it doesn't guarantee that properties required by API are set
+func NewGenerateAggregationNameRequestWithDefaults() *GenerateAggregationNameRequest {
+ this := GenerateAggregationNameRequest{}
+ return &this
+}
+
+// GetMetricName returns the MetricName field value
+func (o *GenerateAggregationNameRequest) GetMetricName() string {
+ if o == nil {
+ var ret string
+ return ret
+ }
+
+ return o.MetricName
+}
+
+// GetMetricNameOk returns a tuple with the MetricName field value
+// and a boolean to check if the value has been set.
+func (o *GenerateAggregationNameRequest) GetMetricNameOk() (*string, bool) {
+ if o == nil {
+ return nil, false
+ }
+ return &o.MetricName, true
+}
+
+// SetMetricName sets field value
+func (o *GenerateAggregationNameRequest) SetMetricName(v string) {
+ o.MetricName = v
+}
+
+// GetDimensions returns the Dimensions field value
+func (o *GenerateAggregationNameRequest) GetDimensions() []string {
+ if o == nil {
+ var ret []string
+ return ret
+ }
+
+ return o.Dimensions
+}
+
+// GetDimensionsOk returns a tuple with the Dimensions field value
+// and a boolean to check if the value has been set.
+func (o *GenerateAggregationNameRequest) GetDimensionsOk() ([]string, bool) {
+ if o == nil {
+ return nil, false
+ }
+ return o.Dimensions, true
+}
+
+// SetDimensions sets field value
+func (o *GenerateAggregationNameRequest) SetDimensions(v []string) {
+ o.Dimensions = v
+}
+
+// GetDropDimensions returns the DropDimensions field value if set, zero value otherwise.
+func (o *GenerateAggregationNameRequest) GetDropDimensions() bool {
+ if o == nil || isNil(o.DropDimensions) {
+ var ret bool
+ return ret
+ }
+ return *o.DropDimensions
+}
+
+// GetDropDimensionsOk returns a tuple with the DropDimensions field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *GenerateAggregationNameRequest) GetDropDimensionsOk() (*bool, bool) {
+ if o == nil || isNil(o.DropDimensions) {
+ return nil, false
+ }
+ return o.DropDimensions, true
+}
+
+// HasDropDimensions returns a boolean if a field has been set.
+func (o *GenerateAggregationNameRequest) HasDropDimensions() bool {
+ if o != nil && !isNil(o.DropDimensions) {
+ return true
+ }
+
+ return false
+}
+
+// SetDropDimensions gets a reference to the given bool and assigns it to the DropDimensions field.
+func (o *GenerateAggregationNameRequest) SetDropDimensions(v bool) {
+ o.DropDimensions = &v
+}
+
+func (o GenerateAggregationNameRequest) MarshalJSON() ([]byte, error) {
+ toSerialize := map[string]interface{}{}
+ if true {
+ toSerialize["metricName"] = o.MetricName
+ }
+ if true {
+ toSerialize["dimensions"] = o.Dimensions
+ }
+ if !isNil(o.DropDimensions) {
+ toSerialize["dropDimensions"] = o.DropDimensions
+ }
+ return json.Marshal(toSerialize)
+}
+
+type NullableGenerateAggregationNameRequest struct {
+ value *GenerateAggregationNameRequest
+ isSet bool
+}
+
+func (v NullableGenerateAggregationNameRequest) Get() *GenerateAggregationNameRequest {
+ return v.value
+}
+
+func (v *NullableGenerateAggregationNameRequest) Set(val *GenerateAggregationNameRequest) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableGenerateAggregationNameRequest) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableGenerateAggregationNameRequest) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableGenerateAggregationNameRequest(val *GenerateAggregationNameRequest) *NullableGenerateAggregationNameRequest {
+ return &NullableGenerateAggregationNameRequest{value: val, isSet: true}
+}
+
+func (v NullableGenerateAggregationNameRequest) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableGenerateAggregationNameRequest) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/model_get_metric_ruleset_response.go b/metric_ruleset/model_get_metric_ruleset_response.go
new file mode 100644
index 0000000..aebf6a9
--- /dev/null
+++ b/metric_ruleset/model_get_metric_ruleset_response.go
@@ -0,0 +1,485 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+)
+
+// GetMetricRulesetResponse Properties of the retrieved metric ruleset
+type GetMetricRulesetResponse struct {
+ // Aggregation rules in the ruleset
+ AggregationRules []AggregationRule `json:"aggregationRules,omitempty"`
+ // User ID of the user who created this metric ruleset
+ Creator *string `json:"creator,omitempty"`
+ // Name of the user who created this metric ruleset
+ CreatorName *string `json:"creatorName,omitempty"`
+ // Date and time when this ruleset was created
+ Created *int64 `json:"created,omitempty"`
+ // Ruleset ID
+ Id *string `json:"id,omitempty"`
+ // ID of the user who last updated the ruleset
+ LastUpdatedBy *string `json:"lastUpdatedBy,omitempty"`
+ // Name of the user who last updated the ruleset
+ LastUpdatedByName *string `json:"lastUpdatedByName,omitempty"`
+ // Time at which this ruleset was last updated
+ LastUpdated *int64 `json:"lastUpdated,omitempty"`
+ // Name of the metric
+ MetricName *string `json:"metricName,omitempty"`
+ RoutingRule *RoutingRule `json:"routingRule,omitempty"`
+ // Version of the ruleset
+ Version *int64 `json:"version,omitempty"`
+}
+
+// NewGetMetricRulesetResponse instantiates a new GetMetricRulesetResponse object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed
+func NewGetMetricRulesetResponse() *GetMetricRulesetResponse {
+ this := GetMetricRulesetResponse{}
+ return &this
+}
+
+// NewGetMetricRulesetResponseWithDefaults instantiates a new GetMetricRulesetResponse object
+// This constructor will only assign default values to properties that have it defined,
+// but it doesn't guarantee that properties required by API are set
+func NewGetMetricRulesetResponseWithDefaults() *GetMetricRulesetResponse {
+ this := GetMetricRulesetResponse{}
+ return &this
+}
+
+// GetAggregationRules returns the AggregationRules field value if set, zero value otherwise.
+func (o *GetMetricRulesetResponse) GetAggregationRules() []AggregationRule {
+ if o == nil || isNil(o.AggregationRules) {
+ var ret []AggregationRule
+ return ret
+ }
+ return o.AggregationRules
+}
+
+// GetAggregationRulesOk returns a tuple with the AggregationRules field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *GetMetricRulesetResponse) GetAggregationRulesOk() ([]AggregationRule, bool) {
+ if o == nil || isNil(o.AggregationRules) {
+ return nil, false
+ }
+ return o.AggregationRules, true
+}
+
+// HasAggregationRules returns a boolean if a field has been set.
+func (o *GetMetricRulesetResponse) HasAggregationRules() bool {
+ if o != nil && !isNil(o.AggregationRules) {
+ return true
+ }
+
+ return false
+}
+
+// SetAggregationRules gets a reference to the given []AggregationRule and assigns it to the AggregationRules field.
+func (o *GetMetricRulesetResponse) SetAggregationRules(v []AggregationRule) {
+ o.AggregationRules = v
+}
+
+// GetCreator returns the Creator field value if set, zero value otherwise.
+func (o *GetMetricRulesetResponse) GetCreator() string {
+ if o == nil || isNil(o.Creator) {
+ var ret string
+ return ret
+ }
+ return *o.Creator
+}
+
+// GetCreatorOk returns a tuple with the Creator field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *GetMetricRulesetResponse) GetCreatorOk() (*string, bool) {
+ if o == nil || isNil(o.Creator) {
+ return nil, false
+ }
+ return o.Creator, true
+}
+
+// HasCreator returns a boolean if a field has been set.
+func (o *GetMetricRulesetResponse) HasCreator() bool {
+ if o != nil && !isNil(o.Creator) {
+ return true
+ }
+
+ return false
+}
+
+// SetCreator gets a reference to the given string and assigns it to the Creator field.
+func (o *GetMetricRulesetResponse) SetCreator(v string) {
+ o.Creator = &v
+}
+
+// GetCreatorName returns the CreatorName field value if set, zero value otherwise.
+func (o *GetMetricRulesetResponse) GetCreatorName() string {
+ if o == nil || isNil(o.CreatorName) {
+ var ret string
+ return ret
+ }
+ return *o.CreatorName
+}
+
+// GetCreatorNameOk returns a tuple with the CreatorName field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *GetMetricRulesetResponse) GetCreatorNameOk() (*string, bool) {
+ if o == nil || isNil(o.CreatorName) {
+ return nil, false
+ }
+ return o.CreatorName, true
+}
+
+// HasCreatorName returns a boolean if a field has been set.
+func (o *GetMetricRulesetResponse) HasCreatorName() bool {
+ if o != nil && !isNil(o.CreatorName) {
+ return true
+ }
+
+ return false
+}
+
+// SetCreatorName gets a reference to the given string and assigns it to the CreatorName field.
+func (o *GetMetricRulesetResponse) SetCreatorName(v string) {
+ o.CreatorName = &v
+}
+
+// GetCreated returns the Created field value if set, zero value otherwise.
+func (o *GetMetricRulesetResponse) GetCreated() int64 {
+ if o == nil || isNil(o.Created) {
+ var ret int64
+ return ret
+ }
+ return *o.Created
+}
+
+// GetCreatedOk returns a tuple with the Created field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *GetMetricRulesetResponse) GetCreatedOk() (*int64, bool) {
+ if o == nil || isNil(o.Created) {
+ return nil, false
+ }
+ return o.Created, true
+}
+
+// HasCreated returns a boolean if a field has been set.
+func (o *GetMetricRulesetResponse) HasCreated() bool {
+ if o != nil && !isNil(o.Created) {
+ return true
+ }
+
+ return false
+}
+
+// SetCreated gets a reference to the given int64 and assigns it to the Created field.
+func (o *GetMetricRulesetResponse) SetCreated(v int64) {
+ o.Created = &v
+}
+
+// GetId returns the Id field value if set, zero value otherwise.
+func (o *GetMetricRulesetResponse) GetId() string {
+ if o == nil || isNil(o.Id) {
+ var ret string
+ return ret
+ }
+ return *o.Id
+}
+
+// GetIdOk returns a tuple with the Id field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *GetMetricRulesetResponse) GetIdOk() (*string, bool) {
+ if o == nil || isNil(o.Id) {
+ return nil, false
+ }
+ return o.Id, true
+}
+
+// HasId returns a boolean if a field has been set.
+func (o *GetMetricRulesetResponse) HasId() bool {
+ if o != nil && !isNil(o.Id) {
+ return true
+ }
+
+ return false
+}
+
+// SetId gets a reference to the given string and assigns it to the Id field.
+func (o *GetMetricRulesetResponse) SetId(v string) {
+ o.Id = &v
+}
+
+// GetLastUpdatedBy returns the LastUpdatedBy field value if set, zero value otherwise.
+func (o *GetMetricRulesetResponse) GetLastUpdatedBy() string {
+ if o == nil || isNil(o.LastUpdatedBy) {
+ var ret string
+ return ret
+ }
+ return *o.LastUpdatedBy
+}
+
+// GetLastUpdatedByOk returns a tuple with the LastUpdatedBy field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *GetMetricRulesetResponse) GetLastUpdatedByOk() (*string, bool) {
+ if o == nil || isNil(o.LastUpdatedBy) {
+ return nil, false
+ }
+ return o.LastUpdatedBy, true
+}
+
+// HasLastUpdatedBy returns a boolean if a field has been set.
+func (o *GetMetricRulesetResponse) HasLastUpdatedBy() bool {
+ if o != nil && !isNil(o.LastUpdatedBy) {
+ return true
+ }
+
+ return false
+}
+
+// SetLastUpdatedBy gets a reference to the given string and assigns it to the LastUpdatedBy field.
+func (o *GetMetricRulesetResponse) SetLastUpdatedBy(v string) {
+ o.LastUpdatedBy = &v
+}
+
+// GetLastUpdatedByName returns the LastUpdatedByName field value if set, zero value otherwise.
+func (o *GetMetricRulesetResponse) GetLastUpdatedByName() string {
+ if o == nil || isNil(o.LastUpdatedByName) {
+ var ret string
+ return ret
+ }
+ return *o.LastUpdatedByName
+}
+
+// GetLastUpdatedByNameOk returns a tuple with the LastUpdatedByName field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *GetMetricRulesetResponse) GetLastUpdatedByNameOk() (*string, bool) {
+ if o == nil || isNil(o.LastUpdatedByName) {
+ return nil, false
+ }
+ return o.LastUpdatedByName, true
+}
+
+// HasLastUpdatedByName returns a boolean if a field has been set.
+func (o *GetMetricRulesetResponse) HasLastUpdatedByName() bool {
+ if o != nil && !isNil(o.LastUpdatedByName) {
+ return true
+ }
+
+ return false
+}
+
+// SetLastUpdatedByName gets a reference to the given string and assigns it to the LastUpdatedByName field.
+func (o *GetMetricRulesetResponse) SetLastUpdatedByName(v string) {
+ o.LastUpdatedByName = &v
+}
+
+// GetLastUpdated returns the LastUpdated field value if set, zero value otherwise.
+func (o *GetMetricRulesetResponse) GetLastUpdated() int64 {
+ if o == nil || isNil(o.LastUpdated) {
+ var ret int64
+ return ret
+ }
+ return *o.LastUpdated
+}
+
+// GetLastUpdatedOk returns a tuple with the LastUpdated field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *GetMetricRulesetResponse) GetLastUpdatedOk() (*int64, bool) {
+ if o == nil || isNil(o.LastUpdated) {
+ return nil, false
+ }
+ return o.LastUpdated, true
+}
+
+// HasLastUpdated returns a boolean if a field has been set.
+func (o *GetMetricRulesetResponse) HasLastUpdated() bool {
+ if o != nil && !isNil(o.LastUpdated) {
+ return true
+ }
+
+ return false
+}
+
+// SetLastUpdated gets a reference to the given int64 and assigns it to the LastUpdated field.
+func (o *GetMetricRulesetResponse) SetLastUpdated(v int64) {
+ o.LastUpdated = &v
+}
+
+// GetMetricName returns the MetricName field value if set, zero value otherwise.
+func (o *GetMetricRulesetResponse) GetMetricName() string {
+ if o == nil || isNil(o.MetricName) {
+ var ret string
+ return ret
+ }
+ return *o.MetricName
+}
+
+// GetMetricNameOk returns a tuple with the MetricName field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *GetMetricRulesetResponse) GetMetricNameOk() (*string, bool) {
+ if o == nil || isNil(o.MetricName) {
+ return nil, false
+ }
+ return o.MetricName, true
+}
+
+// HasMetricName returns a boolean if a field has been set.
+func (o *GetMetricRulesetResponse) HasMetricName() bool {
+ if o != nil && !isNil(o.MetricName) {
+ return true
+ }
+
+ return false
+}
+
+// SetMetricName gets a reference to the given string and assigns it to the MetricName field.
+func (o *GetMetricRulesetResponse) SetMetricName(v string) {
+ o.MetricName = &v
+}
+
+// GetRoutingRule returns the RoutingRule field value if set, zero value otherwise.
+func (o *GetMetricRulesetResponse) GetRoutingRule() RoutingRule {
+ if o == nil || isNil(o.RoutingRule) {
+ var ret RoutingRule
+ return ret
+ }
+ return *o.RoutingRule
+}
+
+// GetRoutingRuleOk returns a tuple with the RoutingRule field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *GetMetricRulesetResponse) GetRoutingRuleOk() (*RoutingRule, bool) {
+ if o == nil || isNil(o.RoutingRule) {
+ return nil, false
+ }
+ return o.RoutingRule, true
+}
+
+// HasRoutingRule returns a boolean if a field has been set.
+func (o *GetMetricRulesetResponse) HasRoutingRule() bool {
+ if o != nil && !isNil(o.RoutingRule) {
+ return true
+ }
+
+ return false
+}
+
+// SetRoutingRule gets a reference to the given RoutingRule and assigns it to the RoutingRule field.
+func (o *GetMetricRulesetResponse) SetRoutingRule(v RoutingRule) {
+ o.RoutingRule = &v
+}
+
+// GetVersion returns the Version field value if set, zero value otherwise.
+func (o *GetMetricRulesetResponse) GetVersion() int64 {
+ if o == nil || isNil(o.Version) {
+ var ret int64
+ return ret
+ }
+ return *o.Version
+}
+
+// GetVersionOk returns a tuple with the Version field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *GetMetricRulesetResponse) GetVersionOk() (*int64, bool) {
+ if o == nil || isNil(o.Version) {
+ return nil, false
+ }
+ return o.Version, true
+}
+
+// HasVersion returns a boolean if a field has been set.
+func (o *GetMetricRulesetResponse) HasVersion() bool {
+ if o != nil && !isNil(o.Version) {
+ return true
+ }
+
+ return false
+}
+
+// SetVersion gets a reference to the given int64 and assigns it to the Version field.
+func (o *GetMetricRulesetResponse) SetVersion(v int64) {
+ o.Version = &v
+}
+
+func (o GetMetricRulesetResponse) MarshalJSON() ([]byte, error) {
+ toSerialize := map[string]interface{}{}
+ if !isNil(o.AggregationRules) {
+ toSerialize["aggregationRules"] = o.AggregationRules
+ }
+ if !isNil(o.Creator) {
+ toSerialize["creator"] = o.Creator
+ }
+ if !isNil(o.CreatorName) {
+ toSerialize["creatorName"] = o.CreatorName
+ }
+ if !isNil(o.Created) {
+ toSerialize["created"] = o.Created
+ }
+ if !isNil(o.Id) {
+ toSerialize["id"] = o.Id
+ }
+ if !isNil(o.LastUpdatedBy) {
+ toSerialize["lastUpdatedBy"] = o.LastUpdatedBy
+ }
+ if !isNil(o.LastUpdatedByName) {
+ toSerialize["lastUpdatedByName"] = o.LastUpdatedByName
+ }
+ if !isNil(o.LastUpdated) {
+ toSerialize["lastUpdated"] = o.LastUpdated
+ }
+ if !isNil(o.MetricName) {
+ toSerialize["metricName"] = o.MetricName
+ }
+ if !isNil(o.RoutingRule) {
+ toSerialize["routingRule"] = o.RoutingRule
+ }
+ if !isNil(o.Version) {
+ toSerialize["version"] = o.Version
+ }
+ return json.Marshal(toSerialize)
+}
+
+type NullableGetMetricRulesetResponse struct {
+ value *GetMetricRulesetResponse
+ isSet bool
+}
+
+func (v NullableGetMetricRulesetResponse) Get() *GetMetricRulesetResponse {
+ return v.value
+}
+
+func (v *NullableGetMetricRulesetResponse) Set(val *GetMetricRulesetResponse) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableGetMetricRulesetResponse) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableGetMetricRulesetResponse) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableGetMetricRulesetResponse(val *GetMetricRulesetResponse) *NullableGetMetricRulesetResponse {
+ return &NullableGetMetricRulesetResponse{value: val, isSet: true}
+}
+
+func (v NullableGetMetricRulesetResponse) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableGetMetricRulesetResponse) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/model_get_metric_rulesets_response.go b/metric_ruleset/model_get_metric_rulesets_response.go
new file mode 100644
index 0000000..259eef0
--- /dev/null
+++ b/metric_ruleset/model_get_metric_rulesets_response.go
@@ -0,0 +1,153 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+)
+
+// GetMetricRulesetsResponse Retrieving metric rulesets by query endpoint response body
+type GetMetricRulesetsResponse struct {
+ // Number of matched metric rulesets
+ Count *int32 `json:"count,omitempty"`
+ // List of metric rulesets
+ Results []MetricRuleset `json:"results,omitempty"`
+}
+
+// NewGetMetricRulesetsResponse instantiates a new GetMetricRulesetsResponse object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed
+func NewGetMetricRulesetsResponse() *GetMetricRulesetsResponse {
+ this := GetMetricRulesetsResponse{}
+ return &this
+}
+
+// NewGetMetricRulesetsResponseWithDefaults instantiates a new GetMetricRulesetsResponse object
+// This constructor will only assign default values to properties that have it defined,
+// but it doesn't guarantee that properties required by API are set
+func NewGetMetricRulesetsResponseWithDefaults() *GetMetricRulesetsResponse {
+ this := GetMetricRulesetsResponse{}
+ return &this
+}
+
+// GetCount returns the Count field value if set, zero value otherwise.
+func (o *GetMetricRulesetsResponse) GetCount() int32 {
+ if o == nil || isNil(o.Count) {
+ var ret int32
+ return ret
+ }
+ return *o.Count
+}
+
+// GetCountOk returns a tuple with the Count field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *GetMetricRulesetsResponse) GetCountOk() (*int32, bool) {
+ if o == nil || isNil(o.Count) {
+ return nil, false
+ }
+ return o.Count, true
+}
+
+// HasCount returns a boolean if a field has been set.
+func (o *GetMetricRulesetsResponse) HasCount() bool {
+ if o != nil && !isNil(o.Count) {
+ return true
+ }
+
+ return false
+}
+
+// SetCount gets a reference to the given int32 and assigns it to the Count field.
+func (o *GetMetricRulesetsResponse) SetCount(v int32) {
+ o.Count = &v
+}
+
+// GetResults returns the Results field value if set, zero value otherwise.
+func (o *GetMetricRulesetsResponse) GetResults() []MetricRuleset {
+ if o == nil || isNil(o.Results) {
+ var ret []MetricRuleset
+ return ret
+ }
+ return o.Results
+}
+
+// GetResultsOk returns a tuple with the Results field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *GetMetricRulesetsResponse) GetResultsOk() ([]MetricRuleset, bool) {
+ if o == nil || isNil(o.Results) {
+ return nil, false
+ }
+ return o.Results, true
+}
+
+// HasResults returns a boolean if a field has been set.
+func (o *GetMetricRulesetsResponse) HasResults() bool {
+ if o != nil && !isNil(o.Results) {
+ return true
+ }
+
+ return false
+}
+
+// SetResults gets a reference to the given []MetricRuleset and assigns it to the Results field.
+func (o *GetMetricRulesetsResponse) SetResults(v []MetricRuleset) {
+ o.Results = v
+}
+
+func (o GetMetricRulesetsResponse) MarshalJSON() ([]byte, error) {
+ toSerialize := map[string]interface{}{}
+ if !isNil(o.Count) {
+ toSerialize["count"] = o.Count
+ }
+ if !isNil(o.Results) {
+ toSerialize["results"] = o.Results
+ }
+ return json.Marshal(toSerialize)
+}
+
+type NullableGetMetricRulesetsResponse struct {
+ value *GetMetricRulesetsResponse
+ isSet bool
+}
+
+func (v NullableGetMetricRulesetsResponse) Get() *GetMetricRulesetsResponse {
+ return v.value
+}
+
+func (v *NullableGetMetricRulesetsResponse) Set(val *GetMetricRulesetsResponse) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableGetMetricRulesetsResponse) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableGetMetricRulesetsResponse) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableGetMetricRulesetsResponse(val *GetMetricRulesetsResponse) *NullableGetMetricRulesetsResponse {
+ return &NullableGetMetricRulesetsResponse{value: val, isSet: true}
+}
+
+func (v NullableGetMetricRulesetsResponse) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableGetMetricRulesetsResponse) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/model_metric_aggregator.go b/metric_ruleset/model_metric_aggregator.go
new file mode 100644
index 0000000..80cfbf9
--- /dev/null
+++ b/metric_ruleset/model_metric_aggregator.go
@@ -0,0 +1,118 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+// MetricAggregator - Metric aggregator
+type MetricAggregator struct {
+ RollupAggregator *RollupAggregator
+}
+
+// RollupAggregatorAsMetricAggregator is a convenience function that returns RollupAggregator wrapped in MetricAggregator
+func RollupAggregatorAsMetricAggregator(v *RollupAggregator) MetricAggregator {
+ return MetricAggregator{
+ RollupAggregator: v,
+ }
+}
+
+
+// Unmarshal JSON data into one of the pointers in the struct
+func (dst *MetricAggregator) UnmarshalJSON(data []byte) error {
+ var err error
+ match := 0
+ // try to unmarshal data into RollupAggregator
+ err = newStrictDecoder(data).Decode(&dst.RollupAggregator)
+ if err == nil {
+ jsonRollupAggregator, _ := json.Marshal(dst.RollupAggregator)
+ if string(jsonRollupAggregator) == "{}" { // empty struct
+ dst.RollupAggregator = nil
+ } else {
+ match++
+ }
+ } else {
+ dst.RollupAggregator = nil
+ }
+
+ if match > 1 { // more than 1 match
+ // reset to nil
+ dst.RollupAggregator = nil
+
+ return fmt.Errorf("data matches more than one schema in oneOf(MetricAggregator)")
+ } else if match == 1 {
+ return nil // exactly one match
+ } else { // no match
+ return fmt.Errorf("data failed to match schemas in oneOf(MetricAggregator)")
+ }
+}
+
+// Marshal data from the first non-nil pointers in the struct to JSON
+func (src MetricAggregator) MarshalJSON() ([]byte, error) {
+ if src.RollupAggregator != nil {
+ return json.Marshal(&src.RollupAggregator)
+ }
+
+ return nil, nil // no data in oneOf schemas
+}
+
+// Get the actual instance
+func (obj *MetricAggregator) GetActualInstance() (interface{}) {
+ if obj == nil {
+ return nil
+ }
+ if obj.RollupAggregator != nil {
+ return obj.RollupAggregator
+ }
+
+ // all schemas are nil
+ return nil
+}
+
+type NullableMetricAggregator struct {
+ value *MetricAggregator
+ isSet bool
+}
+
+func (v NullableMetricAggregator) Get() *MetricAggregator {
+ return v.value
+}
+
+func (v *NullableMetricAggregator) Set(val *MetricAggregator) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableMetricAggregator) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableMetricAggregator) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableMetricAggregator(val *MetricAggregator) *NullableMetricAggregator {
+ return &NullableMetricAggregator{value: val, isSet: true}
+}
+
+func (v NullableMetricAggregator) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableMetricAggregator) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/model_metric_matcher.go b/metric_ruleset/model_metric_matcher.go
new file mode 100644
index 0000000..7b2ecf1
--- /dev/null
+++ b/metric_ruleset/model_metric_matcher.go
@@ -0,0 +1,118 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+// MetricMatcher - Metric matcher
+type MetricMatcher struct {
+ DimensionMatcher *DimensionMatcher
+}
+
+// DimensionMatcherAsMetricMatcher is a convenience function that returns DimensionMatcher wrapped in MetricMatcher
+func DimensionMatcherAsMetricMatcher(v *DimensionMatcher) MetricMatcher {
+ return MetricMatcher{
+ DimensionMatcher: v,
+ }
+}
+
+
+// Unmarshal JSON data into one of the pointers in the struct
+func (dst *MetricMatcher) UnmarshalJSON(data []byte) error {
+ var err error
+ match := 0
+ // try to unmarshal data into DimensionMatcher
+ err = newStrictDecoder(data).Decode(&dst.DimensionMatcher)
+ if err == nil {
+ jsonDimensionMatcher, _ := json.Marshal(dst.DimensionMatcher)
+ if string(jsonDimensionMatcher) == "{}" { // empty struct
+ dst.DimensionMatcher = nil
+ } else {
+ match++
+ }
+ } else {
+ dst.DimensionMatcher = nil
+ }
+
+ if match > 1 { // more than 1 match
+ // reset to nil
+ dst.DimensionMatcher = nil
+
+ return fmt.Errorf("data matches more than one schema in oneOf(MetricMatcher)")
+ } else if match == 1 {
+ return nil // exactly one match
+ } else { // no match
+ return fmt.Errorf("data failed to match schemas in oneOf(MetricMatcher)")
+ }
+}
+
+// Marshal data from the first non-nil pointers in the struct to JSON
+func (src MetricMatcher) MarshalJSON() ([]byte, error) {
+ if src.DimensionMatcher != nil {
+ return json.Marshal(&src.DimensionMatcher)
+ }
+
+ return nil, nil // no data in oneOf schemas
+}
+
+// Get the actual instance
+func (obj *MetricMatcher) GetActualInstance() (interface{}) {
+ if obj == nil {
+ return nil
+ }
+ if obj.DimensionMatcher != nil {
+ return obj.DimensionMatcher
+ }
+
+ // all schemas are nil
+ return nil
+}
+
+type NullableMetricMatcher struct {
+ value *MetricMatcher
+ isSet bool
+}
+
+func (v NullableMetricMatcher) Get() *MetricMatcher {
+ return v.value
+}
+
+func (v *NullableMetricMatcher) Set(val *MetricMatcher) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableMetricMatcher) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableMetricMatcher) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableMetricMatcher(val *MetricMatcher) *NullableMetricMatcher {
+ return &NullableMetricMatcher{value: val, isSet: true}
+}
+
+func (v NullableMetricMatcher) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableMetricMatcher) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/model_metric_ruleset.go b/metric_ruleset/model_metric_ruleset.go
new file mode 100644
index 0000000..3fc57bb
--- /dev/null
+++ b/metric_ruleset/model_metric_ruleset.go
@@ -0,0 +1,485 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+)
+
+// MetricRuleset Metric ruleset properties
+type MetricRuleset struct {
+ // Aggregation rules in the ruleset
+ AggregationRules []AggregationRule `json:"aggregationRules,omitempty"`
+ // User ID of the user who created this metric ruleset
+ Creator *string `json:"creator,omitempty"`
+ // Name of the user who created this metric ruleset
+ CreatorName *string `json:"creatorName,omitempty"`
+ // Date and time when this ruleset was created
+ Created *int64 `json:"created,omitempty"`
+ // Ruleset ID
+ Id *string `json:"id,omitempty"`
+ // ID of the user who last updated the ruleset
+ LastUpdatedBy *string `json:"lastUpdatedBy,omitempty"`
+ // Name of the user who last updated the ruleset
+ LastUpdatedByName *string `json:"lastUpdatedByName,omitempty"`
+ // Time at which this ruleset was last updated
+ LastUpdated *int64 `json:"lastUpdated,omitempty"`
+ // Name of the metric
+ MetricName *string `json:"metricName,omitempty"`
+ RoutingRule *RoutingRule `json:"routingRule,omitempty"`
+ // Version of the ruleset
+ Version *int64 `json:"version,omitempty"`
+}
+
+// NewMetricRuleset instantiates a new MetricRuleset object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed
+func NewMetricRuleset() *MetricRuleset {
+ this := MetricRuleset{}
+ return &this
+}
+
+// NewMetricRulesetWithDefaults instantiates a new MetricRuleset object
+// This constructor will only assign default values to properties that have it defined,
+// but it doesn't guarantee that properties required by API are set
+func NewMetricRulesetWithDefaults() *MetricRuleset {
+ this := MetricRuleset{}
+ return &this
+}
+
+// GetAggregationRules returns the AggregationRules field value if set, zero value otherwise.
+func (o *MetricRuleset) GetAggregationRules() []AggregationRule {
+ if o == nil || isNil(o.AggregationRules) {
+ var ret []AggregationRule
+ return ret
+ }
+ return o.AggregationRules
+}
+
+// GetAggregationRulesOk returns a tuple with the AggregationRules field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *MetricRuleset) GetAggregationRulesOk() ([]AggregationRule, bool) {
+ if o == nil || isNil(o.AggregationRules) {
+ return nil, false
+ }
+ return o.AggregationRules, true
+}
+
+// HasAggregationRules returns a boolean if a field has been set.
+func (o *MetricRuleset) HasAggregationRules() bool {
+ if o != nil && !isNil(o.AggregationRules) {
+ return true
+ }
+
+ return false
+}
+
+// SetAggregationRules gets a reference to the given []AggregationRule and assigns it to the AggregationRules field.
+func (o *MetricRuleset) SetAggregationRules(v []AggregationRule) {
+ o.AggregationRules = v
+}
+
+// GetCreator returns the Creator field value if set, zero value otherwise.
+func (o *MetricRuleset) GetCreator() string {
+ if o == nil || isNil(o.Creator) {
+ var ret string
+ return ret
+ }
+ return *o.Creator
+}
+
+// GetCreatorOk returns a tuple with the Creator field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *MetricRuleset) GetCreatorOk() (*string, bool) {
+ if o == nil || isNil(o.Creator) {
+ return nil, false
+ }
+ return o.Creator, true
+}
+
+// HasCreator returns a boolean if a field has been set.
+func (o *MetricRuleset) HasCreator() bool {
+ if o != nil && !isNil(o.Creator) {
+ return true
+ }
+
+ return false
+}
+
+// SetCreator gets a reference to the given string and assigns it to the Creator field.
+func (o *MetricRuleset) SetCreator(v string) {
+ o.Creator = &v
+}
+
+// GetCreatorName returns the CreatorName field value if set, zero value otherwise.
+func (o *MetricRuleset) GetCreatorName() string {
+ if o == nil || isNil(o.CreatorName) {
+ var ret string
+ return ret
+ }
+ return *o.CreatorName
+}
+
+// GetCreatorNameOk returns a tuple with the CreatorName field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *MetricRuleset) GetCreatorNameOk() (*string, bool) {
+ if o == nil || isNil(o.CreatorName) {
+ return nil, false
+ }
+ return o.CreatorName, true
+}
+
+// HasCreatorName returns a boolean if a field has been set.
+func (o *MetricRuleset) HasCreatorName() bool {
+ if o != nil && !isNil(o.CreatorName) {
+ return true
+ }
+
+ return false
+}
+
+// SetCreatorName gets a reference to the given string and assigns it to the CreatorName field.
+func (o *MetricRuleset) SetCreatorName(v string) {
+ o.CreatorName = &v
+}
+
+// GetCreated returns the Created field value if set, zero value otherwise.
+func (o *MetricRuleset) GetCreated() int64 {
+ if o == nil || isNil(o.Created) {
+ var ret int64
+ return ret
+ }
+ return *o.Created
+}
+
+// GetCreatedOk returns a tuple with the Created field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *MetricRuleset) GetCreatedOk() (*int64, bool) {
+ if o == nil || isNil(o.Created) {
+ return nil, false
+ }
+ return o.Created, true
+}
+
+// HasCreated returns a boolean if a field has been set.
+func (o *MetricRuleset) HasCreated() bool {
+ if o != nil && !isNil(o.Created) {
+ return true
+ }
+
+ return false
+}
+
+// SetCreated gets a reference to the given int64 and assigns it to the Created field.
+func (o *MetricRuleset) SetCreated(v int64) {
+ o.Created = &v
+}
+
+// GetId returns the Id field value if set, zero value otherwise.
+func (o *MetricRuleset) GetId() string {
+ if o == nil || isNil(o.Id) {
+ var ret string
+ return ret
+ }
+ return *o.Id
+}
+
+// GetIdOk returns a tuple with the Id field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *MetricRuleset) GetIdOk() (*string, bool) {
+ if o == nil || isNil(o.Id) {
+ return nil, false
+ }
+ return o.Id, true
+}
+
+// HasId returns a boolean if a field has been set.
+func (o *MetricRuleset) HasId() bool {
+ if o != nil && !isNil(o.Id) {
+ return true
+ }
+
+ return false
+}
+
+// SetId gets a reference to the given string and assigns it to the Id field.
+func (o *MetricRuleset) SetId(v string) {
+ o.Id = &v
+}
+
+// GetLastUpdatedBy returns the LastUpdatedBy field value if set, zero value otherwise.
+func (o *MetricRuleset) GetLastUpdatedBy() string {
+ if o == nil || isNil(o.LastUpdatedBy) {
+ var ret string
+ return ret
+ }
+ return *o.LastUpdatedBy
+}
+
+// GetLastUpdatedByOk returns a tuple with the LastUpdatedBy field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *MetricRuleset) GetLastUpdatedByOk() (*string, bool) {
+ if o == nil || isNil(o.LastUpdatedBy) {
+ return nil, false
+ }
+ return o.LastUpdatedBy, true
+}
+
+// HasLastUpdatedBy returns a boolean if a field has been set.
+func (o *MetricRuleset) HasLastUpdatedBy() bool {
+ if o != nil && !isNil(o.LastUpdatedBy) {
+ return true
+ }
+
+ return false
+}
+
+// SetLastUpdatedBy gets a reference to the given string and assigns it to the LastUpdatedBy field.
+func (o *MetricRuleset) SetLastUpdatedBy(v string) {
+ o.LastUpdatedBy = &v
+}
+
+// GetLastUpdatedByName returns the LastUpdatedByName field value if set, zero value otherwise.
+func (o *MetricRuleset) GetLastUpdatedByName() string {
+ if o == nil || isNil(o.LastUpdatedByName) {
+ var ret string
+ return ret
+ }
+ return *o.LastUpdatedByName
+}
+
+// GetLastUpdatedByNameOk returns a tuple with the LastUpdatedByName field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *MetricRuleset) GetLastUpdatedByNameOk() (*string, bool) {
+ if o == nil || isNil(o.LastUpdatedByName) {
+ return nil, false
+ }
+ return o.LastUpdatedByName, true
+}
+
+// HasLastUpdatedByName returns a boolean if a field has been set.
+func (o *MetricRuleset) HasLastUpdatedByName() bool {
+ if o != nil && !isNil(o.LastUpdatedByName) {
+ return true
+ }
+
+ return false
+}
+
+// SetLastUpdatedByName gets a reference to the given string and assigns it to the LastUpdatedByName field.
+func (o *MetricRuleset) SetLastUpdatedByName(v string) {
+ o.LastUpdatedByName = &v
+}
+
+// GetLastUpdated returns the LastUpdated field value if set, zero value otherwise.
+func (o *MetricRuleset) GetLastUpdated() int64 {
+ if o == nil || isNil(o.LastUpdated) {
+ var ret int64
+ return ret
+ }
+ return *o.LastUpdated
+}
+
+// GetLastUpdatedOk returns a tuple with the LastUpdated field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *MetricRuleset) GetLastUpdatedOk() (*int64, bool) {
+ if o == nil || isNil(o.LastUpdated) {
+ return nil, false
+ }
+ return o.LastUpdated, true
+}
+
+// HasLastUpdated returns a boolean if a field has been set.
+func (o *MetricRuleset) HasLastUpdated() bool {
+ if o != nil && !isNil(o.LastUpdated) {
+ return true
+ }
+
+ return false
+}
+
+// SetLastUpdated gets a reference to the given int64 and assigns it to the LastUpdated field.
+func (o *MetricRuleset) SetLastUpdated(v int64) {
+ o.LastUpdated = &v
+}
+
+// GetMetricName returns the MetricName field value if set, zero value otherwise.
+func (o *MetricRuleset) GetMetricName() string {
+ if o == nil || isNil(o.MetricName) {
+ var ret string
+ return ret
+ }
+ return *o.MetricName
+}
+
+// GetMetricNameOk returns a tuple with the MetricName field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *MetricRuleset) GetMetricNameOk() (*string, bool) {
+ if o == nil || isNil(o.MetricName) {
+ return nil, false
+ }
+ return o.MetricName, true
+}
+
+// HasMetricName returns a boolean if a field has been set.
+func (o *MetricRuleset) HasMetricName() bool {
+ if o != nil && !isNil(o.MetricName) {
+ return true
+ }
+
+ return false
+}
+
+// SetMetricName gets a reference to the given string and assigns it to the MetricName field.
+func (o *MetricRuleset) SetMetricName(v string) {
+ o.MetricName = &v
+}
+
+// GetRoutingRule returns the RoutingRule field value if set, zero value otherwise.
+func (o *MetricRuleset) GetRoutingRule() RoutingRule {
+ if o == nil || isNil(o.RoutingRule) {
+ var ret RoutingRule
+ return ret
+ }
+ return *o.RoutingRule
+}
+
+// GetRoutingRuleOk returns a tuple with the RoutingRule field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *MetricRuleset) GetRoutingRuleOk() (*RoutingRule, bool) {
+ if o == nil || isNil(o.RoutingRule) {
+ return nil, false
+ }
+ return o.RoutingRule, true
+}
+
+// HasRoutingRule returns a boolean if a field has been set.
+func (o *MetricRuleset) HasRoutingRule() bool {
+ if o != nil && !isNil(o.RoutingRule) {
+ return true
+ }
+
+ return false
+}
+
+// SetRoutingRule gets a reference to the given RoutingRule and assigns it to the RoutingRule field.
+func (o *MetricRuleset) SetRoutingRule(v RoutingRule) {
+ o.RoutingRule = &v
+}
+
+// GetVersion returns the Version field value if set, zero value otherwise.
+func (o *MetricRuleset) GetVersion() int64 {
+ if o == nil || isNil(o.Version) {
+ var ret int64
+ return ret
+ }
+ return *o.Version
+}
+
+// GetVersionOk returns a tuple with the Version field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *MetricRuleset) GetVersionOk() (*int64, bool) {
+ if o == nil || isNil(o.Version) {
+ return nil, false
+ }
+ return o.Version, true
+}
+
+// HasVersion returns a boolean if a field has been set.
+func (o *MetricRuleset) HasVersion() bool {
+ if o != nil && !isNil(o.Version) {
+ return true
+ }
+
+ return false
+}
+
+// SetVersion gets a reference to the given int64 and assigns it to the Version field.
+func (o *MetricRuleset) SetVersion(v int64) {
+ o.Version = &v
+}
+
+func (o MetricRuleset) MarshalJSON() ([]byte, error) {
+ toSerialize := map[string]interface{}{}
+ if !isNil(o.AggregationRules) {
+ toSerialize["aggregationRules"] = o.AggregationRules
+ }
+ if !isNil(o.Creator) {
+ toSerialize["creator"] = o.Creator
+ }
+ if !isNil(o.CreatorName) {
+ toSerialize["creatorName"] = o.CreatorName
+ }
+ if !isNil(o.Created) {
+ toSerialize["created"] = o.Created
+ }
+ if !isNil(o.Id) {
+ toSerialize["id"] = o.Id
+ }
+ if !isNil(o.LastUpdatedBy) {
+ toSerialize["lastUpdatedBy"] = o.LastUpdatedBy
+ }
+ if !isNil(o.LastUpdatedByName) {
+ toSerialize["lastUpdatedByName"] = o.LastUpdatedByName
+ }
+ if !isNil(o.LastUpdated) {
+ toSerialize["lastUpdated"] = o.LastUpdated
+ }
+ if !isNil(o.MetricName) {
+ toSerialize["metricName"] = o.MetricName
+ }
+ if !isNil(o.RoutingRule) {
+ toSerialize["routingRule"] = o.RoutingRule
+ }
+ if !isNil(o.Version) {
+ toSerialize["version"] = o.Version
+ }
+ return json.Marshal(toSerialize)
+}
+
+type NullableMetricRuleset struct {
+ value *MetricRuleset
+ isSet bool
+}
+
+func (v NullableMetricRuleset) Get() *MetricRuleset {
+ return v.value
+}
+
+func (v *NullableMetricRuleset) Set(val *MetricRuleset) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableMetricRuleset) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableMetricRuleset) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableMetricRuleset(val *MetricRuleset) *NullableMetricRuleset {
+ return &NullableMetricRuleset{value: val, isSet: true}
+}
+
+func (v NullableMetricRuleset) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableMetricRuleset) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/model_property_filter.go b/metric_ruleset/model_property_filter.go
new file mode 100644
index 0000000..d491be2
--- /dev/null
+++ b/metric_ruleset/model_property_filter.go
@@ -0,0 +1,190 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+)
+
+// PropertyFilter Single filter to include or exclude metric specified in the matcher
+type PropertyFilter struct {
+ // Custom property or dimension for which you want to filter
+ Property *string `json:"property,omitempty"`
+ // Custom property or dimension values to filter
+ PropertyValue []string `json:"propertyValue,omitempty"`
+ // Indicates whether you want the property to be included or excluded from the filter
+ NOT *bool `json:"NOT,omitempty"`
+}
+
+// NewPropertyFilter instantiates a new PropertyFilter object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed
+func NewPropertyFilter() *PropertyFilter {
+ this := PropertyFilter{}
+ return &this
+}
+
+// NewPropertyFilterWithDefaults instantiates a new PropertyFilter object
+// This constructor will only assign default values to properties that have it defined,
+// but it doesn't guarantee that properties required by API are set
+func NewPropertyFilterWithDefaults() *PropertyFilter {
+ this := PropertyFilter{}
+ return &this
+}
+
+// GetProperty returns the Property field value if set, zero value otherwise.
+func (o *PropertyFilter) GetProperty() string {
+ if o == nil || isNil(o.Property) {
+ var ret string
+ return ret
+ }
+ return *o.Property
+}
+
+// GetPropertyOk returns a tuple with the Property field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *PropertyFilter) GetPropertyOk() (*string, bool) {
+ if o == nil || isNil(o.Property) {
+ return nil, false
+ }
+ return o.Property, true
+}
+
+// HasProperty returns a boolean if a field has been set.
+func (o *PropertyFilter) HasProperty() bool {
+ if o != nil && !isNil(o.Property) {
+ return true
+ }
+
+ return false
+}
+
+// SetProperty gets a reference to the given string and assigns it to the Property field.
+func (o *PropertyFilter) SetProperty(v string) {
+ o.Property = &v
+}
+
+// GetPropertyValue returns the PropertyValue field value if set, zero value otherwise.
+func (o *PropertyFilter) GetPropertyValue() []string {
+ if o == nil || isNil(o.PropertyValue) {
+ var ret []string
+ return ret
+ }
+ return o.PropertyValue
+}
+
+// GetPropertyValueOk returns a tuple with the PropertyValue field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *PropertyFilter) GetPropertyValueOk() ([]string, bool) {
+ if o == nil || isNil(o.PropertyValue) {
+ return nil, false
+ }
+ return o.PropertyValue, true
+}
+
+// HasPropertyValue returns a boolean if a field has been set.
+func (o *PropertyFilter) HasPropertyValue() bool {
+ if o != nil && !isNil(o.PropertyValue) {
+ return true
+ }
+
+ return false
+}
+
+// SetPropertyValue gets a reference to the given []string and assigns it to the PropertyValue field.
+func (o *PropertyFilter) SetPropertyValue(v []string) {
+ o.PropertyValue = v
+}
+
+// GetNOT returns the NOT field value if set, zero value otherwise.
+func (o *PropertyFilter) GetNOT() bool {
+ if o == nil || isNil(o.NOT) {
+ var ret bool
+ return ret
+ }
+ return *o.NOT
+}
+
+// GetNOTOk returns a tuple with the NOT field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *PropertyFilter) GetNOTOk() (*bool, bool) {
+ if o == nil || isNil(o.NOT) {
+ return nil, false
+ }
+ return o.NOT, true
+}
+
+// HasNOT returns a boolean if a field has been set.
+func (o *PropertyFilter) HasNOT() bool {
+ if o != nil && !isNil(o.NOT) {
+ return true
+ }
+
+ return false
+}
+
+// SetNOT gets a reference to the given bool and assigns it to the NOT field.
+func (o *PropertyFilter) SetNOT(v bool) {
+ o.NOT = &v
+}
+
+func (o PropertyFilter) MarshalJSON() ([]byte, error) {
+ toSerialize := map[string]interface{}{}
+ if !isNil(o.Property) {
+ toSerialize["property"] = o.Property
+ }
+ if !isNil(o.PropertyValue) {
+ toSerialize["propertyValue"] = o.PropertyValue
+ }
+ if !isNil(o.NOT) {
+ toSerialize["NOT"] = o.NOT
+ }
+ return json.Marshal(toSerialize)
+}
+
+type NullablePropertyFilter struct {
+ value *PropertyFilter
+ isSet bool
+}
+
+func (v NullablePropertyFilter) Get() *PropertyFilter {
+ return v.value
+}
+
+func (v *NullablePropertyFilter) Set(val *PropertyFilter) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullablePropertyFilter) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullablePropertyFilter) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullablePropertyFilter(val *PropertyFilter) *NullablePropertyFilter {
+ return &NullablePropertyFilter{value: val, isSet: true}
+}
+
+func (v NullablePropertyFilter) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullablePropertyFilter) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/model_rollup_aggregator.go b/metric_ruleset/model_rollup_aggregator.go
new file mode 100644
index 0000000..f2be75e
--- /dev/null
+++ b/metric_ruleset/model_rollup_aggregator.go
@@ -0,0 +1,213 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+)
+
+// RollupAggregator A rollup aggregator for your aggregation rule
+type RollupAggregator struct {
+ // Dimensions you want to keep or drop in the aggregation rule
+ Dimensions []string `json:"dimensions,omitempty"`
+ // Flag toggling if the dimensions are being dropped
+ DropDimensions *bool `json:"dropDimensions,omitempty"`
+ // New aggregated metric name
+ OutputName string `json:"outputName"`
+ // Aggregation rule type
+ Type string `json:"type"`
+}
+
+// NewRollupAggregator instantiates a new RollupAggregator object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed
+func NewRollupAggregator(outputName string, type_ string) *RollupAggregator {
+ this := RollupAggregator{}
+ this.OutputName = outputName
+ this.Type = type_
+ return &this
+}
+
+// NewRollupAggregatorWithDefaults instantiates a new RollupAggregator object
+// This constructor will only assign default values to properties that have it defined,
+// but it doesn't guarantee that properties required by API are set
+func NewRollupAggregatorWithDefaults() *RollupAggregator {
+ this := RollupAggregator{}
+ return &this
+}
+
+// GetDimensions returns the Dimensions field value if set, zero value otherwise.
+func (o *RollupAggregator) GetDimensions() []string {
+ if o == nil || isNil(o.Dimensions) {
+ var ret []string
+ return ret
+ }
+ return o.Dimensions
+}
+
+// GetDimensionsOk returns a tuple with the Dimensions field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *RollupAggregator) GetDimensionsOk() ([]string, bool) {
+ if o == nil || isNil(o.Dimensions) {
+ return nil, false
+ }
+ return o.Dimensions, true
+}
+
+// HasDimensions returns a boolean if a field has been set.
+func (o *RollupAggregator) HasDimensions() bool {
+ if o != nil && !isNil(o.Dimensions) {
+ return true
+ }
+
+ return false
+}
+
+// SetDimensions gets a reference to the given []string and assigns it to the Dimensions field.
+func (o *RollupAggregator) SetDimensions(v []string) {
+ o.Dimensions = v
+}
+
+// GetDropDimensions returns the DropDimensions field value if set, zero value otherwise.
+func (o *RollupAggregator) GetDropDimensions() bool {
+ if o == nil || isNil(o.DropDimensions) {
+ var ret bool
+ return ret
+ }
+ return *o.DropDimensions
+}
+
+// GetDropDimensionsOk returns a tuple with the DropDimensions field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *RollupAggregator) GetDropDimensionsOk() (*bool, bool) {
+ if o == nil || isNil(o.DropDimensions) {
+ return nil, false
+ }
+ return o.DropDimensions, true
+}
+
+// HasDropDimensions returns a boolean if a field has been set.
+func (o *RollupAggregator) HasDropDimensions() bool {
+ if o != nil && !isNil(o.DropDimensions) {
+ return true
+ }
+
+ return false
+}
+
+// SetDropDimensions gets a reference to the given bool and assigns it to the DropDimensions field.
+func (o *RollupAggregator) SetDropDimensions(v bool) {
+ o.DropDimensions = &v
+}
+
+// GetOutputName returns the OutputName field value
+func (o *RollupAggregator) GetOutputName() string {
+ if o == nil {
+ var ret string
+ return ret
+ }
+
+ return o.OutputName
+}
+
+// GetOutputNameOk returns a tuple with the OutputName field value
+// and a boolean to check if the value has been set.
+func (o *RollupAggregator) GetOutputNameOk() (*string, bool) {
+ if o == nil {
+ return nil, false
+ }
+ return &o.OutputName, true
+}
+
+// SetOutputName sets field value
+func (o *RollupAggregator) SetOutputName(v string) {
+ o.OutputName = v
+}
+
+// GetType returns the Type field value
+func (o *RollupAggregator) GetType() string {
+ if o == nil {
+ var ret string
+ return ret
+ }
+
+ return o.Type
+}
+
+// GetTypeOk returns a tuple with the Type field value
+// and a boolean to check if the value has been set.
+func (o *RollupAggregator) GetTypeOk() (*string, bool) {
+ if o == nil {
+ return nil, false
+ }
+ return &o.Type, true
+}
+
+// SetType sets field value
+func (o *RollupAggregator) SetType(v string) {
+ o.Type = v
+}
+
+func (o RollupAggregator) MarshalJSON() ([]byte, error) {
+ toSerialize := map[string]interface{}{}
+ if !isNil(o.Dimensions) {
+ toSerialize["dimensions"] = o.Dimensions
+ }
+ if !isNil(o.DropDimensions) {
+ toSerialize["dropDimensions"] = o.DropDimensions
+ }
+ if true {
+ toSerialize["outputName"] = o.OutputName
+ }
+ if true {
+ toSerialize["type"] = o.Type
+ }
+ return json.Marshal(toSerialize)
+}
+
+type NullableRollupAggregator struct {
+ value *RollupAggregator
+ isSet bool
+}
+
+func (v NullableRollupAggregator) Get() *RollupAggregator {
+ return v.value
+}
+
+func (v *NullableRollupAggregator) Set(val *RollupAggregator) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableRollupAggregator) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableRollupAggregator) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableRollupAggregator(val *RollupAggregator) *NullableRollupAggregator {
+ return &NullableRollupAggregator{value: val, isSet: true}
+}
+
+func (v NullableRollupAggregator) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableRollupAggregator) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/model_routing_rule.go b/metric_ruleset/model_routing_rule.go
new file mode 100644
index 0000000..8dfdf44
--- /dev/null
+++ b/metric_ruleset/model_routing_rule.go
@@ -0,0 +1,116 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+)
+
+// RoutingRule Routing rule for your data
+type RoutingRule struct {
+ // Routing destination
+ Destination *string `json:"destination,omitempty"`
+}
+
+// NewRoutingRule instantiates a new RoutingRule object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed
+func NewRoutingRule() *RoutingRule {
+ this := RoutingRule{}
+ return &this
+}
+
+// NewRoutingRuleWithDefaults instantiates a new RoutingRule object
+// This constructor will only assign default values to properties that have it defined,
+// but it doesn't guarantee that properties required by API are set
+func NewRoutingRuleWithDefaults() *RoutingRule {
+ this := RoutingRule{}
+ return &this
+}
+
+// GetDestination returns the Destination field value if set, zero value otherwise.
+func (o *RoutingRule) GetDestination() string {
+ if o == nil || isNil(o.Destination) {
+ var ret string
+ return ret
+ }
+ return *o.Destination
+}
+
+// GetDestinationOk returns a tuple with the Destination field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *RoutingRule) GetDestinationOk() (*string, bool) {
+ if o == nil || isNil(o.Destination) {
+ return nil, false
+ }
+ return o.Destination, true
+}
+
+// HasDestination returns a boolean if a field has been set.
+func (o *RoutingRule) HasDestination() bool {
+ if o != nil && !isNil(o.Destination) {
+ return true
+ }
+
+ return false
+}
+
+// SetDestination gets a reference to the given string and assigns it to the Destination field.
+func (o *RoutingRule) SetDestination(v string) {
+ o.Destination = &v
+}
+
+func (o RoutingRule) MarshalJSON() ([]byte, error) {
+ toSerialize := map[string]interface{}{}
+ if !isNil(o.Destination) {
+ toSerialize["destination"] = o.Destination
+ }
+ return json.Marshal(toSerialize)
+}
+
+type NullableRoutingRule struct {
+ value *RoutingRule
+ isSet bool
+}
+
+func (v NullableRoutingRule) Get() *RoutingRule {
+ return v.value
+}
+
+func (v *NullableRoutingRule) Set(val *RoutingRule) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableRoutingRule) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableRoutingRule) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableRoutingRule(val *RoutingRule) *NullableRoutingRule {
+ return &NullableRoutingRule{value: val, isSet: true}
+}
+
+func (v NullableRoutingRule) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableRoutingRule) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/model_update_metric_ruleset_request.go b/metric_ruleset/model_update_metric_ruleset_request.go
new file mode 100644
index 0000000..4706f68
--- /dev/null
+++ b/metric_ruleset/model_update_metric_ruleset_request.go
@@ -0,0 +1,226 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+)
+
+// UpdateMetricRulesetRequest Update metric ruleset request body
+type UpdateMetricRulesetRequest struct {
+ // Aggregation rules in the ruleset
+ AggregationRules []AggregationRule `json:"aggregationRules,omitempty"`
+ // Name of the metric
+ MetricName *string `json:"metricName,omitempty"`
+ RoutingRule *RoutingRule `json:"routingRule,omitempty"`
+ // Version of the ruleset
+ Version *int64 `json:"version,omitempty"`
+}
+
+// NewUpdateMetricRulesetRequest instantiates a new UpdateMetricRulesetRequest object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed
+func NewUpdateMetricRulesetRequest() *UpdateMetricRulesetRequest {
+ this := UpdateMetricRulesetRequest{}
+ return &this
+}
+
+// NewUpdateMetricRulesetRequestWithDefaults instantiates a new UpdateMetricRulesetRequest object
+// This constructor will only assign default values to properties that have it defined,
+// but it doesn't guarantee that properties required by API are set
+func NewUpdateMetricRulesetRequestWithDefaults() *UpdateMetricRulesetRequest {
+ this := UpdateMetricRulesetRequest{}
+ return &this
+}
+
+// GetAggregationRules returns the AggregationRules field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetRequest) GetAggregationRules() []AggregationRule {
+ if o == nil || isNil(o.AggregationRules) {
+ var ret []AggregationRule
+ return ret
+ }
+ return o.AggregationRules
+}
+
+// GetAggregationRulesOk returns a tuple with the AggregationRules field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetRequest) GetAggregationRulesOk() ([]AggregationRule, bool) {
+ if o == nil || isNil(o.AggregationRules) {
+ return nil, false
+ }
+ return o.AggregationRules, true
+}
+
+// HasAggregationRules returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetRequest) HasAggregationRules() bool {
+ if o != nil && !isNil(o.AggregationRules) {
+ return true
+ }
+
+ return false
+}
+
+// SetAggregationRules gets a reference to the given []AggregationRule and assigns it to the AggregationRules field.
+func (o *UpdateMetricRulesetRequest) SetAggregationRules(v []AggregationRule) {
+ o.AggregationRules = v
+}
+
+// GetMetricName returns the MetricName field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetRequest) GetMetricName() string {
+ if o == nil || isNil(o.MetricName) {
+ var ret string
+ return ret
+ }
+ return *o.MetricName
+}
+
+// GetMetricNameOk returns a tuple with the MetricName field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetRequest) GetMetricNameOk() (*string, bool) {
+ if o == nil || isNil(o.MetricName) {
+ return nil, false
+ }
+ return o.MetricName, true
+}
+
+// HasMetricName returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetRequest) HasMetricName() bool {
+ if o != nil && !isNil(o.MetricName) {
+ return true
+ }
+
+ return false
+}
+
+// SetMetricName gets a reference to the given string and assigns it to the MetricName field.
+func (o *UpdateMetricRulesetRequest) SetMetricName(v string) {
+ o.MetricName = &v
+}
+
+// GetRoutingRule returns the RoutingRule field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetRequest) GetRoutingRule() RoutingRule {
+ if o == nil || isNil(o.RoutingRule) {
+ var ret RoutingRule
+ return ret
+ }
+ return *o.RoutingRule
+}
+
+// GetRoutingRuleOk returns a tuple with the RoutingRule field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetRequest) GetRoutingRuleOk() (*RoutingRule, bool) {
+ if o == nil || isNil(o.RoutingRule) {
+ return nil, false
+ }
+ return o.RoutingRule, true
+}
+
+// HasRoutingRule returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetRequest) HasRoutingRule() bool {
+ if o != nil && !isNil(o.RoutingRule) {
+ return true
+ }
+
+ return false
+}
+
+// SetRoutingRule gets a reference to the given RoutingRule and assigns it to the RoutingRule field.
+func (o *UpdateMetricRulesetRequest) SetRoutingRule(v RoutingRule) {
+ o.RoutingRule = &v
+}
+
+// GetVersion returns the Version field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetRequest) GetVersion() int64 {
+ if o == nil || isNil(o.Version) {
+ var ret int64
+ return ret
+ }
+ return *o.Version
+}
+
+// GetVersionOk returns a tuple with the Version field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetRequest) GetVersionOk() (*int64, bool) {
+ if o == nil || isNil(o.Version) {
+ return nil, false
+ }
+ return o.Version, true
+}
+
+// HasVersion returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetRequest) HasVersion() bool {
+ if o != nil && !isNil(o.Version) {
+ return true
+ }
+
+ return false
+}
+
+// SetVersion gets a reference to the given int64 and assigns it to the Version field.
+func (o *UpdateMetricRulesetRequest) SetVersion(v int64) {
+ o.Version = &v
+}
+
+func (o UpdateMetricRulesetRequest) MarshalJSON() ([]byte, error) {
+ toSerialize := map[string]interface{}{}
+ if !isNil(o.AggregationRules) {
+ toSerialize["aggregationRules"] = o.AggregationRules
+ }
+ if !isNil(o.MetricName) {
+ toSerialize["metricName"] = o.MetricName
+ }
+ if !isNil(o.RoutingRule) {
+ toSerialize["routingRule"] = o.RoutingRule
+ }
+ if !isNil(o.Version) {
+ toSerialize["version"] = o.Version
+ }
+ return json.Marshal(toSerialize)
+}
+
+type NullableUpdateMetricRulesetRequest struct {
+ value *UpdateMetricRulesetRequest
+ isSet bool
+}
+
+func (v NullableUpdateMetricRulesetRequest) Get() *UpdateMetricRulesetRequest {
+ return v.value
+}
+
+func (v *NullableUpdateMetricRulesetRequest) Set(val *UpdateMetricRulesetRequest) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableUpdateMetricRulesetRequest) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableUpdateMetricRulesetRequest) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableUpdateMetricRulesetRequest(val *UpdateMetricRulesetRequest) *NullableUpdateMetricRulesetRequest {
+ return &NullableUpdateMetricRulesetRequest{value: val, isSet: true}
+}
+
+func (v NullableUpdateMetricRulesetRequest) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableUpdateMetricRulesetRequest) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/model_update_metric_ruleset_response.go b/metric_ruleset/model_update_metric_ruleset_response.go
new file mode 100644
index 0000000..bf26ba8
--- /dev/null
+++ b/metric_ruleset/model_update_metric_ruleset_response.go
@@ -0,0 +1,485 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+)
+
+// UpdateMetricRulesetResponse Response body returned by Update Metric Ruleset
+type UpdateMetricRulesetResponse struct {
+ // Aggregation rules in the ruleset
+ AggregationRules []AggregationRule `json:"aggregationRules,omitempty"`
+ // User ID of the user who created this metric ruleset
+ Creator *string `json:"creator,omitempty"`
+ // Name of the user who created this metric ruleset
+ CreatorName *string `json:"creatorName,omitempty"`
+ // Date and time when this ruleset was created
+ Created *int64 `json:"created,omitempty"`
+ // Ruleset ID
+ Id *string `json:"id,omitempty"`
+ // ID of the user who last updated the ruleset
+ LastUpdatedBy *string `json:"lastUpdatedBy,omitempty"`
+ // Name of the user who last updated the ruleset
+ LastUpdatedByName *string `json:"lastUpdatedByName,omitempty"`
+ // Time at which this ruleset was last updated
+ LastUpdated *int64 `json:"lastUpdated,omitempty"`
+ // Name of the metric
+ MetricName *string `json:"metricName,omitempty"`
+ RoutingRule *RoutingRule `json:"routingRule,omitempty"`
+ // Version of the ruleset
+ Version *int64 `json:"version,omitempty"`
+}
+
+// NewUpdateMetricRulesetResponse instantiates a new UpdateMetricRulesetResponse object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed
+func NewUpdateMetricRulesetResponse() *UpdateMetricRulesetResponse {
+ this := UpdateMetricRulesetResponse{}
+ return &this
+}
+
+// NewUpdateMetricRulesetResponseWithDefaults instantiates a new UpdateMetricRulesetResponse object
+// This constructor will only assign default values to properties that have it defined,
+// but it doesn't guarantee that properties required by API are set
+func NewUpdateMetricRulesetResponseWithDefaults() *UpdateMetricRulesetResponse {
+ this := UpdateMetricRulesetResponse{}
+ return &this
+}
+
+// GetAggregationRules returns the AggregationRules field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetResponse) GetAggregationRules() []AggregationRule {
+ if o == nil || isNil(o.AggregationRules) {
+ var ret []AggregationRule
+ return ret
+ }
+ return o.AggregationRules
+}
+
+// GetAggregationRulesOk returns a tuple with the AggregationRules field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetResponse) GetAggregationRulesOk() ([]AggregationRule, bool) {
+ if o == nil || isNil(o.AggregationRules) {
+ return nil, false
+ }
+ return o.AggregationRules, true
+}
+
+// HasAggregationRules returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetResponse) HasAggregationRules() bool {
+ if o != nil && !isNil(o.AggregationRules) {
+ return true
+ }
+
+ return false
+}
+
+// SetAggregationRules gets a reference to the given []AggregationRule and assigns it to the AggregationRules field.
+func (o *UpdateMetricRulesetResponse) SetAggregationRules(v []AggregationRule) {
+ o.AggregationRules = v
+}
+
+// GetCreator returns the Creator field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetResponse) GetCreator() string {
+ if o == nil || isNil(o.Creator) {
+ var ret string
+ return ret
+ }
+ return *o.Creator
+}
+
+// GetCreatorOk returns a tuple with the Creator field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetResponse) GetCreatorOk() (*string, bool) {
+ if o == nil || isNil(o.Creator) {
+ return nil, false
+ }
+ return o.Creator, true
+}
+
+// HasCreator returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetResponse) HasCreator() bool {
+ if o != nil && !isNil(o.Creator) {
+ return true
+ }
+
+ return false
+}
+
+// SetCreator gets a reference to the given string and assigns it to the Creator field.
+func (o *UpdateMetricRulesetResponse) SetCreator(v string) {
+ o.Creator = &v
+}
+
+// GetCreatorName returns the CreatorName field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetResponse) GetCreatorName() string {
+ if o == nil || isNil(o.CreatorName) {
+ var ret string
+ return ret
+ }
+ return *o.CreatorName
+}
+
+// GetCreatorNameOk returns a tuple with the CreatorName field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetResponse) GetCreatorNameOk() (*string, bool) {
+ if o == nil || isNil(o.CreatorName) {
+ return nil, false
+ }
+ return o.CreatorName, true
+}
+
+// HasCreatorName returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetResponse) HasCreatorName() bool {
+ if o != nil && !isNil(o.CreatorName) {
+ return true
+ }
+
+ return false
+}
+
+// SetCreatorName gets a reference to the given string and assigns it to the CreatorName field.
+func (o *UpdateMetricRulesetResponse) SetCreatorName(v string) {
+ o.CreatorName = &v
+}
+
+// GetCreated returns the Created field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetResponse) GetCreated() int64 {
+ if o == nil || isNil(o.Created) {
+ var ret int64
+ return ret
+ }
+ return *o.Created
+}
+
+// GetCreatedOk returns a tuple with the Created field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetResponse) GetCreatedOk() (*int64, bool) {
+ if o == nil || isNil(o.Created) {
+ return nil, false
+ }
+ return o.Created, true
+}
+
+// HasCreated returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetResponse) HasCreated() bool {
+ if o != nil && !isNil(o.Created) {
+ return true
+ }
+
+ return false
+}
+
+// SetCreated gets a reference to the given int64 and assigns it to the Created field.
+func (o *UpdateMetricRulesetResponse) SetCreated(v int64) {
+ o.Created = &v
+}
+
+// GetId returns the Id field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetResponse) GetId() string {
+ if o == nil || isNil(o.Id) {
+ var ret string
+ return ret
+ }
+ return *o.Id
+}
+
+// GetIdOk returns a tuple with the Id field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetResponse) GetIdOk() (*string, bool) {
+ if o == nil || isNil(o.Id) {
+ return nil, false
+ }
+ return o.Id, true
+}
+
+// HasId returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetResponse) HasId() bool {
+ if o != nil && !isNil(o.Id) {
+ return true
+ }
+
+ return false
+}
+
+// SetId gets a reference to the given string and assigns it to the Id field.
+func (o *UpdateMetricRulesetResponse) SetId(v string) {
+ o.Id = &v
+}
+
+// GetLastUpdatedBy returns the LastUpdatedBy field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetResponse) GetLastUpdatedBy() string {
+ if o == nil || isNil(o.LastUpdatedBy) {
+ var ret string
+ return ret
+ }
+ return *o.LastUpdatedBy
+}
+
+// GetLastUpdatedByOk returns a tuple with the LastUpdatedBy field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetResponse) GetLastUpdatedByOk() (*string, bool) {
+ if o == nil || isNil(o.LastUpdatedBy) {
+ return nil, false
+ }
+ return o.LastUpdatedBy, true
+}
+
+// HasLastUpdatedBy returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetResponse) HasLastUpdatedBy() bool {
+ if o != nil && !isNil(o.LastUpdatedBy) {
+ return true
+ }
+
+ return false
+}
+
+// SetLastUpdatedBy gets a reference to the given string and assigns it to the LastUpdatedBy field.
+func (o *UpdateMetricRulesetResponse) SetLastUpdatedBy(v string) {
+ o.LastUpdatedBy = &v
+}
+
+// GetLastUpdatedByName returns the LastUpdatedByName field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetResponse) GetLastUpdatedByName() string {
+ if o == nil || isNil(o.LastUpdatedByName) {
+ var ret string
+ return ret
+ }
+ return *o.LastUpdatedByName
+}
+
+// GetLastUpdatedByNameOk returns a tuple with the LastUpdatedByName field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetResponse) GetLastUpdatedByNameOk() (*string, bool) {
+ if o == nil || isNil(o.LastUpdatedByName) {
+ return nil, false
+ }
+ return o.LastUpdatedByName, true
+}
+
+// HasLastUpdatedByName returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetResponse) HasLastUpdatedByName() bool {
+ if o != nil && !isNil(o.LastUpdatedByName) {
+ return true
+ }
+
+ return false
+}
+
+// SetLastUpdatedByName gets a reference to the given string and assigns it to the LastUpdatedByName field.
+func (o *UpdateMetricRulesetResponse) SetLastUpdatedByName(v string) {
+ o.LastUpdatedByName = &v
+}
+
+// GetLastUpdated returns the LastUpdated field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetResponse) GetLastUpdated() int64 {
+ if o == nil || isNil(o.LastUpdated) {
+ var ret int64
+ return ret
+ }
+ return *o.LastUpdated
+}
+
+// GetLastUpdatedOk returns a tuple with the LastUpdated field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetResponse) GetLastUpdatedOk() (*int64, bool) {
+ if o == nil || isNil(o.LastUpdated) {
+ return nil, false
+ }
+ return o.LastUpdated, true
+}
+
+// HasLastUpdated returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetResponse) HasLastUpdated() bool {
+ if o != nil && !isNil(o.LastUpdated) {
+ return true
+ }
+
+ return false
+}
+
+// SetLastUpdated gets a reference to the given int64 and assigns it to the LastUpdated field.
+func (o *UpdateMetricRulesetResponse) SetLastUpdated(v int64) {
+ o.LastUpdated = &v
+}
+
+// GetMetricName returns the MetricName field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetResponse) GetMetricName() string {
+ if o == nil || isNil(o.MetricName) {
+ var ret string
+ return ret
+ }
+ return *o.MetricName
+}
+
+// GetMetricNameOk returns a tuple with the MetricName field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetResponse) GetMetricNameOk() (*string, bool) {
+ if o == nil || isNil(o.MetricName) {
+ return nil, false
+ }
+ return o.MetricName, true
+}
+
+// HasMetricName returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetResponse) HasMetricName() bool {
+ if o != nil && !isNil(o.MetricName) {
+ return true
+ }
+
+ return false
+}
+
+// SetMetricName gets a reference to the given string and assigns it to the MetricName field.
+func (o *UpdateMetricRulesetResponse) SetMetricName(v string) {
+ o.MetricName = &v
+}
+
+// GetRoutingRule returns the RoutingRule field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetResponse) GetRoutingRule() RoutingRule {
+ if o == nil || isNil(o.RoutingRule) {
+ var ret RoutingRule
+ return ret
+ }
+ return *o.RoutingRule
+}
+
+// GetRoutingRuleOk returns a tuple with the RoutingRule field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetResponse) GetRoutingRuleOk() (*RoutingRule, bool) {
+ if o == nil || isNil(o.RoutingRule) {
+ return nil, false
+ }
+ return o.RoutingRule, true
+}
+
+// HasRoutingRule returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetResponse) HasRoutingRule() bool {
+ if o != nil && !isNil(o.RoutingRule) {
+ return true
+ }
+
+ return false
+}
+
+// SetRoutingRule gets a reference to the given RoutingRule and assigns it to the RoutingRule field.
+func (o *UpdateMetricRulesetResponse) SetRoutingRule(v RoutingRule) {
+ o.RoutingRule = &v
+}
+
+// GetVersion returns the Version field value if set, zero value otherwise.
+func (o *UpdateMetricRulesetResponse) GetVersion() int64 {
+ if o == nil || isNil(o.Version) {
+ var ret int64
+ return ret
+ }
+ return *o.Version
+}
+
+// GetVersionOk returns a tuple with the Version field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *UpdateMetricRulesetResponse) GetVersionOk() (*int64, bool) {
+ if o == nil || isNil(o.Version) {
+ return nil, false
+ }
+ return o.Version, true
+}
+
+// HasVersion returns a boolean if a field has been set.
+func (o *UpdateMetricRulesetResponse) HasVersion() bool {
+ if o != nil && !isNil(o.Version) {
+ return true
+ }
+
+ return false
+}
+
+// SetVersion gets a reference to the given int64 and assigns it to the Version field.
+func (o *UpdateMetricRulesetResponse) SetVersion(v int64) {
+ o.Version = &v
+}
+
+func (o UpdateMetricRulesetResponse) MarshalJSON() ([]byte, error) {
+ toSerialize := map[string]interface{}{}
+ if !isNil(o.AggregationRules) {
+ toSerialize["aggregationRules"] = o.AggregationRules
+ }
+ if !isNil(o.Creator) {
+ toSerialize["creator"] = o.Creator
+ }
+ if !isNil(o.CreatorName) {
+ toSerialize["creatorName"] = o.CreatorName
+ }
+ if !isNil(o.Created) {
+ toSerialize["created"] = o.Created
+ }
+ if !isNil(o.Id) {
+ toSerialize["id"] = o.Id
+ }
+ if !isNil(o.LastUpdatedBy) {
+ toSerialize["lastUpdatedBy"] = o.LastUpdatedBy
+ }
+ if !isNil(o.LastUpdatedByName) {
+ toSerialize["lastUpdatedByName"] = o.LastUpdatedByName
+ }
+ if !isNil(o.LastUpdated) {
+ toSerialize["lastUpdated"] = o.LastUpdated
+ }
+ if !isNil(o.MetricName) {
+ toSerialize["metricName"] = o.MetricName
+ }
+ if !isNil(o.RoutingRule) {
+ toSerialize["routingRule"] = o.RoutingRule
+ }
+ if !isNil(o.Version) {
+ toSerialize["version"] = o.Version
+ }
+ return json.Marshal(toSerialize)
+}
+
+type NullableUpdateMetricRulesetResponse struct {
+ value *UpdateMetricRulesetResponse
+ isSet bool
+}
+
+func (v NullableUpdateMetricRulesetResponse) Get() *UpdateMetricRulesetResponse {
+ return v.value
+}
+
+func (v *NullableUpdateMetricRulesetResponse) Set(val *UpdateMetricRulesetResponse) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableUpdateMetricRulesetResponse) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableUpdateMetricRulesetResponse) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableUpdateMetricRulesetResponse(val *UpdateMetricRulesetResponse) *NullableUpdateMetricRulesetResponse {
+ return &NullableUpdateMetricRulesetResponse{value: val, isSet: true}
+}
+
+func (v NullableUpdateMetricRulesetResponse) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableUpdateMetricRulesetResponse) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+
diff --git a/metric_ruleset/utils.go b/metric_ruleset/utils.go
new file mode 100644
index 0000000..6ca6ba2
--- /dev/null
+++ b/metric_ruleset/utils.go
@@ -0,0 +1,343 @@
+/*
+Metric Ruleset API
+
+Metric ruleset API
+
+API version: 3.0.1
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package metric_ruleset
+
+import (
+ "encoding/json"
+ "reflect"
+ "time"
+)
+
+// PtrBool is a helper routine that returns a pointer to given boolean value.
+func PtrBool(v bool) *bool { return &v }
+
+// PtrInt is a helper routine that returns a pointer to given integer value.
+func PtrInt(v int) *int { return &v }
+
+// PtrInt32 is a helper routine that returns a pointer to given integer value.
+func PtrInt32(v int32) *int32 { return &v }
+
+// PtrInt64 is a helper routine that returns a pointer to given integer value.
+func PtrInt64(v int64) *int64 { return &v }
+
+// PtrFloat32 is a helper routine that returns a pointer to given float value.
+func PtrFloat32(v float32) *float32 { return &v }
+
+// PtrFloat64 is a helper routine that returns a pointer to given float value.
+func PtrFloat64(v float64) *float64 { return &v }
+
+// PtrString is a helper routine that returns a pointer to given string value.
+func PtrString(v string) *string { return &v }
+
+// PtrTime is helper routine that returns a pointer to given Time value.
+func PtrTime(v time.Time) *time.Time { return &v }
+
+type NullableBool struct {
+ value *bool
+ isSet bool
+}
+
+func (v NullableBool) Get() *bool {
+ return v.value
+}
+
+func (v *NullableBool) Set(val *bool) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableBool) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableBool) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableBool(val *bool) *NullableBool {
+ return &NullableBool{value: val, isSet: true}
+}
+
+func (v NullableBool) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableBool) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+type NullableInt struct {
+ value *int
+ isSet bool
+}
+
+func (v NullableInt) Get() *int {
+ return v.value
+}
+
+func (v *NullableInt) Set(val *int) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableInt) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableInt) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableInt(val *int) *NullableInt {
+ return &NullableInt{value: val, isSet: true}
+}
+
+func (v NullableInt) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableInt) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+type NullableInt32 struct {
+ value *int32
+ isSet bool
+}
+
+func (v NullableInt32) Get() *int32 {
+ return v.value
+}
+
+func (v *NullableInt32) Set(val *int32) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableInt32) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableInt32) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableInt32(val *int32) *NullableInt32 {
+ return &NullableInt32{value: val, isSet: true}
+}
+
+func (v NullableInt32) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableInt32) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+type NullableInt64 struct {
+ value *int64
+ isSet bool
+}
+
+func (v NullableInt64) Get() *int64 {
+ return v.value
+}
+
+func (v *NullableInt64) Set(val *int64) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableInt64) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableInt64) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableInt64(val *int64) *NullableInt64 {
+ return &NullableInt64{value: val, isSet: true}
+}
+
+func (v NullableInt64) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableInt64) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+type NullableFloat32 struct {
+ value *float32
+ isSet bool
+}
+
+func (v NullableFloat32) Get() *float32 {
+ return v.value
+}
+
+func (v *NullableFloat32) Set(val *float32) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableFloat32) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableFloat32) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableFloat32(val *float32) *NullableFloat32 {
+ return &NullableFloat32{value: val, isSet: true}
+}
+
+func (v NullableFloat32) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableFloat32) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+type NullableFloat64 struct {
+ value *float64
+ isSet bool
+}
+
+func (v NullableFloat64) Get() *float64 {
+ return v.value
+}
+
+func (v *NullableFloat64) Set(val *float64) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableFloat64) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableFloat64) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableFloat64(val *float64) *NullableFloat64 {
+ return &NullableFloat64{value: val, isSet: true}
+}
+
+func (v NullableFloat64) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableFloat64) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+type NullableString struct {
+ value *string
+ isSet bool
+}
+
+func (v NullableString) Get() *string {
+ return v.value
+}
+
+func (v *NullableString) Set(val *string) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableString) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableString) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableString(val *string) *NullableString {
+ return &NullableString{value: val, isSet: true}
+}
+
+func (v NullableString) MarshalJSON() ([]byte, error) {
+ return json.Marshal(v.value)
+}
+
+func (v *NullableString) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+type NullableTime struct {
+ value *time.Time
+ isSet bool
+}
+
+func (v NullableTime) Get() *time.Time {
+ return v.value
+}
+
+func (v *NullableTime) Set(val *time.Time) {
+ v.value = val
+ v.isSet = true
+}
+
+func (v NullableTime) IsSet() bool {
+ return v.isSet
+}
+
+func (v *NullableTime) Unset() {
+ v.value = nil
+ v.isSet = false
+}
+
+func NewNullableTime(val *time.Time) *NullableTime {
+ return &NullableTime{value: val, isSet: true}
+}
+
+func (v NullableTime) MarshalJSON() ([]byte, error) {
+ return v.value.MarshalJSON()
+}
+
+func (v *NullableTime) UnmarshalJSON(src []byte) error {
+ v.isSet = true
+ return json.Unmarshal(src, &v.value)
+}
+
+// isNil checks if an input is nil
+func isNil(i interface{}) bool {
+ if i == nil {
+ return true
+ }
+ switch reflect.TypeOf(i).Kind() {
+ case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.UnsafePointer, reflect.Interface, reflect.Slice:
+ return reflect.ValueOf(i).IsNil()
+ case reflect.Array:
+ return reflect.ValueOf(i).IsZero()
+ }
+ return false
+}
\ No newline at end of file
diff --git a/metric_ruleset_test.go b/metric_ruleset_test.go
new file mode 100644
index 0000000..abaf17c
--- /dev/null
+++ b/metric_ruleset_test.go
@@ -0,0 +1,135 @@
+package signalfx
+
+import (
+ "context"
+ "net/http"
+ "testing"
+
+ "github.com/signalfx/signalfx-go/metric_ruleset"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestCreateMetricRuleset(t *testing.T) {
+ teardown := setup()
+ defer teardown()
+
+ mux.HandleFunc(MetricRulesetApiURL, verifyRequest(t, http.MethodPost, true, http.StatusOK, nil, "metric_ruleset/create_ruleset_success.json"))
+
+ dest := metric_ruleset.FULL_FIDELITY
+ dropDimensions := false
+ ruleName := "TestRule"
+ result, err := client.CreateMetricRuleset(context.Background(), &metric_ruleset.CreateMetricRulesetRequest{
+ MetricName: "container_cpu_utilization",
+ Version: 1,
+ AggregationRules: []metric_ruleset.AggregationRule{
+ {
+ Name: &ruleName,
+ Enabled: true,
+ Matcher: metric_ruleset.MetricMatcher{
+ DimensionMatcher: &metric_ruleset.DimensionMatcher{
+ Filters: []metric_ruleset.PropertyFilter{},
+ },
+ },
+ Aggregator: metric_ruleset.MetricAggregator{
+ RollupAggregator: &metric_ruleset.RollupAggregator{
+ Type: "rollup",
+ OutputName: "container_cpu_utilization.by.sfx_realm.sfx_service.agg",
+ Dimensions: []string{"sfx_realm", "sfx_service"},
+ DropDimensions: &dropDimensions,
+ },
+ },
+ },
+ },
+ RoutingRule: metric_ruleset.RoutingRule{
+ Destination: (*string)(&dest),
+ },
+ })
+
+ assert.NoError(t, err, "Unexpected error creating metric ruleset")
+ assert.Equal(t, "container_cpu_utilization", *result.MetricName, "MetricName does not match")
+ assert.Equal(t, 1, len(result.AggregationRules), "Unexpected length of aggregation rules array")
+ assert.Equal(t, "rollup", result.AggregationRules[0].Aggregator.RollupAggregator.Type, "Aggregation Rule type does not match expected")
+}
+
+func TestGetMetricRuleset(t *testing.T) {
+ teardown := setup()
+ defer teardown()
+
+ mux.HandleFunc(MetricRulesetApiURL+"/TestId_MemoryUtilization", verifyRequest(t, http.MethodGet, true, http.StatusOK, nil, "metric_ruleset/get_ruleset_success.json"))
+
+ result, err := client.GetMetricRuleset(context.Background(), "TestId_MemoryUtilization")
+ assert.NoError(t, err, "Unexpected error getting metric ruleset")
+ assert.Equal(t, "memory.utilization", *result.MetricName, "MetricName does not match")
+}
+
+func TestUpdateMetricRuleset(t *testing.T) {
+ teardown := setup()
+ defer teardown()
+
+ mux.HandleFunc(MetricRulesetApiURL+"/TestId", verifyRequest(t, http.MethodPut, true, http.StatusOK, nil, "metric_ruleset/update_ruleset_success.json"))
+
+ metricName := "container_cpu_utilization"
+ dest := metric_ruleset.DROP
+ version := int64(2)
+ dropDimensions := false
+ ruleName := "UpdatedName"
+ result, err := client.UpdateMetricRuleset(context.Background(), "TestId", &metric_ruleset.UpdateMetricRulesetRequest{
+ MetricName: &metricName,
+ Version: &version,
+ AggregationRules: []metric_ruleset.AggregationRule{
+ {
+ Name: &ruleName,
+ Enabled: false,
+ Matcher: metric_ruleset.MetricMatcher{
+ DimensionMatcher: &metric_ruleset.DimensionMatcher{
+ Filters: []metric_ruleset.PropertyFilter{},
+ },
+ },
+ Aggregator: metric_ruleset.MetricAggregator{
+ RollupAggregator: &metric_ruleset.RollupAggregator{
+ Type: "rollup",
+ OutputName: "container_cpu_utilization.by.sfx_realm.sfx_service.agg",
+ Dimensions: []string{"sfx_realm", "sfx_service"},
+ DropDimensions: &dropDimensions,
+ },
+ },
+ },
+ },
+ RoutingRule: &metric_ruleset.RoutingRule{
+ Destination: (*string)(&dest),
+ },
+ })
+
+ assert.NoError(t, err, "Unexpected error updating metric ruleset")
+ assert.Equal(t, metricName, *result.MetricName, "Name does not match")
+ assert.Equal(t, 1, len(result.AggregationRules), "Unexpected length of aggregation rules array")
+ assert.Equal(t, false, result.AggregationRules[0].Enabled)
+ assert.Equal(t, "Drop", *result.RoutingRule.Destination)
+}
+
+func TestDeleteMetricRuleset(t *testing.T) {
+ teardown := setup()
+ defer teardown()
+
+ mux.HandleFunc(MetricRulesetApiURL+"/metric_ruleset_id", verifyRequest(t, http.MethodDelete, true, http.StatusNoContent, nil, ""))
+
+ err := client.DeleteMetricRuleset(context.Background(), "metric_ruleset_id")
+ assert.NoError(t, err, "Unexpected error deleting metric ruleset")
+}
+
+func TestGenerateAggregationMetricName(t *testing.T) {
+ teardown := setup()
+ defer teardown()
+
+ mux.HandleFunc(MetricRulesetApiURL+"/generateAggregationMetricName", verifyRequest(t, http.MethodPost, true, http.StatusOK, nil, "metric_ruleset/generate_aggregation_metric_name_success.txt"))
+
+ dropDimensions := false
+ result, err := client.GenerateAggregationMetricName(context.Background(), metric_ruleset.GenerateAggregationNameRequest{
+ MetricName: "cpu.utilization",
+ Dimensions: []string{"sfx_realm"},
+ DropDimensions: &dropDimensions,
+ })
+
+ assert.NoError(t, err, "Unexpected error generating aggregation metric name")
+ assert.Equal(t, "cpu.utilization.by.sfx_realm.agg", result)
+}
diff --git a/organization.go b/organization.go
index f5b3e66..0ef475c 100644
--- a/organization.go
+++ b/organization.go
@@ -112,6 +112,34 @@ func (c *Client) InviteMember(ctx context.Context, inviteRequest *organization.C
return finalMember, err
}
+// Updates admin status of a member.
+func (c *Client) UpdateMember(ctx context.Context, id string, updateRequest *organization.UpdateMemberRequest) (*organization.Member, error) {
+ payload, err := json.Marshal(updateRequest)
+ if err != nil {
+ return nil, err
+ }
+
+ resp, err := c.doRequest(ctx, "PUT", OrganizationMemberAPIURL+"/"+id, nil, bytes.NewReader(payload))
+ if resp != nil {
+ defer resp.Body.Close()
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ if resp.StatusCode != http.StatusOK {
+ message, _ := ioutil.ReadAll(resp.Body)
+ return nil, fmt.Errorf("Bad status %d: %s", resp.StatusCode, message)
+ }
+
+ finalMember := &organization.Member{}
+
+ err = json.NewDecoder(resp.Body).Decode(finalMember)
+ _, _ = io.Copy(ioutil.Discard, resp.Body)
+
+ return finalMember, err
+}
+
// InviteMembers invites many members to the organization.
func (c *Client) InviteMembers(ctx context.Context, inviteRequest *organization.InviteMembersRequest) (*organization.InviteMembersRequest, error) {
payload, err := json.Marshal(inviteRequest)
diff --git a/organization/model_organization.go b/organization/model_organization.go
index 7392b1b..bbec7f0 100644
--- a/organization/model_organization.go
+++ b/organization/model_organization.go
@@ -32,7 +32,7 @@ type Organization struct {
// The authentication key for the account that owns the organization.
AccountKey string `json:"accountKey,omitempty"`
// The renewal status for the account that owns the organization
- AccountRenews string `json:"accountRenews,omitempty"`
+ AccountRenews bool `json:"accountRenews,omitempty"`
// Specifies a date and time after which the account that owns the organization becomes invalid, in Unix time UTC-relative.
AccountValidUntil int64 `json:"accountValidUntil,omitempty"`
// Specifies the number of datapoints per minute that the organization can receive.
diff --git a/organization/model_update_member_request.go b/organization/model_update_member_request.go
new file mode 100644
index 0000000..69dc439
--- /dev/null
+++ b/organization/model_update_member_request.go
@@ -0,0 +1,15 @@
+/*
+ * Organizations API
+ *
+ * API for adding, retrieving, updating, and deleting members in a SignalFx organization.
## Overview Data coming in to SignalFx is associated with a single entity called an **organization** To access this data within an organization, users must be members of the organization. Most SignalFx users belong to a single organization, which they think of as their \"SignalFx account\".
All SignalFx users have user IDs that SignalFx assigns, which identifies the them across organizations at SignalFx. The SignalFx users for an organization also have a **member ID* that's specific to the organization.
To join an organization, SignalFx users need an invitation from an member that has administrative access to the organization. After users join an organization, they can do the following for the organization:
* Submit datapoints to their organization * Use the SignalFx web UI to look at their organization's data * Make requests with the SignalFx API to work with organization data ## Authentication To authenticate with SignalFx, the following operations require a session token associated with a SignalFx user that has administrative privileges:
* Retrieve metadata for the organization - **GET** `/organization` * Create, update, or delete custom categories for an organization - **PATCH** `/organization/custom-categories` * Invite a user to the organization - **POST** `/organization/member` * Retrieve information about the organization's users - **GET** `/organization/member` * Invite one or more users to the organization - **POST** `/organization/members` * Update the administrative privileges of a user - **PUT** `/organization/member/{id}` * Delete a user - **DELETE** `/organization/member/{id}` The following operations can authenticate with either an org token or a session token: * Get information for an organization member - **GET** `/organization/member/{id}` * Get all custom categories for an organization - **GET** `/organization/custom-categories`
+ *
+ * API version: 3.2.0
+ * Generated by: OpenAPI Generator (https://openapi-generator.tech)
+ */
+
+package organization
+
+type UpdateMemberRequest struct {
+ // Flag that indicates if the user should get administrative access to the organization. If `true`, SignalFx gives administrative access after the user joins.
+ Admin bool `json:"admin"`
+}
diff --git a/organization_test.go b/organization_test.go
index 6e1d6bd..bacfec9 100644
--- a/organization_test.go
+++ b/organization_test.go
@@ -69,6 +69,19 @@ func TestInviteMember(t *testing.T) {
assert.Equal(t, "string", results.Email, "Incorrect email")
}
+func TestUpdateMember(t *testing.T) {
+ teardown := setup()
+ defer teardown()
+
+ mux.HandleFunc("/v2/organization/member/string", verifyRequest(t, "PUT", true, http.StatusOK, nil, "organization/update_member_success.json"))
+
+ results, err := client.UpdateMember(context.Background(), "string", &organization.UpdateMemberRequest{
+ Admin: true,
+ })
+ assert.NoError(t, err, "Unexpected error updating member")
+ assert.Equal(t, true, results.Admin, "Incorrect admin config")
+}
+
func TestGetInviteMembers(t *testing.T) {
teardown := setup()
defer teardown()
diff --git a/signalflow/.golangci.yml b/signalflow/.golangci.yml
new file mode 100644
index 0000000..97174ea
--- /dev/null
+++ b/signalflow/.golangci.yml
@@ -0,0 +1,80 @@
+run:
+ timeout: 5m
+ tests: true
+ skip-dirs: []
+ # which files to skip: they will be analyzed, but issues from them
+ # won't be reported. Default value is empty list, but there is
+ # no need to include all autogenerated files, we confidently recognize
+ # autogenerated files. If it's not please let us know.
+ skip-files: []
+ # by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
+ # If invoked with -mod=readonly, the go command is disallowed from the implicit
+ # automatic updating of go.mod described above. Instead, it fails when any changes
+ # to go.mod are needed. This setting is most useful to check that go.mod does
+ # not need updates, such as in a continuous integration and testing system.
+ # If invoked with -mod=vendor, the go command assumes that the vendor
+ # directory holds the correct copies of dependencies and ignores
+ # the dependency descriptions in go.mod.
+ # modules-download-mode: readonly #|release|vendor
+
+
+linters-settings:
+ govet:
+ disable:
+ - composites
+ gosec:
+ excludes:
+ - G404
+
+linters:
+ enable:
+ - asciicheck
+ - depguard
+ - dupl
+ - durationcheck
+ - errorlint
+ - errname
+ - exportloopref
+ - forbidigo
+ - gci
+ - goconst
+ - gofmt
+ - gofumpt
+ - goheader
+ - goimports
+ - gomodguard
+ - goprintffuncname
+ - gosec
+ - gosimple
+ - govet
+ - ineffassign
+ - makezero
+ - misspell
+ - nakedret
+ - nilerr
+ - noctx
+ - prealloc
+ - predeclared
+ - revive
+ - staticcheck
+ - stylecheck
+ - thelper
+ - tparallel
+ - typecheck
+ - unconvert
+ - unparam
+ - wastedassign
+ - whitespace
+ disable-all: true
+ fast: true
+
+# output configuration options
+output:
+ # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
+ format: colored-line-number
+
+ # print lines of code with issue, default is true
+ print-issued-lines: true
+
+ # print linter name in the end of issue text, default is true
+ print-linter-name: true
diff --git a/signalflow/README.md b/signalflow/README.md
new file mode 100644
index 0000000..6b9e922
--- /dev/null
+++ b/signalflow/README.md
@@ -0,0 +1,58 @@
+# SignalFx SignalFlow Go Client
+
+This is a client for [SignalFlow](https://dev.splunk.com/observability/docs/signalflow) that lets
+you stream and analyze metric data in real-time for your organization.
+
+## Installation
+
+**You must use Go 1.19+ for the v2 of this client.**
+
+```
+go get github.com/signalfx/signalfx-go/signalflow/v2@latest
+```
+
+If you do not want to upgrade Go you can use the v1 version of the old client that supports older Go
+versions:
+
+```
+go get github.com/signalfx/signalfx-go@v1.30.0
+```
+
+## Usage
+
+The package must be imported like so:
+
+```
+import (
+ "github.com/signalfx/signalfx-go/signalflow/v2"
+)
+```
+
+See [./example/main.go]() for an example of how to use the client.
+
+SignalFlow itself is documented at https://dev.splunk.com/observability/docs/signalflow/messages.
+
+
+## Migration from v1
+
+If you previously used v1 of this module, you can migrate to v2 by doing the following:
+
+ - You must use Go 1.19+.
+
+ - Remove any uses of the `MetadataTimeout` client option. This has been replaced by the addition
+ of a `ctx` argument on all of the metadata getters (see below).
+
+ - Add a `context.Context` as the first argument to any of the `Computation` metadata getter
+ methods. You can control how long to wait for metadata by using a context with a timeout or
+ cancel. See [the example](./example/main.go).
+
+ - Add a `context.Context` as the first argument to each of the `Client` SignalFlow method calls.
+ This context can be used to cancel the calls in case of connection trouble. Previously these
+ calls could hang indefinitely.
+
+ - Remove references to the `Computation.Done()` method, which returned a channel that would be
+ closed when the computation was finished. You can know if the computation is finished based on
+ when the `Data` channel is closed.
+
+ - `Computation.Events` was removed entirely as it wasn't implemented correctly. Reach out if you
+ have a desire for it.
diff --git a/signalflow/channel.go b/signalflow/channel.go
deleted file mode 100644
index 94f8c59..0000000
--- a/signalflow/channel.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package signalflow
-
-import (
- "context"
- "sync"
-
- "github.com/signalfx/signalfx-go/signalflow/messages"
-)
-
-// Channel is a queue of messages that all pertain to the same computation.
-type Channel struct {
- sync.Mutex
-
- name string
- messages chan messages.Message
- ctx context.Context
- cancel context.CancelFunc
-}
-
-func newChannel(ctx context.Context, name string) *Channel {
- chanCtx, cancel := context.WithCancel(ctx)
- c := &Channel{
- name: name,
- messages: make(chan messages.Message),
- ctx: chanCtx,
- cancel: cancel,
- }
- return c
-}
-
-// AcceptMessage from a websocket. This might block if nothing is reading from
-// the channel but generally a computation should always be doing so.
-func (c *Channel) AcceptMessage(msg messages.Message) {
- select {
- case c.messages <- msg:
- case <-c.ctx.Done():
- return
- }
-}
-
-// Messages returns a Go chan that will be pushed all of the deserialized
-// SignalFlow messages from the websocket.
-func (c *Channel) Messages() <-chan messages.Message {
- return c.messages
-}
-
-// Close the channel. This does not actually stop a job in SignalFlow, for
-// that use Computation.Stop().
-func (c *Channel) Close() {
- c.cancel()
- close(c.messages)
-}
diff --git a/signalflow/channel_test.go b/signalflow/channel_test.go
deleted file mode 100644
index 98d25db..0000000
--- a/signalflow/channel_test.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package signalflow
-
-import (
- "context"
- "testing"
-
- "github.com/signalfx/signalfx-go/idtool"
- "github.com/signalfx/signalfx-go/signalflow/messages"
- "github.com/stretchr/testify/require"
-)
-
-func TestChannel(t *testing.T) {
- ch := newChannel(context.Background(), "test-ch")
-
- msg := messages.MetadataMessage{
- TSID: idtool.ID(4000),
- }
- go ch.AcceptMessage(&msg)
-
- require.Equal(t, &msg, (<-ch.Messages()).(*messages.MetadataMessage))
-}
diff --git a/signalflow/client.go b/signalflow/client.go
index 1458ed6..27c92e4 100644
--- a/signalflow/client.go
+++ b/signalflow/client.go
@@ -5,14 +5,14 @@ import (
"encoding/json"
"errors"
"fmt"
- "log"
+ "io"
"net/url"
"sync"
"sync/atomic"
"time"
"github.com/gorilla/websocket"
- "github.com/signalfx/signalfx-go/signalflow/messages"
+ "github.com/signalfx/signalfx-go/signalflow/v2/messages"
)
// Client for SignalFlow via websockets (SSE is not currently supported).
@@ -27,12 +27,18 @@ type Client struct {
// How long to wait for writes to the websocket to finish
writeTimeout time.Duration
streamURL *url.URL
- channelsByName map[string]*Channel
- outgoingCh chan *clientMessageRequest
+ onError OnErrorFunc
+ channelsByName map[string]chan messages.Message
- ctx context.Context
- cancel context.CancelFunc
+ // These are the lower-level WebSocket level channels for byte messages
+ outgoingTextMsgs chan *outgoingMessage
+ incomingTextMsgs chan []byte
+ incomingBinaryMsgs chan []byte
+ connectedCh chan struct{}
+
+ isClosed atomic.Bool
sync.Mutex
+ cancel context.CancelFunc
}
type clientMessageRequest struct {
@@ -82,20 +88,6 @@ func UserAgent(userAgent string) ClientParam {
}
}
-// MetadataTimeout is the default amount of time that calls to metadata
-// accessors on a SignalFlow Computation instance will wait to receive the
-// metadata from the backend before failing and returning a zero value. Usually
-// metadata comes in very quickly from the stream after the job start.
-func MetadataTimeout(timeout time.Duration) ClientParam {
- return func(c *Client) error {
- if timeout <= 0 {
- return errors.New("MetadataTimeout cannot be <= 0")
- }
- c.defaultMetadataTimeout = timeout
- return nil
- }
-}
-
// ReadTimeout sets the duration to wait between messages that come on the
// websocket. If the resolution of the job is very low, this should be
// increased.
@@ -121,6 +113,15 @@ func WriteTimeout(timeout time.Duration) ClientParam {
}
}
+type OnErrorFunc func(err error)
+
+func OnError(f OnErrorFunc) ClientParam {
+ return func(c *Client) error {
+ c.onError = f
+ return nil
+ }
+}
+
// NewClient makes a new SignalFlow client that will immediately try and
// connect to the SignalFlow backend.
func NewClient(options ...ClientParam) (*Client, error) {
@@ -130,11 +131,14 @@ func NewClient(options ...ClientParam) (*Client, error) {
Host: "stream.us0.signalfx.com",
Path: "/v2/signalflow",
},
- readTimeout: 1 * time.Minute,
- writeTimeout: 5 * time.Second,
- channelsByName: make(map[string]*Channel),
- defaultMetadataTimeout: 5 * time.Second,
- outgoingCh: make(chan *clientMessageRequest),
+ readTimeout: 1 * time.Minute,
+ writeTimeout: 5 * time.Second,
+ channelsByName: make(map[string]chan messages.Message),
+
+ outgoingTextMsgs: make(chan *outgoingMessage),
+ incomingTextMsgs: make(chan []byte),
+ incomingBinaryMsgs: make(chan []byte),
+ connectedCh: make(chan struct{}),
}
for i := range options {
@@ -143,27 +147,34 @@ func NewClient(options ...ClientParam) (*Client, error) {
}
}
- c.ctx, c.cancel = context.WithCancel(context.Background())
-
- c.conn = newWebsocketConn(c.ctx, c.streamURL)
- c.conn.ReadTimeout = c.readTimeout
- c.conn.WriteTimeout = c.writeTimeout
- c.conn.PostDisconnectCallback = func() {
- c.closeRegisteredChannels()
+ c.conn = &wsConn{
+ StreamURL: c.streamURL,
+ OutgoingTextMsgs: c.outgoingTextMsgs,
+ IncomingTextMsgs: c.incomingTextMsgs,
+ IncomingBinaryMsgs: c.incomingBinaryMsgs,
+ ConnectedCh: c.connectedCh,
+ ConnectTimeout: 10 * time.Second,
+ ReadTimeout: c.readTimeout,
+ WriteTimeout: c.writeTimeout,
+ OnError: c.onError,
+ PostDisconnectCallback: func() {
+ c.closeRegisteredChannels()
+ },
+ PostConnectMessage: func() []byte {
+ bytes, err := c.makeAuthRequest()
+ if err != nil {
+ c.sendErrIfWanted(fmt.Errorf("failed to send auth: %w", err))
+ return nil
+ }
+ return bytes
+ },
}
- c.conn.PostConnectMessage = func() []byte {
- bytes, err := c.makeAuthRequest()
- if err != nil {
- // This could almost be a panic
- log.Printf("Could not make auth request: %v", err)
- return nil
- }
- return bytes
- }
+ var ctx context.Context
+ ctx, c.cancel = context.WithCancel(context.Background())
- go c.conn.Run()
- go c.run()
+ go c.conn.Run(ctx)
+ go c.run(ctx)
return c, nil
}
@@ -173,64 +184,64 @@ func (c *Client) newUniqueChannelName() string {
return name
}
+func (c *Client) sendErrIfWanted(err error) {
+ if c.onError != nil {
+ c.onError(err)
+ }
+}
+
// Writes all messages from a single goroutine since that is required by
// websocket library.
-func (c *Client) run() {
+func (c *Client) run(ctx context.Context) {
for {
select {
- case <-c.ctx.Done():
+ case <-ctx.Done():
return
- case msg := <-c.conn.IncomingTextMessages():
+ case msg := <-c.incomingTextMsgs:
err := c.handleMessage(msg, websocket.TextMessage)
if err != nil {
- log.Printf("Error handling SignalFlow text message: %v", err)
+ c.sendErrIfWanted(fmt.Errorf("error handling SignalFlow text message: %w", err))
}
- case msg := <-c.conn.IncomingBinaryMessages():
+ case msg := <-c.incomingBinaryMsgs:
err := c.handleMessage(msg, websocket.BinaryMessage)
if err != nil {
- log.Printf("Error handling SignalFlow binary message: %v", err)
+ c.sendErrIfWanted(fmt.Errorf("error handling SignalFlow binary message: %w", err))
}
- case outMsg := <-c.outgoingCh:
- outMsg.resultCh <- c.serializeAndWriteMessage(outMsg.msg)
}
}
}
-func (c *Client) sendMessage(message interface{}) error {
+func (c *Client) sendMessage(ctx context.Context, message interface{}) error {
+ msgBytes, err := c.serializeMessage(message)
+ if err != nil {
+ return err
+ }
+
resultCh := make(chan error, 1)
- c.outgoingCh <- &clientMessageRequest{
- msg: message,
+ select {
+ case c.outgoingTextMsgs <- &outgoingMessage{
+ bytes: msgBytes,
resultCh: resultCh,
+ }:
+ return <-resultCh
+ case <-ctx.Done():
+ close(resultCh)
+ return ctx.Err()
}
- return <-resultCh
}
func (c *Client) serializeMessage(message interface{}) ([]byte, error) {
msgBytes, err := json.Marshal(message)
if err != nil {
- return nil, fmt.Errorf("could not marshal SignalFlow request: %v", err)
+ return nil, fmt.Errorf("could not marshal SignalFlow request: %w", err)
}
return msgBytes, nil
}
-func (c *Client) serializeAndWriteMessage(message interface{}) error {
- msgBytes, err := c.serializeMessage(message)
- if err != nil {
- return err
- }
-
- resultCh := make(chan error, 1)
- c.conn.OutgoingTextMessages() <- &outgoingMessage{
- bytes: msgBytes,
- resultCh: resultCh,
- }
- return <-resultCh
-}
-
func (c *Client) handleMessage(msgBytes []byte, msgTyp int) error {
message, err := messages.ParseMessage(msgBytes, msgTyp == websocket.TextMessage)
if err != nil {
- return fmt.Errorf("could not parse SignalFlow message: %v", err)
+ return fmt.Errorf("could not parse SignalFlow message: %w", err)
}
if cm, ok := message.(messages.ChannelMessage); ok {
@@ -245,7 +256,7 @@ func (c *Client) handleMessage(msgBytes []byte, msgTyp int) error {
c.acceptMessage(message)
return nil
}
- channel.AcceptMessage(message)
+ channel <- message
c.Unlock()
} else {
return c.acceptMessage(message)
@@ -279,32 +290,45 @@ func (c *Client) makeAuthRequest() ([]byte, error) {
// Execute a SignalFlow job and return a channel upon which informational
// messages and data will flow.
-func (c *Client) Execute(req *ExecuteRequest) (*Computation, error) {
+// See https://dev.splunk.com/observability/docs/signalflow/messages/websocket_request_messages#Execute-a-computation
+func (c *Client) Execute(ctx context.Context, req *ExecuteRequest) (*Computation, error) {
if req.Channel == "" {
req.Channel = c.newUniqueChannelName()
}
- err := c.sendMessage(req)
+ err := c.sendMessage(ctx, req)
if err != nil {
return nil, err
}
- return newComputation(c.ctx, c.registerChannel(req.Channel), c), nil
+ return newComputation(c.registerChannel(req.Channel), req.Channel, c), nil
+}
+
+// Detach from a computation but keep it running. See
+// https://dev.splunk.com/observability/docs/signalflow/messages/websocket_request_messages#Detach-from-a-computation.
+func (c *Client) Detach(ctx context.Context, req *DetachRequest) error {
+ // We are assuming that the detach request will always come from the same
+ // client that started it with the Execute method above, and thus the
+ // connection is still active (i.e. we don't need to call ensureInitialized
+ // here). If the websocket connection does drop, all jobs started by that
+ // connection get detached/stopped automatically.
+ return c.sendMessage(ctx, req)
}
// Stop sends a job stop request message to the backend. It does not wait for
// jobs to actually be stopped.
-func (c *Client) Stop(req *StopRequest) error {
+// See https://dev.splunk.com/observability/docs/signalflow/messages/websocket_request_messages#Stop-a-computation
+func (c *Client) Stop(ctx context.Context, req *StopRequest) error {
// We are assuming that the stop request will always come from the same
// client that started it with the Execute method above, and thus the
// connection is still active (i.e. we don't need to call ensureInitialized
// here). If the websocket connection does drop, all jobs started by that
// connection get stopped automatically.
- return c.sendMessage(req)
+ return c.sendMessage(ctx, req)
}
-func (c *Client) registerChannel(name string) *Channel {
- ch := newChannel(c.ctx, name)
+func (c *Client) registerChannel(name string) chan messages.Message {
+ ch := make(chan messages.Message)
c.Lock()
c.channelsByName[name] = ch
@@ -316,17 +340,32 @@ func (c *Client) registerChannel(name string) *Channel {
func (c *Client) closeRegisteredChannels() {
c.Lock()
for _, ch := range c.channelsByName {
- ch.Close()
+ close(ch)
}
- c.channelsByName = map[string]*Channel{}
+ c.channelsByName = map[string]chan messages.Message{}
c.Unlock()
}
-// Close the client and shutdown any ongoing connections and goroutines. The
-// client cannot be reused after Close.
+// Close the client and shutdown any ongoing connections and goroutines. The client cannot be
+// reused after Close. Calling any of the client methods after Close() is undefined and will likely
+// result in a panic.
func (c *Client) Close() {
- if c.cancel != nil {
- c.cancel()
+ if c.isClosed.Load() {
+ panic("cannot close client more than once")
}
+ c.isClosed.Store(true)
+
+ c.cancel()
c.closeRegisteredChannels()
+
+DRAIN:
+ for {
+ select {
+ case outMsg := <-c.outgoingTextMsgs:
+ outMsg.resultCh <- io.EOF
+ default:
+ break DRAIN
+ }
+ }
+ close(c.outgoingTextMsgs)
}
diff --git a/signalflow/client_test.go b/signalflow/client_test.go
index 4caddfe..af6fcad 100644
--- a/signalflow/client_test.go
+++ b/signalflow/client_test.go
@@ -1,18 +1,24 @@
package signalflow
import (
+ "context"
"fmt"
"log"
"math/rand"
+ "os"
+ "runtime"
+ "runtime/pprof"
+ "sync"
"testing"
"time"
"github.com/signalfx/signalfx-go/idtool"
- "github.com/signalfx/signalfx-go/signalflow/messages"
+ "github.com/signalfx/signalfx-go/signalflow/v2/messages"
"github.com/stretchr/testify/require"
)
func TestAuthenticationFlow(t *testing.T) {
+ t.Parallel()
fakeBackend := NewRunningFakeBackend()
defer fakeBackend.Stop()
@@ -20,17 +26,21 @@ func TestAuthenticationFlow(t *testing.T) {
require.Nil(t, err)
defer c.Close()
- comp, err := c.Execute(&ExecuteRequest{
+ comp, err := c.Execute(context.Background(), &ExecuteRequest{
Program: "data('cpu.utilization').publish()",
})
require.Nil(t, err)
- require.Equal(t, 1*time.Second, comp.Resolution())
+ resolution, _ := comp.Resolution(context.Background())
+ require.Equal(t, 1*time.Second, resolution)
require.Equal(t, []map[string]interface{}{
- {"type": "authenticate",
- "token": fakeBackend.AccessToken},
- {"type": "execute",
+ {
+ "type": "authenticate",
+ "token": fakeBackend.AccessToken,
+ },
+ {
+ "type": "execute",
"channel": "ch-1",
"immediate": false,
"maxDelay": 0.,
@@ -38,11 +48,13 @@ func TestAuthenticationFlow(t *testing.T) {
"resolution": 0.,
"start": 0.,
"stop": 0.,
- "timezone": ""},
+ "timezone": "",
+ },
}, fakeBackend.received)
}
func TestBasicComputation(t *testing.T) {
+ t.Parallel()
fakeBackend := NewRunningFakeBackend()
defer fakeBackend.Stop()
@@ -67,13 +79,14 @@ func TestBasicComputation(t *testing.T) {
program := "data('cpu.utilization').publish()"
fakeBackend.AddProgramTSIDs(program, tsids)
- comp, err := c.Execute(&ExecuteRequest{
+ comp, err := c.Execute(context.Background(), &ExecuteRequest{
Program: program,
Resolution: 1 * time.Second,
})
require.Nil(t, err)
- require.Equal(t, 1*time.Second, comp.Resolution())
+ resolution, _ := comp.Resolution(context.Background())
+ require.Equal(t, 1*time.Second, resolution)
dataMsg := <-comp.Data()
require.Len(t, dataMsg.Payloads, 2)
@@ -82,6 +95,7 @@ func TestBasicComputation(t *testing.T) {
}
func TestMultipleComputations(t *testing.T) {
+ t.Parallel()
fakeBackend := NewRunningFakeBackend()
defer fakeBackend.Stop()
@@ -90,14 +104,15 @@ func TestMultipleComputations(t *testing.T) {
defer c.Close()
for i := 1; i < 50; i++ {
- comp, err := c.Execute(&ExecuteRequest{
+ comp, err := c.Execute(context.Background(), &ExecuteRequest{
Program: "data('cpu.utilization').publish()",
Resolution: time.Duration(i) * time.Second,
})
require.Nil(t, err)
- require.Equal(t, time.Duration(i)*time.Second, comp.Resolution())
- require.Equal(t, fmt.Sprintf("ch-%d", i), comp.Channel().name)
+ resolution, _ := comp.Resolution(context.Background())
+ require.Equal(t, time.Duration(i)*time.Second, resolution)
+ require.Equal(t, fmt.Sprintf("ch-%d", i), comp.name)
}
}
@@ -107,29 +122,31 @@ func TestShutdown(t *testing.T) {
c, err := NewClient(StreamURL(fakeBackend.URL()), AccessToken(fakeBackend.AccessToken))
require.Nil(t, err)
- defer c.Close()
var comps []*Computation
for i := 1; i < 3; i++ {
- comp, err := c.Execute(&ExecuteRequest{
+ comp, err := c.Execute(context.Background(), &ExecuteRequest{
Program: "data('cpu.utilization').publish()",
Resolution: time.Duration(i) * time.Second,
})
require.Nil(t, err)
comps = append(comps, comp)
- require.Equal(t, time.Duration(i)*time.Second, comp.Resolution())
- require.Equal(t, fmt.Sprintf("ch-%d", i), comp.Channel().name)
+ resolution, _ := comp.Resolution(context.Background())
+ require.Equal(t, time.Duration(i)*time.Second, resolution)
+ require.Equal(t, fmt.Sprintf("ch-%d", i), comp.name)
}
c.Close()
for _, comp := range comps {
- require.True(t, comp.IsFinished())
+ _, ok := <-comp.Data()
+ require.False(t, ok)
}
}
func TestReconnect(t *testing.T) {
+ t.Parallel()
fakeBackend := NewRunningFakeBackend()
defer fakeBackend.Stop()
@@ -137,17 +154,21 @@ func TestReconnect(t *testing.T) {
require.Nil(t, err)
defer c.Close()
- comp, err := c.Execute(&ExecuteRequest{
+ comp, err := c.Execute(context.Background(), &ExecuteRequest{
Program: "data('cpu.utilization').publish()",
})
require.Nil(t, err)
- require.Equal(t, 1*time.Second, comp.Resolution())
+ resolution, _ := comp.Resolution(context.Background())
+ require.Equal(t, 1*time.Second, resolution)
require.Equal(t, []map[string]interface{}{
- {"type": "authenticate",
- "token": fakeBackend.AccessToken},
- {"type": "execute",
+ {
+ "type": "authenticate",
+ "token": fakeBackend.AccessToken,
+ },
+ {
+ "type": "execute",
"channel": "ch-1",
"immediate": false,
"maxDelay": 0.,
@@ -155,25 +176,35 @@ func TestReconnect(t *testing.T) {
"resolution": 0.,
"start": 0.,
"stop": 0.,
- "timezone": ""},
+ "timezone": "",
+ },
}, fakeBackend.received)
fakeBackend.KillExistingConnections()
- <-comp.Done()
+ for {
+ _, ok := <-comp.Data()
+ if !ok {
+ break
+ }
+ }
- comp, err = c.Execute(&ExecuteRequest{
+ comp, err = c.Execute(context.Background(), &ExecuteRequest{
Program: "data('cpu.utilization').publish()",
})
require.Nil(t, err)
- require.Equal(t, 1*time.Second, comp.Resolution())
+ resolution, _ = comp.Resolution(context.Background())
+ require.Equal(t, 1*time.Second, resolution)
log.Printf("%v", fakeBackend.received)
require.Equal(t, []map[string]interface{}{
- {"type": "authenticate",
- "token": fakeBackend.AccessToken},
- {"type": "execute",
+ {
+ "type": "authenticate",
+ "token": fakeBackend.AccessToken,
+ },
+ {
+ "type": "execute",
"channel": "ch-1",
"immediate": false,
"maxDelay": 0.,
@@ -181,10 +212,14 @@ func TestReconnect(t *testing.T) {
"resolution": 0.,
"start": 0.,
"stop": 0.,
- "timezone": ""},
- {"type": "authenticate",
- "token": fakeBackend.AccessToken},
- {"type": "execute",
+ "timezone": "",
+ },
+ {
+ "type": "authenticate",
+ "token": fakeBackend.AccessToken,
+ },
+ {
+ "type": "execute",
"channel": "ch-2",
"immediate": false,
"maxDelay": 0.,
@@ -192,11 +227,13 @@ func TestReconnect(t *testing.T) {
"resolution": 0.,
"start": 0.,
"stop": 0.,
- "timezone": ""},
+ "timezone": "",
+ },
}, fakeBackend.received)
}
func TestReconnectAfterBackendDown(t *testing.T) {
+ t.Parallel()
fakeBackend := NewRunningFakeBackend()
defer fakeBackend.Stop()
@@ -205,17 +242,21 @@ func TestReconnectAfterBackendDown(t *testing.T) {
defer c.Close()
- comp, err := c.Execute(&ExecuteRequest{
+ comp, err := c.Execute(context.Background(), &ExecuteRequest{
Program: "data('cpu.utilization').publish()",
})
require.Nil(t, err)
- require.Equal(t, 1*time.Second, comp.Resolution())
+ resolution, _ := comp.Resolution(context.Background())
+ require.Equal(t, 1*time.Second, resolution)
require.Equal(t, []map[string]interface{}{
- {"type": "authenticate",
- "token": fakeBackend.AccessToken},
- {"type": "execute",
+ {
+ "type": "authenticate",
+ "token": fakeBackend.AccessToken,
+ },
+ {
+ "type": "execute",
"channel": "ch-1",
"immediate": false,
"maxDelay": 0.,
@@ -223,26 +264,36 @@ func TestReconnectAfterBackendDown(t *testing.T) {
"resolution": 0.,
"start": 0.,
"stop": 0.,
- "timezone": ""},
+ "timezone": "",
+ },
}, fakeBackend.received)
fakeBackend.Stop()
- <-comp.Done()
+ for {
+ _, ok := <-comp.Data()
+ if !ok {
+ break
+ }
+ }
time.Sleep(7 * time.Second)
fakeBackend.Restart()
- comp, err = c.Execute(&ExecuteRequest{
+ comp, err = c.Execute(context.Background(), &ExecuteRequest{
Program: "data('cpu.utilization').publish()",
})
require.Nil(t, err)
- require.Equal(t, 1*time.Second, comp.Resolution())
+ resolution, _ = comp.Resolution(context.Background())
+ require.Equal(t, 1*time.Second, resolution)
require.Equal(t, []map[string]interface{}{
- {"type": "authenticate",
- "token": fakeBackend.AccessToken},
- {"type": "execute",
+ {
+ "type": "authenticate",
+ "token": fakeBackend.AccessToken,
+ },
+ {
+ "type": "execute",
"channel": "ch-1",
"immediate": false,
"maxDelay": 0.,
@@ -250,10 +301,14 @@ func TestReconnectAfterBackendDown(t *testing.T) {
"resolution": 0.,
"start": 0.,
"stop": 0.,
- "timezone": ""},
- {"type": "authenticate",
- "token": fakeBackend.AccessToken},
- {"type": "execute",
+ "timezone": "",
+ },
+ {
+ "type": "authenticate",
+ "token": fakeBackend.AccessToken,
+ },
+ {
+ "type": "execute",
"channel": "ch-2",
"immediate": false,
"maxDelay": 0.,
@@ -261,50 +316,46 @@ func TestReconnectAfterBackendDown(t *testing.T) {
"resolution": 0.,
"start": 0.,
"stop": 0.,
- "timezone": ""},
+ "timezone": "",
+ },
}, fakeBackend.received)
}
-func Example() {
- c, err := NewClient(
- StreamURLForRealm("us1"),
- AccessToken("MY_ORG_ACCESS_TOKEN"))
- if err != nil {
- log.Printf("Error creating client: %v", err)
- return
- }
+func TestFailedConnGoroutineShutdown(t *testing.T) {
+ defer func() {
+ time.Sleep(2 * time.Second)
+ pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
+ }()
- comp, err := c.Execute(&ExecuteRequest{
- Program: "data('cpu.utilization').publish()",
- })
- if err != nil {
- log.Printf("Could not send execute request: %v", err)
- return
- }
+ fakeBackend := NewRunningFakeBackend()
+ fakeBackend.Stop()
- fmt.Printf("Resolution: %v\n", comp.Resolution())
- fmt.Printf("Max Delay: %v\n", comp.MaxDelay())
- fmt.Printf("Detected Lag: %v\n", comp.Lag())
-
- for msg := range comp.Data() {
- // This will run as long as there is data, or until the websocket gets
- // disconnected. If a websocket error occurs, the job will NOT be
- // automatically restarted.
- if len(msg.Payloads) == 0 {
- fmt.Printf("\rNo data available")
- continue
- }
- for _, pl := range msg.Payloads {
- meta := comp.TSIDMetadata(pl.TSID)
- fmt.Printf("%s %v: %v\n", meta.OriginatingMetric, meta.CustomProperties, pl.Value())
- }
- fmt.Println("")
+ startingGoroutines := runtime.NumGoroutine()
+ clients := make([]*Client, 100)
+ var wg sync.WaitGroup
+ for i := range clients {
+ var err error
+ clients[i], err = NewClient(StreamURL(fakeBackend.URL()), AccessToken(fakeBackend.AccessToken))
+ require.Nil(t, err)
+
+ wg.Add(1)
+ go func(c *Client) {
+ ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
+ _, err = c.Execute(ctx, &ExecuteRequest{
+ Program: "data('cpu.utilization').publish()",
+ })
+ cancel()
+ t.Logf("execute error: %v", err)
+ require.Error(t, err)
+ wg.Done()
+ }(clients[i])
}
+ wg.Wait()
- err = comp.Err()
- if err != nil {
- log.Printf("Error: %v", comp.Err())
- } else {
- log.Printf("Job completed")
+ for _, c := range clients {
+ c.Close()
}
+ time.Sleep(1 * time.Second)
+
+ require.InDelta(t, startingGoroutines, runtime.NumGoroutine(), 10)
}
diff --git a/signalflow/computation.go b/signalflow/computation.go
index df8e70b..4cd4de6 100644
--- a/signalflow/computation.go
+++ b/signalflow/computation.go
@@ -2,47 +2,43 @@ package signalflow
import (
"context"
+ "errors"
"fmt"
"sync"
"time"
- "github.com/signalfx/golib/v3/pointer"
"github.com/signalfx/signalfx-go/idtool"
- "github.com/signalfx/signalfx-go/signalflow/messages"
+ "github.com/signalfx/signalfx-go/signalflow/v2/messages"
)
// Computation is a single running SignalFlow job
type Computation struct {
- ctx context.Context
- cancel context.CancelFunc
- channel *Channel
+ sync.Mutex
+ channel <-chan messages.Message
+ name string
client *Client
dataCh chan *messages.DataMessage
// An intermediate channel for data messages where they can be buffered if
// nothing is currently pulling data messages.
dataChBuffer chan *messages.DataMessage
+ eventCh chan *messages.EventMessage
+ eventChBuffer chan *messages.EventMessage
expirationCh chan *messages.ExpiredTSIDMessage
expirationChBuffer chan *messages.ExpiredTSIDMessage
- updateSignal updateSignal
- lastError error
-
- resolutionMS *int
- lagMS *int
- maxDelayMS *int
- matchedSize *int
- limitSize *int
- matchedNoTimeseriesQuery *string
- groupByMissingProperties []string
-
- tsidMetadata map[idtool.ID]*messages.MetadataProperties
- events []*messages.EventMessage
-
- handle string
-
- // The timeout to wait for metadata when a metadata access function is
- // called. This will default to what is set on the client, but can be
- // overridden by changing this field directly.
- MetadataTimeout time.Duration
+
+ errMutex sync.RWMutex
+ lastError error
+
+ handle asyncMetadata[string]
+ resolutionMS asyncMetadata[int]
+ lagMS asyncMetadata[int]
+ maxDelayMS asyncMetadata[int]
+ matchedSize asyncMetadata[int]
+ limitSize asyncMetadata[int]
+ matchedNoTimeseriesQuery asyncMetadata[string]
+ groupByMissingProperties asyncMetadata[[]string]
+
+ tsidMetadata map[idtool.ID]*asyncMetadata[*messages.MetadataProperties]
}
// ComputationError exposes the underlying metadata of a computation error
@@ -63,220 +59,153 @@ func (e *ComputationError) Error() string {
return err
}
-func newComputation(ctx context.Context, channel *Channel, client *Client) *Computation {
- newCtx, cancel := context.WithCancel(ctx)
+func newComputation(channel <-chan messages.Message, name string, client *Client) *Computation {
comp := &Computation{
- ctx: newCtx,
- cancel: cancel,
channel: channel,
+ name: name,
client: client,
dataCh: make(chan *messages.DataMessage),
dataChBuffer: make(chan *messages.DataMessage),
+ eventCh: make(chan *messages.EventMessage),
+ eventChBuffer: make(chan *messages.EventMessage),
expirationCh: make(chan *messages.ExpiredTSIDMessage),
expirationChBuffer: make(chan *messages.ExpiredTSIDMessage),
- tsidMetadata: make(map[idtool.ID]*messages.MetadataProperties),
- updateSignal: updateSignal{},
- MetadataTimeout: client.defaultMetadataTimeout,
+ tsidMetadata: make(map[idtool.ID]*asyncMetadata[*messages.MetadataProperties]),
}
- go comp.bufferDataMessages()
- go comp.bufferExpirationMessages()
- go comp.watchMessages()
- return comp
-}
+ go bufferMessages(comp.dataChBuffer, comp.dataCh)
+ go bufferMessages(comp.expirationChBuffer, comp.expirationCh)
+ go bufferMessages(comp.eventChBuffer, comp.eventCh)
-// Channel returns the underlying Channel instance used by this computation.
-func (c *Computation) Channel() *Channel {
- return c.channel
-}
+ go func() {
+ err := comp.watchMessages()
-// Handle of the computation
-func (c *Computation) Handle() string {
- if err := c.waitForMetadata(func() bool { return c.handle != "" }); err != nil {
- return ""
- }
- return c.handle
-}
-
-// Waits for the given cond func to return true, or until the metadata timeout
-// duration has passed.
-func (c *Computation) waitForMetadata(cond func() bool) error {
- c.updateSignal.Lock()
- defer c.updateSignal.Unlock()
- remaining := c.MetadataTimeout
- for !cond() {
- if err := c.updateSignal.WaitWithTimeout(c.ctx, &remaining); err != nil {
- return err
+ if !errors.Is(err, errChannelClosed) {
+ comp.errMutex.Lock()
+ comp.lastError = err
+ comp.errMutex.Unlock()
}
- }
- return nil
-}
-// Resolution of the job. This will wait for a short while for the resolution
-// message to come on the websocket, but will return 0 after a timeout if it
-// does not come.
-func (c *Computation) Resolution() time.Duration {
- if err := c.waitForMetadata(func() bool { return c.resolutionMS != nil }); err != nil {
- return 0
- }
- c.updateSignal.Lock()
- defer c.updateSignal.Unlock()
- return time.Duration(*c.resolutionMS) * time.Millisecond
+ comp.shutdown()
+ }()
+
+ return comp
}
-// Lag detected for the job. This will wait for a short while for the lag
-// message to come on the websocket, but will return 0 after a timeout if it
-// does not come.
-func (c *Computation) Lag() time.Duration {
- if err := c.waitForMetadata(func() bool { return c.lagMS != nil }); err != nil {
- return 0
- }
- c.updateSignal.Lock()
- defer c.updateSignal.Unlock()
- return time.Duration(*c.lagMS) * time.Millisecond
+// Handle of the computation. Will wait as long as the given ctx is not closed. If ctx is closed an
+// error will be returned.
+func (c *Computation) Handle(ctx context.Context) (string, error) {
+ return c.handle.Get(ctx)
}
-// MaxDelay detected of the job. This will wait for a short while for the max
-// delay message to come on the websocket, but will return 0 after a timeout if
-// it does not come.
-func (c *Computation) MaxDelay() time.Duration {
- if err := c.waitForMetadata(func() bool { return c.maxDelayMS != nil }); err != nil {
- return 0
- }
- c.updateSignal.Lock()
- defer c.updateSignal.Unlock()
- return time.Duration(*c.maxDelayMS) * time.Millisecond
+// Resolution of the job. Will wait as long as the given ctx is not closed. If ctx is closed an
+// error will be returned.
+func (c *Computation) Resolution(ctx context.Context) (time.Duration, error) {
+ resMS, err := c.resolutionMS.Get(ctx)
+ return time.Duration(resMS) * time.Millisecond, err
}
-// MatchedSize detected of the job. This will wait for a short while for the matched
-// size message to come on the websocket, but will return 0 after a timeout if
-// it does not come.
-func (c *Computation) MatchedSize() int {
- if err := c.waitForMetadata(func() bool { return c.matchedSize != nil }); err != nil {
- return 0
- }
- c.updateSignal.Lock()
- defer c.updateSignal.Unlock()
- return *c.matchedSize
+// Lag detected for the job. Will wait as long as the given ctx is not closed. If ctx is closed an
+// error will be returned.
+func (c *Computation) Lag(ctx context.Context) (time.Duration, error) {
+ lagMS, err := c.lagMS.Get(ctx)
+ return time.Duration(lagMS) * time.Millisecond, err
}
-// LimitSize detected of the job. This will wait for a short while for the limit
-// size message to come on the websocket, but will return 0 after a timeout if
-// it does not come.
-func (c *Computation) LimitSize() int {
- if err := c.waitForMetadata(func() bool { return c.limitSize != nil }); err != nil {
- return 0
- }
- c.updateSignal.Lock()
- defer c.updateSignal.Unlock()
- return *c.limitSize
+// MaxDelay detected of the job. Will wait as long as the given ctx is not closed. If ctx is closed an
+// error will be returned.
+func (c *Computation) MaxDelay(ctx context.Context) (time.Duration, error) {
+ maxDelayMS, err := c.maxDelayMS.Get(ctx)
+ return time.Duration(maxDelayMS) * time.Millisecond, err
}
-// MatchedNoTimeseriesQuery if it matched no active timeseries.
-// This will wait for a short while for the limit
-// size message to come on the websocket, but will return "" after a timeout if
-// it does not come.
-func (c *Computation) MatchedNoTimeseriesQuery() string {
- if err := c.waitForMetadata(func() bool { return c.matchedNoTimeseriesQuery != nil }); err != nil {
- return ""
- }
- c.updateSignal.Lock()
- defer c.updateSignal.Unlock()
- return *c.matchedNoTimeseriesQuery
+// MatchedSize detected of the job. Will wait as long as the given ctx is not closed. If ctx is closed an
+// error will be returned.
+func (c *Computation) MatchedSize(ctx context.Context) (int, error) {
+ return c.matchedSize.Get(ctx)
}
-// GroupByMissingProperties are timeseries that don't contain the required dimensions.
-// This will wait for a short while for the limit
-// size message to come on the websocket, but will return nil after a timeout if
-// it does not come.
-func (c *Computation) GroupByMissingProperties() []string {
- if err := c.waitForMetadata(func() bool { return c.groupByMissingProperties != nil }); err != nil {
- return nil
- }
- c.updateSignal.Lock()
- defer c.updateSignal.Unlock()
- return c.groupByMissingProperties
+// LimitSize detected of the job. Will wait as long as the given ctx is not closed. If ctx is closed an
+// error will be returned.
+func (c *Computation) LimitSize(ctx context.Context) (int, error) {
+ return c.limitSize.Get(ctx)
}
-// TSIDMetadata for a particular tsid. This will wait for a short while for
-// the tsid metadata message to come on the websocket, but will return nil
-// after a timeout if it does not come.
-func (c *Computation) TSIDMetadata(tsid idtool.ID) *messages.MetadataProperties {
- if err := c.waitForMetadata(func() bool { return c.tsidMetadata[tsid] != nil }); err != nil {
- return nil
- }
- c.updateSignal.Lock()
- defer c.updateSignal.Unlock()
- return c.tsidMetadata[tsid]
+// MatchedNoTimeseriesQuery if it matched no active timeseries. Will wait as long as the given ctx
+// is not closed. If ctx is closed an error will be returned.
+func (c *Computation) MatchedNoTimeseriesQuery(ctx context.Context) (string, error) {
+ return c.matchedNoTimeseriesQuery.Get(ctx)
}
-// Events returns the results from events or alerts queries.
-func (c *Computation) Events() []*messages.EventMessage {
- if err := c.waitForMetadata(func() bool { return c.events != nil }); err != nil {
- return nil
- }
- c.updateSignal.Lock()
- defer c.updateSignal.Unlock()
- return c.events
+// GroupByMissingProperties are timeseries that don't contain the required dimensions. Will wait as
+// long as the given ctx is not closed. If ctx is closed an error will be returned.
+func (c *Computation) GroupByMissingProperties(ctx context.Context) ([]string, error) {
+ return c.groupByMissingProperties.Get(ctx)
}
-// Done passes through the computation context's Done channel for use in select
-// statements to know when the computation is finished or an error occurred.
-func (c *Computation) Done() <-chan struct{} {
- return c.ctx.Done()
+// TSIDMetadata for a particular tsid. Will wait as long as the given ctx is not closed. If ctx is closed an
+// error will be returned.
+func (c *Computation) TSIDMetadata(ctx context.Context, tsid idtool.ID) (*messages.MetadataProperties, error) {
+ c.Lock()
+ if _, ok := c.tsidMetadata[tsid]; !ok {
+ c.tsidMetadata[tsid] = &asyncMetadata[*messages.MetadataProperties]{}
+ }
+ md := c.tsidMetadata[tsid]
+ c.Unlock()
+ return md.Get(ctx)
}
// Err returns the last fatal error that caused the computation to stop, if
// any. Will be nil if the computation stopped in an expected manner.
func (c *Computation) Err() error {
+ c.errMutex.RLock()
+ defer c.errMutex.RUnlock()
+
return c.lastError
}
-func (c *Computation) watchMessages() {
+func (c *Computation) watchMessages() error {
for {
- select {
- case <-c.ctx.Done():
- return
- case m, ok := <-c.channel.Messages():
- if !ok {
- c.cancel()
- continue
- }
- c.processMessage(m)
+ m, ok := <-c.channel
+ if !ok {
+ return nil
+ }
+ if err := c.processMessage(m); err != nil {
+ return err
}
}
}
-func (c *Computation) processMessage(m messages.Message) {
- defer c.updateSignal.SignalAll()
- c.updateSignal.Lock()
- defer c.updateSignal.Unlock()
+var errChannelClosed = errors.New("computation channel is closed")
+func (c *Computation) processMessage(m messages.Message) error {
switch v := m.(type) {
case *messages.JobStartControlMessage:
- c.handle = v.Handle
+ c.handle.Set(v.Handle)
case *messages.EndOfChannelControlMessage, *messages.ChannelAbortControlMessage:
- c.cancel()
+ return errChannelClosed
case *messages.DataMessage:
c.dataChBuffer <- v
case *messages.ExpiredTSIDMessage:
+ c.Lock()
delete(c.tsidMetadata, idtool.IDFromString(v.TSID))
+ c.Unlock()
c.expirationChBuffer <- v
case *messages.InfoMessage:
switch v.MessageBlock.Code {
case messages.JobRunningResolution:
- c.resolutionMS = pointer.Int(v.MessageBlock.Contents.(messages.JobRunningResolutionContents).ResolutionMS())
+ c.resolutionMS.Set(v.MessageBlock.Contents.(messages.JobRunningResolutionContents).ResolutionMS())
case messages.JobDetectedLag:
- c.lagMS = pointer.Int(v.MessageBlock.Contents.(messages.JobDetectedLagContents).LagMS())
+ c.lagMS.Set(v.MessageBlock.Contents.(messages.JobDetectedLagContents).LagMS())
case messages.JobInitialMaxDelay:
- c.maxDelayMS = pointer.Int(v.MessageBlock.Contents.(messages.JobInitialMaxDelayContents).MaxDelayMS())
+ c.maxDelayMS.Set(v.MessageBlock.Contents.(messages.JobInitialMaxDelayContents).MaxDelayMS())
case messages.FindLimitedResultSet:
- c.matchedSize = pointer.Int(v.MessageBlock.Contents.(messages.FindLimitedResultSetContents).MatchedSize())
- c.limitSize = pointer.Int(v.MessageBlock.Contents.(messages.FindLimitedResultSetContents).LimitSize())
+ c.matchedSize.Set(v.MessageBlock.Contents.(messages.FindLimitedResultSetContents).MatchedSize())
+ c.limitSize.Set(v.MessageBlock.Contents.(messages.FindLimitedResultSetContents).LimitSize())
case messages.FindMatchedNoTimeseries:
- c.matchedNoTimeseriesQuery = pointer.String(v.MessageBlock.Contents.(messages.FindMatchedNoTimeseriesContents).MatchedNoTimeseriesQuery())
+ c.matchedNoTimeseriesQuery.Set(v.MessageBlock.Contents.(messages.FindMatchedNoTimeseriesContents).MatchedNoTimeseriesQuery())
case messages.GroupByMissingProperty:
- c.groupByMissingProperties = v.MessageBlock.Contents.(messages.GroupByMissingPropertyContents).GroupByMissingProperties()
+ c.groupByMissingProperties.Set(v.MessageBlock.Contents.(messages.GroupByMissingPropertyContents).GroupByMissingProperties())
}
case *messages.ErrorMessage:
rawData := v.RawData()
@@ -290,83 +219,33 @@ func (c *Computation) processMessage(m messages.Message) {
if errType, ok := rawData["errorType"]; ok {
computationError.ErrorType = errType.(string)
}
- c.lastError = &computationError
- c.cancel()
+ return &computationError
case *messages.MetadataMessage:
- c.tsidMetadata[v.TSID] = &v.Properties
- case *messages.EventMessage:
- c.events = append(c.events, v)
- }
-}
-
-// Buffer up data messages indefinitely until another goroutine reads them off of
-// c.messages, which is an unbuffered channel.
-func (c *Computation) bufferDataMessages() {
- buffer := make([]*messages.DataMessage, 0)
- var nextMessage *messages.DataMessage
-
- defer func() {
- if nextMessage != nil {
- c.dataCh <- nextMessage
- }
- for i := range buffer {
- c.dataCh <- buffer[i]
- }
-
- select {
- case msg := <- c.dataChBuffer:
- c.dataCh <- msg
- default:
- }
-
- close(c.dataCh)
- }()
-
- for {
- if len(buffer) > 0 {
- if nextMessage == nil {
- nextMessage, buffer = buffer[0], buffer[1:]
- }
- select {
- case <-c.ctx.Done():
- return
- case c.dataCh <- nextMessage:
- nextMessage = nil
- case msg := <-c.dataChBuffer:
- buffer = append(buffer, msg)
- }
- } else {
- select {
- case <-c.ctx.Done():
- return
- case msg := <-c.dataChBuffer:
- buffer = append(buffer, msg)
- }
+ c.Lock()
+ if _, ok := c.tsidMetadata[v.TSID]; !ok {
+ c.tsidMetadata[v.TSID] = &asyncMetadata[*messages.MetadataProperties]{}
}
+ c.tsidMetadata[v.TSID].Set(&v.Properties)
+ c.Unlock()
+ case *messages.EventMessage:
+ c.eventChBuffer <- v
}
+ return nil
}
-// Buffer up expiration messages indefinitely until another goroutine reads
-// them off of c.expirationCh, which is an unbuffered channel.
-func (c *Computation) bufferExpirationMessages() {
- buffer := make([]*messages.ExpiredTSIDMessage, 0)
- var nextMessage *messages.ExpiredTSIDMessage
+func bufferMessages[T any](in chan *T, out chan *T) {
+ buffer := make([]*T, 0)
+ var nextMessage *T
defer func() {
if nextMessage != nil {
- c.expirationCh <- nextMessage
+ out <- nextMessage
}
for i := range buffer {
- c.expirationCh <- buffer[i]
- }
-
- select {
- case msg := <- c.expirationChBuffer:
- c.expirationCh <- msg
- default:
+ out <- buffer[i]
}
- close(c.expirationCh)
+ close(out)
}()
for {
if len(buffer) > 0 {
@@ -375,107 +254,116 @@ func (c *Computation) bufferExpirationMessages() {
}
select {
- case <-c.ctx.Done():
- return
- case c.expirationCh <- nextMessage:
+ case out <- nextMessage:
nextMessage = nil
- case msg := <-c.expirationChBuffer:
+ case msg, ok := <-in:
+ if !ok {
+ return
+ }
buffer = append(buffer, msg)
}
} else {
- select {
- case <-c.ctx.Done():
+ msg, ok := <-in
+ if !ok {
return
- case msg := <-c.expirationChBuffer:
- buffer = append(buffer, msg)
}
+ buffer = append(buffer, msg)
}
}
}
-// Data returns the channel on which data messages come.
+// Data returns the channel on which data messages come. This channel will be closed when the
+// computation is finished. To prevent goroutine leaks, you should read all messages from this
+// channel until it is closed.
func (c *Computation) Data() <-chan *messages.DataMessage {
return c.dataCh
}
-// Expirations returns a channel that will be sent messages about expired
-// TSIDs, i.e. time series that are no longer valid for this computation.
+// Expirations returns a channel that will be sent messages about expired TSIDs, i.e. time series
+// that are no longer valid for this computation. This channel will be closed when the computation
+// is finished. To prevent goroutine leaks, you should read all messages from this channel until it
+// is closed.
func (c *Computation) Expirations() <-chan *messages.ExpiredTSIDMessage {
return c.expirationCh
}
-// IsFinished returns true if the computation is done and no more data should
-// be expected from it.
-func (c *Computation) IsFinished() bool {
- // The context will have a non-nil err if it was cancelled.
- return c.ctx.Err() != nil
+// Events returns a channel that receives event/alert messages from the signalflow computation.
+func (c *Computation) Events() <-chan *messages.EventMessage {
+ return c.eventCh
+}
+
+// Detach the computation on the backend
+func (c *Computation) Detach(ctx context.Context) error {
+ return c.DetachWithReason(ctx, "")
+}
+
+// DetachWithReason detaches the computation with a given reason. This reason will
+// be reflected in the control message that signals the end of the job/channel
+func (c *Computation) DetachWithReason(ctx context.Context, reason string) error {
+ return c.client.Detach(ctx, &DetachRequest{
+ Reason: reason,
+ Channel: c.name,
+ })
}
// Stop the computation on the backend.
-func (c *Computation) Stop() error {
- return c.StopWithReason("")
+func (c *Computation) Stop(ctx context.Context) error {
+ return c.StopWithReason(ctx, "")
}
// StopWithReason stops the computation with a given reason. This reason will
// be reflected in the control message that signals the end of the job/channel.
-func (c *Computation) StopWithReason(reason string) error {
- return c.client.Stop(&StopRequest{
+func (c *Computation) StopWithReason(ctx context.Context, reason string) error {
+ handle, err := c.handle.Get(ctx)
+ if err != nil {
+ return err
+ }
+ return c.client.Stop(ctx, &StopRequest{
Reason: reason,
- Handle: c.handle,
+ Handle: handle,
})
}
-// Simple struct that allows one goroutine to signal a bunch of other
-// goroutines that are waiting on a condition, with a timeout. It is basically
-// similar to sync.Cond except the lock in internal (but accessible) and you
-// can set a timeout.
-type updateSignal struct {
- sync.Mutex
- s chan struct{}
+func (c *Computation) shutdown() {
+ close(c.dataChBuffer)
+ close(c.expirationChBuffer)
}
-// WaitWithTimeout waits for the given duration, remaining, for the signal to
-// be triggered. It is assumed that the caller holds u.Mutex upon calling.
-// When this function returns, that mutex will be relocked, but will have been
-// unlocked for some time while waiting. The remaining arg will be updated in
-// place to contain the remaining time when the function returned.
-func (u *updateSignal) WaitWithTimeout(ctx context.Context, remaining *time.Duration) error {
- start := time.Now()
+var ErrMetadataTimeout = errors.New("metadata value did not come in time")
- if u.s == nil {
- u.reset()
- }
- sig := u.s
- u.Unlock()
- defer func() {
- newRemaining := *remaining - time.Since(start)
- if newRemaining > 0 {
- *remaining = newRemaining
- } else {
- *remaining = 0
- }
- }()
- defer u.Lock()
+type asyncMetadata[T any] struct {
+ sync.Mutex
+ sig chan struct{}
+ isSet bool
+ val T
+}
- ctxTimeout, cancel := context.WithTimeout(ctx, *remaining)
- defer cancel()
- select {
- case <-ctxTimeout.Done():
- return ctxTimeout.Err()
- case <-sig:
- return nil
+func (a *asyncMetadata[T]) ensureInit() {
+ a.Lock()
+ if a.sig == nil {
+ a.sig = make(chan struct{})
}
+ a.Unlock()
}
-func (u *updateSignal) reset() {
- u.s = make(chan struct{})
+func (a *asyncMetadata[T]) Set(val T) {
+ a.ensureInit()
+ a.Lock()
+ a.val = val
+ if !a.isSet {
+ close(a.sig)
+ a.isSet = true
+ }
+ a.Unlock()
}
-func (u *updateSignal) SignalAll() {
- u.Lock()
- if u.s != nil {
- close(u.s)
- u.reset()
+func (a *asyncMetadata[T]) Get(ctx context.Context) (T, error) {
+ a.ensureInit()
+ select {
+ case <-ctx.Done():
+ var t T
+ return t, ErrMetadataTimeout
+ case <-a.sig:
+ return a.val, nil
}
- u.Unlock()
}
diff --git a/signalflow/computation_test.go b/signalflow/computation_test.go
index be38ac1..cd113ab 100644
--- a/signalflow/computation_test.go
+++ b/signalflow/computation_test.go
@@ -2,104 +2,122 @@ package signalflow
import (
"context"
+ "errors"
"sync"
"testing"
"time"
"github.com/signalfx/signalfx-go/idtool"
- "github.com/signalfx/signalfx-go/signalflow/messages"
+ "github.com/signalfx/signalfx-go/signalflow/v2/messages"
"github.com/stretchr/testify/require"
)
-func waitForDataMsg(t *testing.T, comp *Computation) (messages.Message, error) {
- ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
- defer cancel()
- for {
- select {
- case m := <-comp.Data():
- if m == nil {
- continue
- }
- return m, nil
- case <-ctx.Done():
- err := comp.Err()
- if err != nil {
- return nil, err
- }
-
- t.Fatal("data message didn't get buffered")
- }
- }
-}
-
func TestBuffersDataMessages(t *testing.T) {
- ch := newChannel(context.Background(), "ch1")
- comp := newComputation(context.Background(), ch, &Client{
+ t.Parallel()
+ ch := make(chan messages.Message)
+ comp := newComputation(ch, "ch1", &Client{
defaultMetadataTimeout: 1 * time.Second,
})
- defer comp.cancel()
- ch.AcceptMessage(&messages.DataMessage{
+ defer close(ch)
+ ch <- &messages.DataMessage{
Payloads: []messages.DataPayload{
{
TSID: idtool.ID(4000),
},
},
- })
- ch.AcceptMessage(&messages.MetadataMessage{
+ }
+ ch <- &messages.MetadataMessage{
TSID: idtool.ID(4000),
- })
+ }
- require.NotNil(t, comp.TSIDMetadata(4000))
+ md, _ := comp.TSIDMetadata(context.Background(), 4000)
+ require.NotNil(t, md)
- ch.AcceptMessage(&messages.InfoMessage{})
+ ch <- &messages.InfoMessage{}
- msg, _ := waitForDataMsg(t, comp)
- require.Equal(t, idtool.ID(4000), msg.(*messages.DataMessage).Payloads[0].TSID)
+ msg := waitForMsg(t, comp.Data(), comp)
+ require.Equal(t, idtool.ID(4000), msg.Payloads[0].TSID)
- ch.AcceptMessage(&messages.DataMessage{
+ ch <- &messages.DataMessage{
Payloads: []messages.DataPayload{
{
TSID: idtool.ID(4001),
},
},
- })
- msg, _ = waitForDataMsg(t, comp)
- require.Equal(t, idtool.ID(4001), msg.(*messages.DataMessage).Payloads[0].TSID)
+ }
+ msg = waitForMsg(t, comp.Data(), comp)
+ require.Equal(t, idtool.ID(4001), msg.Payloads[0].TSID)
+}
+
+func waitForMsg[T any](t *testing.T, ch <-chan *T, comp *Computation) *T {
+ t.Helper()
+ ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
+ defer cancel()
+ for {
+ select {
+ case m, ok := <-ch:
+ if !ok {
+ require.FailNow(t, "message channel closed unexpected")
+ }
+ return m
+ case <-ctx.Done():
+ require.FailNow(t, "message didn't arrive in timeout with error: %v", comp.Err())
+ }
+ }
}
func TestBuffersExpiryMessages(t *testing.T) {
- ch := newChannel(context.Background(), "ch1")
- comp := newComputation(context.Background(), ch, &Client{
+ t.Parallel()
+ ch := make(chan messages.Message)
+ comp := newComputation(ch, "ch1", &Client{
defaultMetadataTimeout: 1 * time.Second,
})
- defer comp.cancel()
- ch.AcceptMessage(&messages.DataMessage{
- Payloads: []messages.DataPayload{
- {
- TSID: idtool.ID(4000),
- },
- },
- })
- ch.AcceptMessage(&messages.MetadataMessage{
+ defer close(ch)
+ ch <- &messages.ExpiredTSIDMessage{
+ TSID: idtool.ID(4000).String(),
+ }
+ ch <- &messages.MetadataMessage{
TSID: idtool.ID(4000),
- })
+ }
- require.NotNil(t, comp.TSIDMetadata(4000))
+ md, _ := comp.TSIDMetadata(context.Background(), 4000)
+ require.NotNil(t, md)
- ch.AcceptMessage(&messages.InfoMessage{})
+ ch <- &messages.InfoMessage{}
- msg, _ := waitForDataMsg(t, comp)
- require.Equal(t, idtool.ID(4000), msg.(*messages.DataMessage).Payloads[0].TSID)
+ msg := waitForMsg(t, comp.Expirations(), comp)
+ require.Equal(t, idtool.ID(4000).String(), msg.TSID)
- ch.AcceptMessage(&messages.DataMessage{
- Payloads: []messages.DataPayload{
- {
- TSID: idtool.ID(4001),
- },
- },
+ ch <- &messages.ExpiredTSIDMessage{
+ TSID: idtool.ID(4001).String(),
+ }
+ msg = waitForMsg(t, comp.Expirations(), comp)
+ require.Equal(t, idtool.ID(4001).String(), msg.TSID)
+}
+
+func TestBuffersEventMessages(t *testing.T) {
+ t.Parallel()
+ ch := make(chan messages.Message)
+ comp := newComputation(ch, "ch1", &Client{
+ defaultMetadataTimeout: 1 * time.Second,
})
- msg, _ = waitForDataMsg(t, comp)
- require.Equal(t, idtool.ID(4001), msg.(*messages.DataMessage).Payloads[0].TSID)
+ defer close(ch)
+ ch <- &messages.EventMessage{}
+ ch <- &messages.MetadataMessage{
+ TSID: idtool.ID(4000),
+ }
+
+ md, _ := comp.TSIDMetadata(context.Background(), 4000)
+ require.NotNil(t, md)
+
+ ch <- &messages.InfoMessage{}
+
+ msg := waitForMsg(t, comp.Events(), comp)
+ require.NotNil(t, msg)
+
+ ch <- &messages.EventMessage{}
+ msg = waitForMsg(t, comp.Events(), comp)
+ require.NotNil(t, msg)
}
func mustParse(m messages.Message, err error) messages.Message {
@@ -110,11 +128,12 @@ func mustParse(m messages.Message, err error) messages.Message {
}
func TestResolutionMetadata(t *testing.T) {
- ch := newChannel(context.Background(), "ch1")
- comp := newComputation(context.Background(), ch, &Client{
+ t.Parallel()
+ ch := make(chan messages.Message)
+ comp := newComputation(ch, "ch1", &Client{
defaultMetadataTimeout: 1 * time.Second,
})
- defer comp.cancel()
+ defer close(ch)
wg := sync.WaitGroup{}
@@ -122,12 +141,13 @@ func TestResolutionMetadata(t *testing.T) {
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
- require.Equal(t, 5*time.Second, comp.Resolution())
- wg.Done()
+ defer wg.Done()
+ resolution, _ := comp.Resolution(context.Background())
+ require.Equal(t, 5*time.Second, resolution)
}()
}
- ch.AcceptMessage(mustParse(messages.ParseMessage([]byte(`{
+ ch <- mustParse(messages.ParseMessage([]byte(`{
"type": "message",
"message": {
"messageCode": "JOB_RUNNING_RESOLUTION",
@@ -135,18 +155,19 @@ func TestResolutionMetadata(t *testing.T) {
"resolutionMs": 5000
}
}
- }`), true)))
+ }`), true))
wg.Wait()
}
func TestMaxDelayMetadata(t *testing.T) {
- ch := newChannel(context.Background(), "ch1")
- comp := newComputation(context.Background(), ch, &Client{
+ t.Parallel()
+ ch := make(chan messages.Message)
+ comp := newComputation(ch, "ch1", &Client{
defaultMetadataTimeout: 1 * time.Second,
})
- defer comp.cancel()
- ch.AcceptMessage(mustParse(messages.ParseMessage([]byte(`{
+ defer close(ch)
+ ch <- mustParse(messages.ParseMessage([]byte(`{
"type": "message",
"message": {
"messageCode": "JOB_INITIAL_MAX_DELAY",
@@ -154,18 +175,20 @@ func TestMaxDelayMetadata(t *testing.T) {
"maxDelayMs": 1000
}
}
- }`), true)))
+ }`), true))
- require.Equal(t, 1*time.Second, comp.MaxDelay())
+ maxDelay, _ := comp.MaxDelay(context.Background())
+ require.Equal(t, 1*time.Second, maxDelay)
}
func TestLagMetadata(t *testing.T) {
- ch := newChannel(context.Background(), "ch1")
- comp := newComputation(context.Background(), ch, &Client{
+ t.Parallel()
+ ch := make(chan messages.Message)
+ comp := newComputation(ch, "ch1", &Client{
defaultMetadataTimeout: 1 * time.Second,
})
- defer comp.cancel()
- ch.AcceptMessage(mustParse(messages.ParseMessage([]byte(`{
+ defer close(ch)
+ ch <- mustParse(messages.ParseMessage([]byte(`{
"type": "message",
"message": {
"messageCode": "JOB_DETECTED_LAG",
@@ -173,18 +196,20 @@ func TestLagMetadata(t *testing.T) {
"lagMs": 3500
}
}
- }`), true)))
+ }`), true))
- require.Equal(t, 3500*time.Millisecond, comp.Lag())
+ lag, _ := comp.Lag(context.Background())
+ require.Equal(t, 3500*time.Millisecond, lag)
}
func TestFindLimitedResultSetMetadata(t *testing.T) {
- ch := newChannel(context.Background(), "ch1")
- comp := newComputation(context.Background(), ch, &Client{
+ t.Parallel()
+ ch := make(chan messages.Message)
+ comp := newComputation(ch, "ch1", &Client{
defaultMetadataTimeout: 1 * time.Second,
})
- defer comp.cancel()
- ch.AcceptMessage(mustParse(messages.ParseMessage([]byte(`{
+ defer close(ch)
+ ch <- mustParse(messages.ParseMessage([]byte(`{
"type": "message",
"message": {
"messageCode": "FIND_LIMITED_RESULT_SET",
@@ -193,19 +218,23 @@ func TestFindLimitedResultSetMetadata(t *testing.T) {
"limitSize": 50000
}
}
- }`), true)))
+ }`), true))
- require.Equal(t, 123456789, comp.MatchedSize())
- require.Equal(t, 50000, comp.LimitSize())
+ matchedSize, _ := comp.MatchedSize(context.Background())
+ require.Equal(t, 123456789, matchedSize)
+
+ limitSize, _ := comp.LimitSize(context.Background())
+ require.Equal(t, 50000, limitSize)
}
func TestMatchedNoTimeseriesQueryMetaData(t *testing.T) {
- ch := newChannel(context.Background(), "ch1")
- comp := newComputation(context.Background(), ch, &Client{
+ t.Parallel()
+ ch := make(chan messages.Message)
+ comp := newComputation(ch, "ch1", &Client{
defaultMetadataTimeout: 1 * time.Second,
})
- defer comp.cancel()
- ch.AcceptMessage(mustParse(messages.ParseMessage([]byte(`{
+ defer close(ch)
+ ch <- mustParse(messages.ParseMessage([]byte(`{
"type": "message",
"message": {
"messageCode": "FIND_MATCHED_NO_TIMESERIES",
@@ -213,18 +242,20 @@ func TestMatchedNoTimeseriesQueryMetaData(t *testing.T) {
"query": "abc"
}
}
- }`), true)))
+ }`), true))
- require.Equal(t, "abc", comp.MatchedNoTimeseriesQuery())
+ noMatched, _ := comp.MatchedNoTimeseriesQuery(context.Background())
+ require.Equal(t, "abc", noMatched)
}
func TestGroupByMissingPropertyMetaData(t *testing.T) {
- ch := newChannel(context.Background(), "ch1")
- comp := newComputation(context.Background(), ch, &Client{
+ t.Parallel()
+ ch := make(chan messages.Message)
+ comp := newComputation(ch, "ch1", &Client{
defaultMetadataTimeout: 1 * time.Second,
})
- defer comp.cancel()
- ch.AcceptMessage(mustParse(messages.ParseMessage([]byte(`{
+ defer close(ch)
+ ch <- mustParse(messages.ParseMessage([]byte(`{
"type": "message",
"message": {
"messageCode": "GROUPBY_MISSING_PROPERTY",
@@ -232,96 +263,119 @@ func TestGroupByMissingPropertyMetaData(t *testing.T) {
"propertyNames": ["x", "y", "z"]
}
}
- }`), true)))
+ }`), true))
- require.Equal(t, []string{"x", "y", "z"}, comp.GroupByMissingProperties())
+ missingProps, _ := comp.GroupByMissingProperties(context.Background())
+ require.Equal(t, []string{"x", "y", "z"}, missingProps)
}
func TestHandle(t *testing.T) {
- ch := newChannel(context.Background(), "ch1")
- comp := newComputation(context.Background(), ch, &Client{
+ t.Parallel()
+ ch := make(chan messages.Message)
+ comp := newComputation(ch, "ch1", &Client{
defaultMetadataTimeout: 1 * time.Second,
})
- defer comp.cancel()
- ch.AcceptMessage(mustParse(messages.ParseMessage([]byte(`{
+ defer close(ch)
+ ch <- mustParse(messages.ParseMessage([]byte(`{
"type": "control-message",
"event": "JOB_START",
"handle": "AAAABBBB"
- }`), true)))
+ }`), true))
- require.Equal(t, "AAAABBBB", comp.Handle())
+ handle, _ := comp.Handle(context.Background())
+ require.Equal(t, "AAAABBBB", handle)
}
func TestComputationError(t *testing.T) {
- ch := newChannel(context.Background(), "ch1")
- comp := newComputation(context.Background(), ch, &Client{
+ t.Parallel()
+ ch := make(chan messages.Message)
+ comp := newComputation(ch, "ch1", &Client{
defaultMetadataTimeout: 1 * time.Second,
})
- defer comp.cancel()
- ch.AcceptMessage(mustParse(messages.ParseMessage([]byte(`{
+ defer close(ch)
+ ch <- mustParse(messages.ParseMessage([]byte(`{
"type": "error",
"error": 400,
"errorType": "ANALYTICS_PROGRAM_NAME_ERROR",
"message": "We hit some error"
- }`), true)))
+ }`), true))
- _, err := waitForDataMsg(t, comp)
- if err == nil {
- t.Fatal("Expected computation error")
+ err := waitForComputationError(t, comp)
+ var ce *ComputationError
+ if !errors.As(err, &ce) {
+ t.FailNow()
}
- require.Equal(t, 400, err.(*ComputationError).Code)
- require.Equal(t, "ANALYTICS_PROGRAM_NAME_ERROR", err.(*ComputationError).ErrorType)
- require.Equal(t, "We hit some error", err.(*ComputationError).Message)
+ require.Equal(t, 400, ce.Code)
+ require.Equal(t, "ANALYTICS_PROGRAM_NAME_ERROR", ce.ErrorType)
+ require.Equal(t, "We hit some error", ce.Message)
}
func TestComputationErrorWithNullMessage(t *testing.T) {
- ch := newChannel(context.Background(), "ch1")
- comp := newComputation(context.Background(), ch, &Client{
+ t.Parallel()
+ ch := make(chan messages.Message)
+ comp := newComputation(ch, "ch1", &Client{
defaultMetadataTimeout: 1 * time.Second,
})
- defer comp.cancel()
- ch.AcceptMessage(mustParse(messages.ParseMessage([]byte(`{
+ defer close(ch)
+ ch <- mustParse(messages.ParseMessage([]byte(`{
"type": "error",
"error": 400,
"errorType": "ANALYTICS_INTERNAL_ERROR",
"message": null
- }`), true)))
+ }`), true))
- _, err := waitForDataMsg(t, comp)
- if err == nil {
- t.Fatal("Expected computation error")
+ err := waitForComputationError(t, comp)
+ var ce *ComputationError
+ if !errors.As(err, &ce) {
+ t.FailNow()
}
- require.Equal(t, 400, err.(*ComputationError).Code)
- require.Equal(t, "ANALYTICS_INTERNAL_ERROR", err.(*ComputationError).ErrorType)
- require.Equal(t, "", err.(*ComputationError).Message)
+ require.Equal(t, 400, ce.Code)
+ require.Equal(t, "ANALYTICS_INTERNAL_ERROR", ce.ErrorType)
+ require.Equal(t, "", ce.Message)
+}
+
+func waitForComputationError(t *testing.T, comp *Computation) error {
+ t.Helper()
+ start := time.Now()
+ var err error
+ for time.Since(start) < 3*time.Second {
+ err = comp.Err()
+ if err != nil {
+ return err
+ }
+ time.Sleep(50 * time.Millisecond)
+ }
+ require.FailNow(t, "computation did not fail")
+ return nil
}
func TestComputationFinish(t *testing.T) {
- ch := newChannel(context.Background(), "ch1")
- comp := newComputation(context.Background(), ch, &Client{
+ t.Parallel()
+ ch := make(chan messages.Message)
+ comp := newComputation(ch, "ch1", &Client{
defaultMetadataTimeout: 1 * time.Second,
})
- defer comp.cancel()
+ defer close(ch)
go func() {
- ch.AcceptMessage(mustParse(messages.ParseMessage([]byte(`{
+ ch <- mustParse(messages.ParseMessage([]byte(`{
"type": "control-message",
"event": "JOB_START",
"handle": "AAAABBBB"
- }`), true)))
+ }`), true))
- ch.AcceptMessage(&messages.MetadataMessage{
+ ch <- &messages.MetadataMessage{
TSID: idtool.ID(4000),
- })
+ }
- ch.AcceptMessage(&messages.DataMessage{
+ ch <- &messages.DataMessage{
Payloads: []messages.DataPayload{
{
TSID: idtool.ID(4000),
},
},
- })
+ }
- ch.AcceptMessage(&messages.EndOfChannelControlMessage{})
+ ch <- &messages.EndOfChannelControlMessage{}
}()
for msg := range comp.Data() {
diff --git a/signalflow/conn.go b/signalflow/conn.go
index 094eacf..6da947a 100644
--- a/signalflow/conn.go
+++ b/signalflow/conn.go
@@ -3,32 +3,28 @@ package signalflow
import (
"context"
"fmt"
- "log"
"net/url"
"path"
- "sync"
"time"
"github.com/gorilla/websocket"
)
// How long to wait between connections in case of a bad connection.
-var ReconnectDelay = 5 * time.Second
+var reconnectDelay = 5 * time.Second
type wsConn struct {
- sync.Mutex
- ctx context.Context
- streamURL *url.URL
+ StreamURL *url.URL
- outgoingTextMsgs chan *outgoingMessage
- incomingTextMsgs chan []byte
- incomingBinaryMsgs chan []byte
- readErrCh chan error
- readCh chan struct{}
- connectedCh chan struct{}
+ OutgoingTextMsgs chan *outgoingMessage
+ IncomingTextMsgs chan []byte
+ IncomingBinaryMsgs chan []byte
+ ConnectedCh chan struct{}
+ ConnectTimeout time.Duration
ReadTimeout time.Duration
WriteTimeout time.Duration
+ OnError OnErrorFunc
PostDisconnectCallback func()
PostConnectMessage func() []byte
}
@@ -38,110 +34,125 @@ type outgoingMessage struct {
resultCh chan error
}
-func newWebsocketConn(ctx context.Context, streamURL *url.URL) *wsConn {
- ws := &wsConn{
- ctx: ctx,
- streamURL: streamURL,
- incomingTextMsgs: make(chan []byte),
- incomingBinaryMsgs: make(chan []byte),
- outgoingTextMsgs: make(chan *outgoingMessage),
- readErrCh: make(chan error),
- readCh: make(chan struct{}),
- connectedCh: make(chan struct{}),
- ReadTimeout: 1 * time.Minute,
- WriteTimeout: 20 * time.Second,
- }
- return ws
-}
+// Run keeps the connection alive and puts all incoming messages into a channel
+// as needed.
+func (c *wsConn) Run(ctx context.Context) {
+ var conn *websocket.Conn
+ defer func() {
+ if conn != nil {
+ conn.Close()
+ }
+ }()
-func (c *wsConn) IncomingTextMessages() <-chan []byte {
- return c.incomingTextMsgs
-}
+ for {
+ if conn != nil {
+ conn.Close()
+ time.Sleep(reconnectDelay)
+ }
+ // This will get run on before the first connection as well.
+ if c.PostDisconnectCallback != nil {
+ c.PostDisconnectCallback()
+ }
-func (c *wsConn) IncomingBinaryMessages() <-chan []byte {
- return c.incomingBinaryMsgs
-}
+ if ctx.Err() != nil {
+ return
+ }
+
+ dialCtx, cancel := context.WithTimeout(ctx, c.ConnectTimeout)
+ var err error
+ conn, err = c.connect(dialCtx)
+ cancel()
+ if err != nil {
+ c.sendErrIfWanted(fmt.Errorf("Error connecting to SignalFlow websocket: %w", err))
+ continue
+ }
-func (c *wsConn) OutgoingTextMessages() chan<- *outgoingMessage {
- return c.outgoingTextMsgs
+ err = c.postConnect(conn)
+ if err != nil {
+ c.sendErrIfWanted(fmt.Errorf("Error setting up SignalFlow websocket: %w", err))
+ continue
+ }
+
+ err = c.readAndWriteMessages(conn)
+ if err == nil {
+ return
+ }
+ c.sendErrIfWanted(fmt.Errorf("Error in SignalFlow websocket: %w", err))
+ }
}
-func (c *wsConn) ConnectedSignal() <-chan struct{} {
- return c.connectedCh
+type messageWithType struct {
+ bytes []byte
+ msgType int
}
-// Run keeps the connection alive and puts all incoming messages into a channel
-// as needed.
-func (c *wsConn) Run() {
- var conn *websocket.Conn
+func (c *wsConn) readAndWriteMessages(conn *websocket.Conn) error {
+ readMessageCh := make(chan messageWithType)
+ readErrCh := make(chan error)
- for {
- if conn == nil {
- // This will get run on before the first connection as well.
- if c.PostDisconnectCallback != nil {
- c.PostDisconnectCallback()
- }
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
- if c.ctx.Err() == context.Canceled {
- log.Printf("Context cancelled, stop reconnecting.")
- return
- }
-
- var err error
- conn, err = c.connect()
+ go func() {
+ for {
+ bytes, typ, err := readNextMessage(conn, c.ReadTimeout)
if err != nil {
- log.Printf("Error connecting to SignalFlow websocket: %v", err)
- time.Sleep(ReconnectDelay)
- continue
+ select {
+ case readErrCh <- err:
+ case <-ctx.Done():
+ }
+ return
}
-
- err = c.postConnect(conn)
- if err != nil {
- log.Printf("Error setting up SignalFlow websocket: %v", err)
- conn.Close()
- conn = nil
- time.Sleep(ReconnectDelay)
- continue
+ readMessageCh <- messageWithType{
+ bytes: bytes,
+ msgType: typ,
}
-
- go c.readNextMessage(conn)
}
+ }()
+ for {
select {
- case <-c.ctx.Done():
- conn.Close()
- return
- case <-c.readCh:
- go c.readNextMessage(conn)
- case err := <-c.readErrCh:
- log.Printf("Error reading from SignalFlow websocket: %v", err)
- conn.Close()
- conn = nil
- time.Sleep(ReconnectDelay)
- case msg := <-c.outgoingTextMsgs:
+ case msg, ok := <-readMessageCh:
+ if !ok {
+ return nil
+ }
+ if msg.msgType == websocket.TextMessage {
+ c.IncomingTextMsgs <- msg.bytes
+ } else {
+ c.IncomingBinaryMsgs <- msg.bytes
+ }
+ case err := <-readErrCh:
+ return err
+ case msg, ok := <-c.OutgoingTextMsgs:
+ if !ok {
+ return nil
+ }
err := c.writeMessage(conn, msg.bytes)
msg.resultCh <- err
if err != nil {
- // Force the connection closed if it isn't already and wait for
- // the read goroutine to finish.
- conn.Close()
- select {
- case <-c.readErrCh:
- case <-c.readCh:
- }
- conn = nil
- time.Sleep(ReconnectDelay)
+ return err
}
}
}
}
-func (c *wsConn) connect() (*websocket.Conn, error) {
- connectURL := *c.streamURL
- connectURL.Path = path.Join(c.streamURL.Path, "connect")
- conn, _, err := websocket.DefaultDialer.DialContext(c.ctx, connectURL.String(), nil)
+func (c *wsConn) sendErrIfWanted(err error) {
+ if c.OnError != nil {
+ c.OnError(err)
+ }
+}
+
+func (c *wsConn) Close() {
+ close(c.IncomingTextMsgs)
+ close(c.IncomingBinaryMsgs)
+}
+
+func (c *wsConn) connect(ctx context.Context) (*websocket.Conn, error) {
+ connectURL := *c.StreamURL
+ connectURL.Path = path.Join(c.StreamURL.Path, "connect")
+ conn, _, err := websocket.DefaultDialer.DialContext(ctx, connectURL.String(), nil)
if err != nil {
- return nil, fmt.Errorf("could not connect Signalflow websocket: %v", err)
+ return nil, fmt.Errorf("could not connect Signalflow websocket: %w", err)
}
return conn, nil
}
@@ -156,35 +167,22 @@ func (c *wsConn) postConnect(conn *websocket.Conn) error {
return nil
}
-func (c *wsConn) readNextMessage(conn *websocket.Conn) {
- if err := conn.SetReadDeadline(time.Now().Add(c.ReadTimeout)); err != nil {
- select {
- case c.readErrCh <- fmt.Errorf("could not set read timeout in SignalFlow client: %v", err):
- case <-c.ctx.Done():
- }
- return
+func readNextMessage(conn *websocket.Conn, timeout time.Duration) (data []byte, msgType int, err error) {
+ if err := conn.SetReadDeadline(time.Now().Add(timeout)); err != nil {
+ return nil, 0, fmt.Errorf("could not set read timeout in SignalFlow client: %w", err)
}
typ, bytes, err := conn.ReadMessage()
if err != nil {
- select {
- case c.readErrCh <- err:
- case <-c.ctx.Done():
- }
- return
- }
- if typ == websocket.TextMessage {
- c.incomingTextMsgs <- bytes
- } else {
- c.incomingBinaryMsgs <- bytes
+ return nil, 0, err
}
- c.readCh <- struct{}{}
+ return bytes, typ, nil
}
func (c *wsConn) writeMessage(conn *websocket.Conn, msgBytes []byte) error {
err := conn.SetWriteDeadline(time.Now().Add(c.WriteTimeout))
if err != nil {
- return fmt.Errorf("could not set write timeout for SignalFlow request: %v", err)
+ return fmt.Errorf("could not set write timeout for SignalFlow request: %w", err)
}
err = conn.WriteMessage(websocket.TextMessage, msgBytes)
diff --git a/signalflow/doc.go b/signalflow/doc.go
index d121a56..ac147e4 100644
--- a/signalflow/doc.go
+++ b/signalflow/doc.go
@@ -1,9 +1,11 @@
-// Package signalflow contains a SignalFx SignalFlow client, which can be used
-// to execute analytics jobs against the SignalFx backend.
+// Package signalflow contains a SignalFx SignalFlow client, which can be used to execute analytics
+// jobs against the SignalFx backend.
//
-// The client currently only supports the execute request. Not all SignalFlow
-// messages are handled at this time, and some will be silently dropped.
+// Not all SignalFlow messages are handled at this time, and some will be silently dropped. All of
+// the most important and useful ones are supported though.
//
-// The client will automatically attempt to reconnect to the backend if the
-// connection is broken. There is a 5 second delay between retries.
+// The client will automatically attempt to reconnect to the backend if the connection is broken
+// after a short delay.
+//
+// SignalFlow is documented at https://dev.splunk.com/observability/docs/signalflow/messages.
package signalflow
diff --git a/signalflow/example/main.go b/signalflow/example/main.go
index cdf97ea..5757992 100644
--- a/signalflow/example/main.go
+++ b/signalflow/example/main.go
@@ -2,31 +2,47 @@
package main
import (
- "fmt"
+ "context"
+ "flag"
"log"
"os"
+ "time"
- "github.com/signalfx/signalfx-go/signalflow"
+ "github.com/signalfx/signalfx-go/signalflow/v2"
)
func main() {
- var streamURL = os.Getenv("SIGNALFX_STREAM_URL")
- var accessToken = os.Getenv("SIGNALFX_ACCESS_TOKEN")
+ var (
+ realm string
+ accessToken string
+ program string
+ duration time.Duration
+ )
+
+ flag.StringVar(&realm, "realm", "", "SignalFx Realm")
+ flag.StringVar(&accessToken, "access-token", "", "SignalFx Org Access Token")
+ flag.StringVar(&program, "program", "data('cpu.utilization').count().publish()", "The SignalFlow program to execute")
+ flag.DurationVar(&duration, "duration", 30*time.Second, "How long to run the job before sending Stop message")
+ flag.Parse()
+
+ if realm == "" || accessToken == "" {
+ flag.Usage()
+ os.Exit(1)
+ }
c, err := signalflow.NewClient(
- signalflow.StreamURL(streamURL),
- signalflow.AccessToken(accessToken))
+ signalflow.StreamURLForRealm(realm),
+ signalflow.AccessToken(accessToken),
+ signalflow.OnError(func(err error) {
+ log.Printf("Error in SignalFlow client: %v", err)
+ }))
if err != nil {
log.Printf("Error creating client: %v", err)
return
}
- program := os.Getenv("SIGNALFLOW_PROGRAM")
- if program == "" {
- program = "data('cpu.utilization').publish()"
- }
-
- comp, err := c.Execute(&signalflow.ExecuteRequest{
+ log.Printf("Executing program for %v: %s", duration, program)
+ comp, err := c.Execute(context.Background(), &signalflow.ExecuteRequest{
Program: program,
})
if err != nil {
@@ -34,13 +50,29 @@ func main() {
return
}
- fmt.Printf("Resolution: %v\n", comp.Resolution())
- fmt.Printf("Max Delay: %v\n", comp.MaxDelay())
- fmt.Printf("Detected Lag: %v\n", comp.Lag())
+ // If you want to limit how long to wait for the resolution metadata to come in you can use a
+ // timed context.
+ ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
+ resolution, err := comp.Resolution(ctx)
+ cancel()
+
+ maxDelay, _ := comp.MaxDelay(context.Background())
+ lag, _ := comp.Lag(context.Background())
+
+ log.Printf("Resolution: %v (err: %v)\n", resolution, err)
+ log.Printf("Max Delay: %v\n", maxDelay)
+ log.Printf("Detected Lag: %v\n", lag)
go func() {
for msg := range comp.Expirations() {
- fmt.Printf("Got expiration notice for TSID %s", msg.TSID)
+ log.Printf("Got expiration notice for TSID %s", msg.TSID)
+ }
+ }()
+
+ go func() {
+ time.Sleep(duration)
+ if err := comp.Stop(context.Background()); err != nil {
+ log.Printf("Failed to stop computation: %v", err)
}
}()
@@ -48,14 +80,20 @@ func main() {
// This will run as long as there is data, or until the websocket gets
// disconnected.
if len(msg.Payloads) == 0 {
- fmt.Printf("\rNo data available")
+ log.Printf("\rNo data available")
continue
}
for _, pl := range msg.Payloads {
- meta := comp.TSIDMetadata(pl.TSID)
- fmt.Printf("%s %v: %v\n", meta.OriginatingMetric, meta.CustomProperties, pl.Value())
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ meta, err := comp.TSIDMetadata(ctx, pl.TSID)
+ cancel()
+ if err != nil {
+ log.Printf("Failed to get metadata for tsid %s: %v", pl.TSID, err)
+ continue
+ }
+ log.Printf("%s (%s) %v %v: %v\n", meta.OriginatingMetric, meta.Metric, meta.CustomProperties, meta.InternalProperties, pl.Value())
}
- fmt.Println("")
+ log.Println("")
}
err = comp.Err()
diff --git a/signalflow/fake_backend.go b/signalflow/fake_backend.go
index 9dc9a3f..bec8a66 100644
--- a/signalflow/fake_backend.go
+++ b/signalflow/fake_backend.go
@@ -17,7 +17,7 @@ import (
"github.com/gorilla/websocket"
"github.com/signalfx/signalfx-go/idtool"
- "github.com/signalfx/signalfx-go/signalflow/messages"
+ "github.com/signalfx/signalfx-go/signalflow/v2/messages"
)
var upgrader = websocket.Upgrader{} // use default options
@@ -45,6 +45,7 @@ type FakeBackend struct {
programErrors map[string]string
runningJobsByProgram map[string]int
cancelFuncsByHandle map[string]context.CancelFunc
+ cancelFuncsByChannel map[string]context.CancelFunc
server *httptest.Server
handleIdx int
}
@@ -83,8 +84,10 @@ func (f *FakeBackend) ServeHTTP(w http.ResponseWriter, r *http.Request) {
for {
_, message, err := c.ReadMessage()
if err != nil {
- log.Println("read err:", err)
- break
+ if !errors.Is(err, net.ErrClosed) {
+ log.Println("read err:", err)
+ }
+ return
}
var in map[string]interface{}
@@ -114,9 +117,6 @@ func (f *FakeBackend) unregisterConn(conn *websocket.Conn) {
}
func (f *FakeBackend) handleMessage(ctx context.Context, message map[string]interface{}, textMsgs chan<- string, binMsgs chan<- []byte) error {
- f.Lock()
- defer f.Unlock()
-
typ, ok := message["type"].(string)
if !ok {
textMsgs <- `{"type": "error"}`
@@ -137,6 +137,10 @@ func (f *FakeBackend) handleMessage(ctx context.Context, message map[string]inte
if cancel := f.cancelFuncsByHandle[message["handle"].(string)]; cancel != nil {
cancel()
}
+ case "detach":
+ if cancel := f.cancelFuncsByChannel[message["channel"].(string)]; cancel != nil {
+ cancel()
+ }
case "execute":
if !f.authenticated {
return errors.New("not authenticated")
@@ -155,6 +159,7 @@ func (f *FakeBackend) handleMessage(ctx context.Context, message map[string]inte
execCtx, cancel := context.WithCancel(ctx)
f.cancelFuncsByHandle[handle] = cancel
+ f.cancelFuncsByChannel[ch] = cancel
log.Printf("Executing SignalFlow program %s with tsids %v and handle %s", program, programTSIDs, handle)
f.runningJobsByProgram[program]++
@@ -209,6 +214,8 @@ func (f *FakeBackend) handleMessage(ctx context.Context, message map[string]inte
}
}
+ log.Print("done sending metadata messages")
+
// Send data periodically until the connection is closed.
iterations := 0
go func() {
@@ -216,6 +223,7 @@ func (f *FakeBackend) handleMessage(ctx context.Context, message map[string]inte
for {
select {
case <-execCtx.Done():
+ log.Printf("sending done")
f.Lock()
f.runningJobsByProgram[program]--
f.Unlock()
@@ -228,16 +236,18 @@ func (f *FakeBackend) handleMessage(ctx context.Context, message map[string]inte
valsWithTSID = append(valsWithTSID, tsidVal{TSID: tsid, Val: *data})
}
}
+ f.Unlock()
metricTime := startMs + uint64(iterations*resolutionMs)
if stopMs != 0 && metricTime > stopMs {
+ log.Printf("sending channel end")
// tell the client the computation is complete
textMsgs <- fmt.Sprintf(`{"type": "control-message", "channel": "%s", "event": "END_OF_CHANNEL", "handle": "%s"}`, ch, handle)
- } else {
- binMsgs <- makeDataMessage(ch, valsWithTSID, metricTime)
+ return
}
- f.Unlock()
+ log.Printf("sending data message")
+ binMsgs <- makeDataMessage(ch, valsWithTSID, metricTime)
+ log.Printf("done sending data message")
iterations++
-
}
}
}()
@@ -289,6 +299,7 @@ func (f *FakeBackend) Start() {
f.programErrors = map[string]string{}
f.runningJobsByProgram = map[string]int{}
f.cancelFuncsByHandle = map[string]context.CancelFunc{}
+ f.cancelFuncsByChannel = map[string]context.CancelFunc{}
f.conns = map[*websocket.Conn]bool{}
f.server = httptest.NewServer(f)
}
diff --git a/signalflow/fake_backend_test.go b/signalflow/fake_backend_test.go
index 69ca87b..6fb91cf 100644
--- a/signalflow/fake_backend_test.go
+++ b/signalflow/fake_backend_test.go
@@ -1,14 +1,14 @@
package signalflow
import (
- "fmt"
+ "context"
"math/rand"
"strconv"
"testing"
"time"
"github.com/signalfx/signalfx-go/idtool"
- "github.com/signalfx/signalfx-go/signalflow/messages"
+ "github.com/signalfx/signalfx-go/signalflow/v2/messages"
"github.com/stretchr/testify/assert"
)
@@ -25,6 +25,7 @@ type testCase struct {
}
func TestFakeBackend(t *testing.T) {
+ t.Parallel()
now := time.Now()
testCases := []testCase{
@@ -42,11 +43,11 @@ func TestFakeBackend(t *testing.T) {
},
{
timeSeriesProperties: []map[string]string{
- map[string]string{
+ {
"dim1": "val1",
"dim2": "val2",
},
- map[string]string{
+ {
"dim1": "val1",
},
},
@@ -64,46 +65,49 @@ func TestFakeBackend(t *testing.T) {
}
for _, testCase := range testCases {
- fakeBackend := NewRunningFakeBackend()
- tsids := []idtool.ID{}
- for _, _ = range testCase.timeSeriesProperties {
- tsids = append(tsids, idtool.ID(rand.Int63()))
- }
- for i, ts := range testCase.timeSeriesProperties {
- fakeBackend.AddTSIDMetadata(tsids[i], &messages.MetadataProperties{
- Metric: program,
- CustomProperties: ts,
- })
- fakeBackend.SetTSIDFloatData(tsids[i], 0)
- }
-
- fakeBackend.AddProgramTSIDs(program, tsids)
+ testCase := testCase
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+ fakeBackend := NewRunningFakeBackend()
+ tsids := []idtool.ID{}
+ for range testCase.timeSeriesProperties {
+ tsids = append(tsids, idtool.ID(rand.Int63()))
+ }
+ for i, ts := range testCase.timeSeriesProperties {
+ fakeBackend.AddTSIDMetadata(tsids[i], &messages.MetadataProperties{
+ Metric: program,
+ CustomProperties: ts,
+ })
+ fakeBackend.SetTSIDFloatData(tsids[i], 0)
+ }
- // connect N clients so we can prove the fakebackend is not killed by the first client disconnecting
- for i := 1; i <= testCase.numberOfSfxClients; i++ {
- sfxClient, _ := NewClient(StreamURL(fakeBackend.URL()), AccessToken(fakeBackend.AccessToken))
- processClient(t, sfxClient, testCase, i)
- }
+ fakeBackend.AddProgramTSIDs(program, tsids)
+ // connect N clients so we can prove the fakebackend is not killed by the first client disconnecting
+ for i := 1; i <= testCase.numberOfSfxClients; i++ {
+ sfxClient, _ := NewClient(StreamURL(fakeBackend.URL()), AccessToken(fakeBackend.AccessToken))
+ processClient(t, sfxClient, testCase, i)
+ }
+ })
}
-
}
func processClient(t *testing.T, sfxClient *Client, testCase testCase, connectionCount int) {
-
- data, _ := sfxClient.Execute(&ExecuteRequest{
+ t.Helper()
+ data, _ := sfxClient.Execute(context.Background(), &ExecuteRequest{
Program: program,
StartMs: testCase.startMs,
StopMs: testCase.stopMs,
ResolutionMs: testCase.resolutionSecs * 1000,
})
+
timestamps := []int64{}
datapointCount := 0
for msg := range data.Data() {
timestamps = append(timestamps, int64(msg.TimestampMillis))
datapoints := []map[string]string{}
for _, pl := range msg.Payloads {
- meta := data.TSIDMetadata(pl.TSID)
+ meta, _ := data.TSIDMetadata(context.Background(), pl.TSID)
dims := map[string]string{}
for k, v := range meta.CustomProperties {
dims[k] = v
@@ -113,15 +117,9 @@ func processClient(t *testing.T, sfxClient *Client, testCase testCase, connectio
}
// the datapoints should be always the same the fed in mts
assert.Equal(t, testCase.timeSeriesProperties, datapoints, testCase.name+": datapoints are wrong on connection "+strconv.Itoa(connectionCount))
-
- if data.IsFinished() {
- sfxClient.Close()
- break
- }
}
assert.Equal(t, testCase.expectedTimestamps, timestamps, testCase.name+": timestamps in metrics are wrong on connection "+strconv.Itoa(connectionCount))
// the number of datapoints should be the number of resolution windows multiplied by the number of MTS in each timestamp payload
assert.Equal(t, len(testCase.expectedTimestamps)*len(testCase.timeSeriesProperties), datapointCount, testCase.name+": amount of datapoints unexpected on connection "+strconv.Itoa(connectionCount))
- fmt.Println("finisged " + strconv.Itoa(connectionCount))
}
diff --git a/signalflow/go.mod b/signalflow/go.mod
new file mode 100644
index 0000000..1a3711f
--- /dev/null
+++ b/signalflow/go.mod
@@ -0,0 +1,15 @@
+module github.com/signalfx/signalfx-go/signalflow/v2
+
+go 1.19
+
+require (
+ github.com/gorilla/websocket v1.5.0
+ github.com/signalfx/signalfx-go v1.31.0
+ github.com/stretchr/testify v1.8.2
+)
+
+require (
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+)
diff --git a/signalflow/go.sum b/signalflow/go.sum
new file mode 100644
index 0000000..583f300
--- /dev/null
+++ b/signalflow/go.sum
@@ -0,0 +1,21 @@
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
+github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/signalfx/signalfx-go v1.31.0 h1:+uaneB7MLCiYXPgpAeNYTsRq/6QKDHPI9gyxDT627k4=
+github.com/signalfx/signalfx-go v1.31.0/go.mod h1:IpGZLPvCKNFyspAXoS480jB02mocTpo0KYd8jbl6/T8=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/signalflow/messages/binary.go b/signalflow/messages/binary.go
index 6c29704..cc20e1d 100644
--- a/signalflow/messages/binary.go
+++ b/signalflow/messages/binary.go
@@ -6,7 +6,7 @@ import (
"encoding/binary"
"errors"
"fmt"
- "io/ioutil"
+ "io"
"math"
"github.com/signalfx/signalfx-go/idtool"
@@ -143,7 +143,7 @@ func parseBinaryMessage(msg []byte) (Message, error) {
if err != nil {
return nil, err
}
- rest, err = ioutil.ReadAll(reader)
+ rest, err = io.ReadAll(reader)
if err != nil {
return nil, err
}
diff --git a/signalflow/messages/binary_test.go b/signalflow/messages/binary_test.go
index b079dcd..cc2fe2c 100644
--- a/signalflow/messages/binary_test.go
+++ b/signalflow/messages/binary_test.go
@@ -29,8 +29,14 @@ func TestDecodeBinaryMessage(t *testing.T) {
assert.Equal(t, dm.Type(), DataType)
assert.Equal(t, dm.Channel(), "channel-1")
+
assert.Equal(t, dm.TimestampMillis, uint64(1504064040000))
- assert.Equal(t, dm.Timestamp().Unix(), time.Date(2017, 8, 29, 23, 34, 00, 0, time.FixedZone("EDT", -4*60*60)).Unix())
+ assert.Equal(
+ t,
+ dm.Timestamp().Unix(),
+ time.Date(2017, 8, 29, 23, 34, 0, 0, time.FixedZone("EDT", -4*60*60)).Unix(),
+ )
+
assert.Len(t, dm.Payloads, 16)
assert.Equal(t, dm.Payloads[0].Value(), 691.1)
assert.Equal(t, dm.Payloads[0].TSID, idtool.ID(3079061720))
diff --git a/signalflow/messages/types.go b/signalflow/messages/types.go
index 6cc9561..00ccd01 100644
--- a/signalflow/messages/types.go
+++ b/signalflow/messages/types.go
@@ -66,8 +66,8 @@ type BaseJSONMessage struct {
rawData map[string]interface{}
}
-func (bjm *BaseJSONMessage) JSONBase() *BaseJSONMessage {
- return bjm
+func (j *BaseJSONMessage) JSONBase() *BaseJSONMessage {
+ return j
}
// The raw message deserialized from JSON. Only applicable for JSON
@@ -95,15 +95,15 @@ type BaseJSONChannelMessage struct {
}
func (j *BaseJSONChannelMessage) String() string {
- return fmt.Sprintf("%s", j.BaseJSONMessage.rawMessage)
+ return string(j.BaseJSONMessage.rawMessage)
}
type TimestampedMessage struct {
TimestampMillis uint64 `json:"timestampMs"`
}
-func (tsm *TimestampedMessage) Timestamp() time.Time {
- return time.Unix(0, int64(tsm.TimestampMillis*uint64(time.Millisecond)))
+func (m *TimestampedMessage) Timestamp() time.Time {
+ return time.Unix(0, int64(m.TimestampMillis*uint64(time.Millisecond)))
}
type AuthenticatedMessage struct {
@@ -118,7 +118,7 @@ func ParseMessage(msg []byte, isText bool) (Message, error) {
if isText {
var baseMessage BaseMessage
if err := json.Unmarshal(msg, &baseMessage); err != nil {
- return nil, fmt.Errorf("couldn't unmarshal JSON websocket message: %v", err)
+ return nil, fmt.Errorf("couldn't unmarshal JSON websocket message: %w", err)
}
return parseJSONMessage(&baseMessage, msg)
}
diff --git a/signalflow/messages/types_test.go b/signalflow/messages/types_test.go
index 379e1e5..229ee50 100644
--- a/signalflow/messages/types_test.go
+++ b/signalflow/messages/types_test.go
@@ -15,5 +15,4 @@ func TestParseMessage(t *testing.T) {
require.NoError(t, err)
require.IsType(t, &EndOfChannelControlMessage{}, msg)
})
-
}
diff --git a/signalflow/requests.go b/signalflow/requests.go
index 1be6fe1..57227a0 100644
--- a/signalflow/requests.go
+++ b/signalflow/requests.go
@@ -12,6 +12,7 @@ func (at AuthType) MarshalJSON() ([]byte, error) {
}
type AuthRequest struct {
+ // This should not be set manually.
Type AuthType `json:"type"`
// The Auth token for the org
Token string `json:"token"`
@@ -24,7 +25,11 @@ func (ExecuteType) MarshalJSON() ([]byte, error) {
return []byte(`"execute"`), nil
}
+// See
+// https://dev.splunk.com/observability/docs/signalflow/messages/websocket_request_messages#Execute-message-properties
+// for details on the fields.
type ExecuteRequest struct {
+ // This should not be set manually
Type ExecuteType `json:"type"`
Program string `json:"program"`
Channel string `json:"channel"`
@@ -66,6 +71,7 @@ func (DetachType) MarshalJSON() ([]byte, error) {
}
type DetachRequest struct {
+ // This should not be set manually
Type DetachType `json:"type"`
Channel string `json:"channel"`
Reason string `json:"reason"`
@@ -78,6 +84,7 @@ func (StopType) MarshalJSON() ([]byte, error) {
}
type StopRequest struct {
+ // This should not be set manually
Type StopType `json:"type"`
Handle string `json:"handle"`
Reason string `json:"reason"`
diff --git a/signalflow/requests_test.go b/signalflow/requests_test.go
index 5b670ab..00fd9f1 100644
--- a/signalflow/requests_test.go
+++ b/signalflow/requests_test.go
@@ -9,6 +9,7 @@ import (
)
func TestSerializeExecuteRequest(t *testing.T) {
+ t.Parallel()
er := ExecuteRequest{
Program: "data(cpu.utilization).publish()",
Start: time.Unix(5000, 0),
@@ -21,5 +22,4 @@ func TestSerializeExecuteRequest(t *testing.T) {
serialized, err := json.Marshal(er)
require.Nil(t, err)
require.Equal(t, `{"type":"execute","program":"data(cpu.utilization).publish()","channel":"","start":5000000,"stop":6000000,"resolution":5000,"maxDelay":3000,"immediate":false,"timezone":""}`, string(serialized))
-
}
diff --git a/testdata/fixtures/integration/create_aws_success.json b/testdata/fixtures/integration/create_aws_success.json
index 5ffd299..20482b9 100644
--- a/testdata/fixtures/integration/create_aws_success.json
+++ b/testdata/fixtures/integration/create_aws_success.json
@@ -32,7 +32,7 @@
"action": "Exclude",
"source": "string"
},
- "namespace": "AWS/ApiGateway"
+ "namespace": "AWS/SomeNewNamespace"
}
],
"pollRate": 600000,
@@ -41,7 +41,7 @@
],
"roleArn": "string",
"services": [
- "AWS/ApiGateway"
+ "AWS/AnotherNewNamespace"
],
"sfxAwsAccountArn": "arn:aws:iam::1234567890:root",
"token": "string",
diff --git a/testdata/fixtures/metric_ruleset/create_ruleset_success.json b/testdata/fixtures/metric_ruleset/create_ruleset_success.json
new file mode 100644
index 0000000..8716c94
--- /dev/null
+++ b/testdata/fixtures/metric_ruleset/create_ruleset_success.json
@@ -0,0 +1,33 @@
+{
+ "aggregationRules": [
+ {
+ "aggregator": {
+ "dimensions": [
+ "sfx_realm",
+ "sfx_service"
+ ],
+ "dropDimensions": false,
+ "outputName": "container_cpu_utilization.by.sfx_realm.sfx_service.agg",
+ "type": "rollup"
+ },
+ "enabled": true,
+ "matcher": {
+ "filters": [],
+ "type": "dimension"
+ },
+ "name": "TestRule"
+ }
+ ],
+ "created": 1674598662022,
+ "creator": "TestCreatorId",
+ "creatorName": "TestName",
+ "id": "TestId",
+ "lastUpdated": 1674598662022,
+ "lastUpdatedBy": "TestUpdatedId",
+ "lastUpdatedByName": "TestName",
+ "metricName": "container_cpu_utilization",
+ "routingRule": {
+ "destination": "RealTime"
+ },
+ "version": 1
+}
\ No newline at end of file
diff --git a/testdata/fixtures/metric_ruleset/generate_aggregation_metric_name_success.txt b/testdata/fixtures/metric_ruleset/generate_aggregation_metric_name_success.txt
new file mode 100644
index 0000000..e71a28f
--- /dev/null
+++ b/testdata/fixtures/metric_ruleset/generate_aggregation_metric_name_success.txt
@@ -0,0 +1 @@
+cpu.utilization.by.sfx_realm.agg
\ No newline at end of file
diff --git a/testdata/fixtures/metric_ruleset/get_ruleset_success.json b/testdata/fixtures/metric_ruleset/get_ruleset_success.json
new file mode 100644
index 0000000..d724603
--- /dev/null
+++ b/testdata/fixtures/metric_ruleset/get_ruleset_success.json
@@ -0,0 +1,38 @@
+{
+ "aggregationRules": [
+ {
+ "aggregator": {
+ "dimensions": [
+ "sfx_service"
+ ],
+ "dropDimensions": false,
+ "outputName": "memory_utilization.by.sfx_realm.agg",
+ "type": "rollup"
+ },
+ "enabled": true,
+ "matcher": {
+ "filters": [
+ {
+ "property": "sfx_realm",
+ "NOT": false,
+ "propertyValue": ["lab0"]
+ }
+ ],
+ "type": "dimension"
+ },
+ "name": "TestRule"
+ }
+ ],
+ "created": 1674598662022,
+ "creator": "TestCreatorId",
+ "creatorName": "TestName",
+ "id": "TestId_MemoryUtilization",
+ "lastUpdated": 1674598662022,
+ "lastUpdatedBy": "TestUpdatedId",
+ "lastUpdatedByName": "TestName",
+ "metricName": "memory.utilization",
+ "routingRule": {
+ "destination": "Drop"
+ },
+ "version": 1
+}
\ No newline at end of file
diff --git a/testdata/fixtures/metric_ruleset/update_ruleset_success.json b/testdata/fixtures/metric_ruleset/update_ruleset_success.json
new file mode 100644
index 0000000..c978540
--- /dev/null
+++ b/testdata/fixtures/metric_ruleset/update_ruleset_success.json
@@ -0,0 +1,33 @@
+{
+ "aggregationRules": [
+ {
+ "aggregator": {
+ "dimensions": [
+ "sfx_realm",
+ "sfx_service"
+ ],
+ "dropDimensions": false,
+ "outputName": "container_cpu_utilization.by.sfx_realm.sfx_service.agg",
+ "type": "rollup"
+ },
+ "enabled": false,
+ "matcher": {
+ "filters": [],
+ "type": "dimension"
+ },
+ "name": "UpdatedName"
+ }
+ ],
+ "created": 1674598662022,
+ "creator": "TestCreatorId",
+ "creatorName": "TestName",
+ "id": "TestId",
+ "lastUpdated": 1674598662022,
+ "lastUpdatedBy": "TestUpdatedId",
+ "lastUpdatedByName": "TestName",
+ "metricName": "container_cpu_utilization",
+ "routingRule": {
+ "destination": "Drop"
+ },
+ "version": 1
+}
\ No newline at end of file
diff --git a/testdata/fixtures/organization/get_success.json b/testdata/fixtures/organization/get_success.json
index 6ed99d8..6e71fb1 100644
--- a/testdata/fixtures/organization/get_success.json
+++ b/testdata/fixtures/organization/get_success.json
@@ -9,7 +9,7 @@
"accountType": "string",
"accountStatus": "string",
"accountKey": "string",
- "accountRenews": "string",
+ "accountRenews": true,
"accountValidUntil": 1626384630000,
"dpmLimit": 0
}
diff --git a/testdata/fixtures/organization/update_member_success.json b/testdata/fixtures/organization/update_member_success.json
new file mode 100644
index 0000000..b6e82c8
--- /dev/null
+++ b/testdata/fixtures/organization/update_member_success.json
@@ -0,0 +1,14 @@
+{
+ "creator": "string",
+ "lastUpdatedBy": "string",
+ "created": 1533676829319,
+ "lastUpdated": 1557696630000,
+ "id": "string",
+ "userId": "string",
+ "organizationId": "string",
+ "email": "string",
+ "fullName": "string",
+ "phone": "string",
+ "title": "string",
+ "admin": true
+ }
\ No newline at end of file