From f323ffc16d79a6abd74d63a05020dd433b0bd1b2 Mon Sep 17 00:00:00 2001 From: Paul Chaignon Date: Mon, 12 Aug 2024 10:49:38 +0200 Subject: [PATCH] kvstore: Remove Consul support Consul support has been deprecated in v1.12 with commit fb65f8c55b ("docs: Deprecate Consul support"). It's time to fully remove it. This commit deletes all Consul logic, replaces Consul with Etcd in tests where it still was the default, removes Consul-specific tests, and removes the dependency to hashicorp/consul. Signed-off-by: Paul Chaignon --- .github/workflows/conformance-runtime.yaml | 3 - Documentation/cheatsheet.rst | 4 +- Documentation/cmdref/kvstore.rst | 2 +- .../contributing/development/dev_setup.rst | 3 - .../contributing/testing/e2e_legacy.rst | 2 +- Documentation/operations/upgrade.rst | 1 + .../security/network/proxy/envoy.rst | 2 +- Makefile | 23 +- Makefile.defs | 2 - Vagrantfile | 1 - contrib/systemd/cilium | 10 +- contrib/systemd/cilium-consul.service | 21 - contrib/systemd/cilium.service | 2 +- contrib/systemd/cilium.service-with-docker | 2 +- contrib/vagrant/start.sh | 12 +- daemon/cmd/daemon_test.go | 14 - daemon/cmd/endpoint_test.go | 25 - daemon/cmd/policy_test.go | 40 - go.mod | 10 - go.sum | 92 - pkg/command/map_string_test.go | 2 +- pkg/defaults/defaults.go | 2 +- pkg/identity/cache/allocation_test.go | 60 +- pkg/kvstore/allocator/allocator_test.go | 125 +- pkg/kvstore/allocator/doublewrite/backend.go | 1 - pkg/kvstore/base_test.go | 75 +- pkg/kvstore/config.go | 7 - pkg/kvstore/consul.go | 701 ------- pkg/kvstore/consul_test.go | 79 - pkg/kvstore/etcd_lease_test.go | 6 + pkg/kvstore/etcd_test.go | 4 +- pkg/kvstore/logfields.go | 2 +- pkg/kvstore/store/store_test.go | 40 +- test/consul/ca-config.json | 37 - test/consul/ca-csr.json | 16 - test/consul/cilium-consul.yaml | 4 - test/consul/consul-client-ca.crt | 23 - test/consul/consul-client.crt | 24 - test/consul/consul-client.json | 17 - test/consul/consul-client.key | 27 - test/consul/consul-config.json | 10 - test/consul/gen-cert.sh | 60 - test/consul/server-ca.crt | 23 - test/consul/server.crt | 24 - test/consul/server.json | 19 - test/consul/server.key | 27 - test/envoy/helpers.bash | 7 - test/helpers/cilium.go | 3 +- test/provision/docker-run-cilium.sh | 4 +- test/runtime/chaos.go | 2 - test/runtime/kvstore.go | 102 - tools/licensecheck/allowed.go | 1 - vendor/github.com/armon/go-metrics/.gitignore | 26 - .../github.com/armon/go-metrics/.travis.yml | 13 - vendor/github.com/armon/go-metrics/LICENSE | 20 - vendor/github.com/armon/go-metrics/README.md | 91 - .../github.com/armon/go-metrics/const_unix.go | 12 - .../armon/go-metrics/const_windows.go | 13 - vendor/github.com/armon/go-metrics/inmem.go | 339 ---- .../armon/go-metrics/inmem_endpoint.go | 162 -- .../armon/go-metrics/inmem_signal.go | 117 -- vendor/github.com/armon/go-metrics/metrics.go | 299 --- vendor/github.com/armon/go-metrics/sink.go | 132 -- vendor/github.com/armon/go-metrics/start.go | 158 -- vendor/github.com/armon/go-metrics/statsd.go | 184 -- .../github.com/armon/go-metrics/statsite.go | 172 -- .../hashicorp/consul/api/.copywrite.hcl | 8 - .../github.com/hashicorp/consul/api/LICENSE | 365 ---- .../github.com/hashicorp/consul/api/README.md | 77 - vendor/github.com/hashicorp/consul/api/acl.go | 1744 ----------------- .../github.com/hashicorp/consul/api/agent.go | 1446 -------------- vendor/github.com/hashicorp/consul/api/api.go | 1314 ------------- .../hashicorp/consul/api/catalog.go | 377 ---- .../hashicorp/consul/api/config_entry.go | 691 ------- .../consul/api/config_entry_discoverychain.go | 385 ---- .../consul/api/config_entry_exports.go | 84 - .../config_entry_file_system_certificate.go | 44 - .../consul/api/config_entry_gateways.go | 347 ---- .../api/config_entry_inline_certificate.go | 46 - .../consul/api/config_entry_intentions.go | 100 - .../consul/api/config_entry_jwt_provider.go | 310 --- .../hashicorp/consul/api/config_entry_mesh.go | 90 - .../consul/api/config_entry_rate_limit_ip.go | 91 - .../consul/api/config_entry_routes.go | 281 --- .../consul/api/config_entry_sameness_group.go | 29 - .../consul/api/config_entry_status.go | 358 ---- .../hashicorp/consul/api/connect.go | 18 - .../hashicorp/consul/api/connect_ca.go | 201 -- .../hashicorp/consul/api/connect_intention.go | 461 ----- .../hashicorp/consul/api/coordinate.go | 122 -- .../github.com/hashicorp/consul/api/debug.go | 141 -- .../hashicorp/consul/api/discovery_chain.go | 283 --- .../github.com/hashicorp/consul/api/event.go | 114 -- .../hashicorp/consul/api/exported_services.go | 49 - .../github.com/hashicorp/consul/api/health.go | 398 ---- .../hashicorp/consul/api/internal.go | 67 - vendor/github.com/hashicorp/consul/api/kv.go | 307 --- .../github.com/hashicorp/consul/api/lock.go | 411 ---- .../hashicorp/consul/api/namespace.go | 227 --- .../hashicorp/consul/api/operator.go | 14 - .../hashicorp/consul/api/operator_area.go | 209 -- .../hashicorp/consul/api/operator_audit.go | 40 - .../consul/api/operator_autopilot.go | 404 ---- .../hashicorp/consul/api/operator_keyring.go | 110 -- .../hashicorp/consul/api/operator_license.go | 134 -- .../hashicorp/consul/api/operator_raft.go | 132 -- .../hashicorp/consul/api/operator_segment.go | 14 - .../hashicorp/consul/api/operator_usage.go | 57 - .../hashicorp/consul/api/partition.go | 170 -- .../hashicorp/consul/api/peering.go | 295 --- .../hashicorp/consul/api/prepared_query.go | 269 --- vendor/github.com/hashicorp/consul/api/raw.go | 32 - .../hashicorp/consul/api/semaphore.go | 533 ----- .../hashicorp/consul/api/session.go | 246 --- .../hashicorp/consul/api/snapshot.go | 57 - .../github.com/hashicorp/consul/api/status.go | 70 - vendor/github.com/hashicorp/consul/api/txn.go | 249 --- .../github.com/hashicorp/go-cleanhttp/LICENSE | 363 ---- .../hashicorp/go-cleanhttp/README.md | 30 - .../hashicorp/go-cleanhttp/cleanhttp.go | 58 - .../github.com/hashicorp/go-cleanhttp/doc.go | 20 - .../hashicorp/go-cleanhttp/handlers.go | 48 - .../hashicorp/go-immutable-radix/.gitignore | 24 - .../hashicorp/go-immutable-radix/CHANGELOG.md | 23 - .../hashicorp/go-immutable-radix/LICENSE | 363 ---- .../hashicorp/go-immutable-radix/README.md | 66 - .../hashicorp/go-immutable-radix/edges.go | 21 - .../hashicorp/go-immutable-radix/iradix.go | 676 ------- .../hashicorp/go-immutable-radix/iter.go | 205 -- .../hashicorp/go-immutable-radix/node.go | 334 ---- .../hashicorp/go-immutable-radix/raw_iter.go | 78 - .../go-immutable-radix/reverse_iter.go | 239 --- .../hashicorp/go-rootcerts/.travis.yml | 12 - .../github.com/hashicorp/go-rootcerts/LICENSE | 363 ---- .../hashicorp/go-rootcerts/Makefile | 8 - .../hashicorp/go-rootcerts/README.md | 44 - .../github.com/hashicorp/go-rootcerts/doc.go | 9 - .../hashicorp/go-rootcerts/rootcerts.go | 123 -- .../hashicorp/go-rootcerts/rootcerts_base.go | 12 - .../go-rootcerts/rootcerts_darwin.go | 48 - .../github.com/hashicorp/golang-lru/LICENSE | 362 ---- .../hashicorp/golang-lru/simplelru/lru.go | 177 -- .../golang-lru/simplelru/lru_interface.go | 39 - vendor/github.com/hashicorp/serf/LICENSE | 354 ---- .../hashicorp/serf/coordinate/client.go | 243 --- .../hashicorp/serf/coordinate/config.go | 77 - .../hashicorp/serf/coordinate/coordinate.go | 203 -- .../hashicorp/serf/coordinate/phantom.go | 187 -- vendor/modules.txt | 27 - 149 files changed, 113 insertions(+), 22287 deletions(-) delete mode 100644 contrib/systemd/cilium-consul.service delete mode 100644 pkg/kvstore/consul.go delete mode 100644 pkg/kvstore/consul_test.go delete mode 100644 test/consul/ca-config.json delete mode 100644 test/consul/ca-csr.json delete mode 100644 test/consul/cilium-consul.yaml delete mode 100644 test/consul/consul-client-ca.crt delete mode 100644 test/consul/consul-client.crt delete mode 100644 test/consul/consul-client.json delete mode 100644 test/consul/consul-client.key delete mode 100644 test/consul/consul-config.json delete mode 100755 test/consul/gen-cert.sh delete mode 100644 test/consul/server-ca.crt delete mode 100644 test/consul/server.crt delete mode 100644 test/consul/server.json delete mode 100644 test/consul/server.key delete mode 100644 vendor/github.com/armon/go-metrics/.gitignore delete mode 100644 vendor/github.com/armon/go-metrics/.travis.yml delete mode 100644 vendor/github.com/armon/go-metrics/LICENSE delete mode 100644 vendor/github.com/armon/go-metrics/README.md delete mode 100644 vendor/github.com/armon/go-metrics/const_unix.go delete mode 100644 vendor/github.com/armon/go-metrics/const_windows.go delete mode 100644 vendor/github.com/armon/go-metrics/inmem.go delete mode 100644 vendor/github.com/armon/go-metrics/inmem_endpoint.go delete mode 100644 vendor/github.com/armon/go-metrics/inmem_signal.go delete mode 100644 vendor/github.com/armon/go-metrics/metrics.go delete mode 100644 vendor/github.com/armon/go-metrics/sink.go delete mode 100644 vendor/github.com/armon/go-metrics/start.go delete mode 100644 vendor/github.com/armon/go-metrics/statsd.go delete mode 100644 vendor/github.com/armon/go-metrics/statsite.go delete mode 100644 vendor/github.com/hashicorp/consul/api/.copywrite.hcl delete mode 100644 vendor/github.com/hashicorp/consul/api/LICENSE delete mode 100644 vendor/github.com/hashicorp/consul/api/README.md delete mode 100644 vendor/github.com/hashicorp/consul/api/acl.go delete mode 100644 vendor/github.com/hashicorp/consul/api/agent.go delete mode 100644 vendor/github.com/hashicorp/consul/api/api.go delete mode 100644 vendor/github.com/hashicorp/consul/api/catalog.go delete mode 100644 vendor/github.com/hashicorp/consul/api/config_entry.go delete mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_discoverychain.go delete mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_exports.go delete mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_file_system_certificate.go delete mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_gateways.go delete mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_inline_certificate.go delete mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_intentions.go delete mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_jwt_provider.go delete mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_mesh.go delete mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_rate_limit_ip.go delete mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_routes.go delete mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_sameness_group.go delete mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_status.go delete mode 100644 vendor/github.com/hashicorp/consul/api/connect.go delete mode 100644 vendor/github.com/hashicorp/consul/api/connect_ca.go delete mode 100644 vendor/github.com/hashicorp/consul/api/connect_intention.go delete mode 100644 vendor/github.com/hashicorp/consul/api/coordinate.go delete mode 100644 vendor/github.com/hashicorp/consul/api/debug.go delete mode 100644 vendor/github.com/hashicorp/consul/api/discovery_chain.go delete mode 100644 vendor/github.com/hashicorp/consul/api/event.go delete mode 100644 vendor/github.com/hashicorp/consul/api/exported_services.go delete mode 100644 vendor/github.com/hashicorp/consul/api/health.go delete mode 100644 vendor/github.com/hashicorp/consul/api/internal.go delete mode 100644 vendor/github.com/hashicorp/consul/api/kv.go delete mode 100644 vendor/github.com/hashicorp/consul/api/lock.go delete mode 100644 vendor/github.com/hashicorp/consul/api/namespace.go delete mode 100644 vendor/github.com/hashicorp/consul/api/operator.go delete mode 100644 vendor/github.com/hashicorp/consul/api/operator_area.go delete mode 100644 vendor/github.com/hashicorp/consul/api/operator_audit.go delete mode 100644 vendor/github.com/hashicorp/consul/api/operator_autopilot.go delete mode 100644 vendor/github.com/hashicorp/consul/api/operator_keyring.go delete mode 100644 vendor/github.com/hashicorp/consul/api/operator_license.go delete mode 100644 vendor/github.com/hashicorp/consul/api/operator_raft.go delete mode 100644 vendor/github.com/hashicorp/consul/api/operator_segment.go delete mode 100644 vendor/github.com/hashicorp/consul/api/operator_usage.go delete mode 100644 vendor/github.com/hashicorp/consul/api/partition.go delete mode 100644 vendor/github.com/hashicorp/consul/api/peering.go delete mode 100644 vendor/github.com/hashicorp/consul/api/prepared_query.go delete mode 100644 vendor/github.com/hashicorp/consul/api/raw.go delete mode 100644 vendor/github.com/hashicorp/consul/api/semaphore.go delete mode 100644 vendor/github.com/hashicorp/consul/api/session.go delete mode 100644 vendor/github.com/hashicorp/consul/api/snapshot.go delete mode 100644 vendor/github.com/hashicorp/consul/api/status.go delete mode 100644 vendor/github.com/hashicorp/consul/api/txn.go delete mode 100644 vendor/github.com/hashicorp/go-cleanhttp/LICENSE delete mode 100644 vendor/github.com/hashicorp/go-cleanhttp/README.md delete mode 100644 vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go delete mode 100644 vendor/github.com/hashicorp/go-cleanhttp/doc.go delete mode 100644 vendor/github.com/hashicorp/go-cleanhttp/handlers.go delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/.gitignore delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/CHANGELOG.md delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/LICENSE delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/README.md delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/edges.go delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/iradix.go delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/iter.go delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/node.go delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/raw_iter.go delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/reverse_iter.go delete mode 100644 vendor/github.com/hashicorp/go-rootcerts/.travis.yml delete mode 100644 vendor/github.com/hashicorp/go-rootcerts/LICENSE delete mode 100644 vendor/github.com/hashicorp/go-rootcerts/Makefile delete mode 100644 vendor/github.com/hashicorp/go-rootcerts/README.md delete mode 100644 vendor/github.com/hashicorp/go-rootcerts/doc.go delete mode 100644 vendor/github.com/hashicorp/go-rootcerts/rootcerts.go delete mode 100644 vendor/github.com/hashicorp/go-rootcerts/rootcerts_base.go delete mode 100644 vendor/github.com/hashicorp/go-rootcerts/rootcerts_darwin.go delete mode 100644 vendor/github.com/hashicorp/golang-lru/LICENSE delete mode 100644 vendor/github.com/hashicorp/golang-lru/simplelru/lru.go delete mode 100644 vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go delete mode 100644 vendor/github.com/hashicorp/serf/LICENSE delete mode 100644 vendor/github.com/hashicorp/serf/coordinate/client.go delete mode 100644 vendor/github.com/hashicorp/serf/coordinate/config.go delete mode 100644 vendor/github.com/hashicorp/serf/coordinate/coordinate.go delete mode 100644 vendor/github.com/hashicorp/serf/coordinate/phantom.go diff --git a/.github/workflows/conformance-runtime.yaml b/.github/workflows/conformance-runtime.yaml index b8512dac14bd5..6dd3afd4d40ba 100644 --- a/.github/workflows/conformance-runtime.yaml +++ b/.github/workflows/conformance-runtime.yaml @@ -186,8 +186,6 @@ jobs: ### # RuntimeAgentChaos Cilium agent Checking for file-descriptor leak # RuntimeAgentChaos Cilium agent removing leftover Cilium interfaces - # RuntimeAgentChaos KVStore Delete event on KVStore with CIDR identities - # RuntimeAgentChaos KVStore Validate that delete events on KVStore do not release in use identities # RuntimeAgentFQDNPolicies Can update L7 DNS policy rules # RuntimeAgentFQDNPolicies CNAME follow # RuntimeAgentFQDNPolicies DNS proxy policy works if Cilium stops @@ -200,7 +198,6 @@ jobs: # RuntimeAgentFQDNPolicies toFQDNs populates toCIDRSet (data from proxy) Policy addition after DNS lookup # RuntimeAgentFQDNPolicies Validate dns-proxy monitor information # RuntimeAgentFQDNPolicies With verbose policy logs Validates DNSSEC responses - # RuntimeAgentKVStoreTest KVStore tests Consul KVStore # RuntimeAgentKVStoreTest KVStore tests Etcd KVStore # RuntimeAgentPolicies Init Policy Default Drop Test tests egress # RuntimeAgentPolicies Init Policy Default Drop Test tests ingress diff --git a/Documentation/cheatsheet.rst b/Documentation/cheatsheet.rst index 1d8a4d09627cc..60a133e14547c 100644 --- a/Documentation/cheatsheet.rst +++ b/Documentation/cheatsheet.rst @@ -106,7 +106,7 @@ Check the status of the agent .. code-block:: shell-session $ cilium-dbg status - KVStore: Ok Consul: 172.17.0.3:8300 + KVStore: Ok Etcd: 172.17.0.3:4001 ContainerRuntime: Ok Kubernetes: Disabled Cilium: Ok OK @@ -122,7 +122,7 @@ Get a detailed status of the agent: .. code-block:: shell-session $ cilium-dbg status --all-controllers --all-health --all-redirects - KVStore: Ok Consul: 172.17.0.3:8300 + KVStore: Ok Etcd: 172.17.0.3:4001 ContainerRuntime: Ok Kubernetes: Disabled Cilium: Ok OK diff --git a/Documentation/cmdref/kvstore.rst b/Documentation/cmdref/kvstore.rst index 7dc4c6a3761cb..b6c69cee4ce94 100644 --- a/Documentation/cmdref/kvstore.rst +++ b/Documentation/cmdref/kvstore.rst @@ -13,7 +13,7 @@ Key-Value Store | Option | Description | Default | +---------------------+--------------------------------------+----------------------+ | --kvstore TYPE | Key Value Store Type: | | -| | (consul, etcd) | | +| | (etcd) | | +---------------------+--------------------------------------+----------------------+ | --kvstore-opt OPTS | | | +---------------------+--------------------------------------+----------------------+ diff --git a/Documentation/contributing/development/dev_setup.rst b/Documentation/contributing/development/dev_setup.rst index 35e4973f07663..e3fba64ed81fd 100644 --- a/Documentation/contributing/development/dev_setup.rst +++ b/Documentation/contributing/development/dev_setup.rst @@ -378,13 +378,10 @@ directly and manually install Cilium: $ sudo mkdir -p /etc/sysconfig/ $ sudo cp contrib/systemd/cilium.service /etc/systemd/system/ $ sudo cp contrib/systemd/cilium-docker.service /etc/systemd/system/ - $ sudo cp contrib/systemd/cilium-consul.service /etc/systemd/system/ $ sudo cp contrib/systemd/cilium /etc/sysconfig/cilium $ sudo usermod -a -G cilium vagrant $ sudo systemctl enable cilium-docker $ sudo systemctl restart cilium-docker - $ sudo systemctl enable cilium-consul - $ sudo systemctl restart cilium-consul $ sudo systemctl enable cilium $ sudo systemctl restart cilium diff --git a/Documentation/contributing/testing/e2e_legacy.rst b/Documentation/contributing/testing/e2e_legacy.rst index 7ac6c35d617ec..0cf714ff9954e 100644 --- a/Documentation/contributing/testing/e2e_legacy.rst +++ b/Documentation/contributing/testing/e2e_legacy.rst @@ -680,7 +680,7 @@ test an exhaustive data will be added. level=info msg=Starting testName=RuntimeKafka level=info msg="Vagrant: running command \"vagrant ssh-config runtime\"" cmd: "sudo cilium-dbg status" exitCode: 0 - KVStore: Ok Consul: 172.17.0.3:8300 + KVStore: Ok Etcd: 172.17.0.3:4001 ContainerRuntime: Ok Kubernetes: Disabled Kubernetes APIs: [""] diff --git a/Documentation/operations/upgrade.rst b/Documentation/operations/upgrade.rst index 841205072a01a..62198846e5d76 100644 --- a/Documentation/operations/upgrade.rst +++ b/Documentation/operations/upgrade.rst @@ -301,6 +301,7 @@ communicating via the proxy must reconnect to re-establish connections. 100 QPS/200 Burst. To configure the rate limit for Cilium Operator, use the ``--operator-k8s-client-qps`` and ``--operator-k8s-client-burst`` flags or the corresponding Helm values. +* Support for Consul, deprecated since v1.12, has been removed. Removed Options ~~~~~~~~~~~~~~~ diff --git a/Documentation/security/network/proxy/envoy.rst b/Documentation/security/network/proxy/envoy.rst index 9293f37db61af..8b775bdf5c751 100644 --- a/Documentation/security/network/proxy/envoy.rst +++ b/Documentation/security/network/proxy/envoy.rst @@ -585,7 +585,7 @@ and adding the ``--debug-verbose=flow`` flag. $ sudo service cilium stop - $ sudo /usr/bin/cilium-agent --debug --ipv4-range 10.11.0.0/16 --kvstore-opt consul.address=192.168.60.11:8500 --kvstore consul -t vxlan --fixed-identity-mapping=128=kv-store --fixed-identity-mapping=129=kube-dns --debug-verbose=flow + $ sudo /usr/bin/cilium-agent --debug --ipv4-range 10.11.0.0/16 --kvstore-opt etcd.address=192.168.60.11:4001 --kvstore etcd -t vxlan --fixed-identity-mapping=128=kv-store --fixed-identity-mapping=129=kube-dns --debug-verbose=flow Step 13: Add Runtime Tests diff --git a/Makefile b/Makefile index 04282fbdfa0f0..66d801ae91be0 100644 --- a/Makefile +++ b/Makefile @@ -49,8 +49,7 @@ SKIP_CUSTOMVET_CHECK ?= "false" JOB_BASE_NAME ?= cilium_test -TEST_LDFLAGS=-ldflags "-X github.com/cilium/cilium/pkg/kvstore.consulDummyAddress=https://consul:8443 \ - -X github.com/cilium/cilium/pkg/kvstore.etcdDummyAddress=http://etcd:4002" +TEST_LDFLAGS=-ldflags "-X github.com/cilium/cilium/pkg/kvstore.etcdDummyAddress=http://etcd:4002" TEST_UNITTEST_LDFLAGS= @@ -86,9 +85,9 @@ tests-privileged: ## Run Go tests including ones that require elevated privilege $(TESTPKGS) $(GOTEST_BASE) $(GOTEST_COVER_OPTS) | $(GOTEST_FORMATTER) $(MAKE) generate-cov -start-kvstores: ## Start running kvstores (etcd and consul containers) for integration tests. +start-kvstores: ## Start running kvstores (etcd container) for integration tests. ifeq ($(SKIP_KVSTORES),"false") - @echo Starting key-value store containers... + @echo Starting key-value store container... -$(QUIET)$(CONTAINER_ENGINE) rm -f "cilium-etcd-test-container" 2> /dev/null $(QUIET)$(CONTAINER_ENGINE) run -d \ -e ETCD_UNSUPPORTED_ARCH=$(GOARCH) \ @@ -101,25 +100,11 @@ ifeq ($(SKIP_KVSTORES),"false") -listen-peer-urls http://0.0.0.0:2380 \ -initial-cluster-token etcd-cluster-1 \ -initial-cluster-state new - -$(QUIET)$(CONTAINER_ENGINE) rm -f "cilium-consul-test-container" 2> /dev/null - $(QUIET)rm -rf /tmp/cilium-consul-certs - $(QUIET)mkdir /tmp/cilium-consul-certs - $(QUIET)cp $(CURDIR)/test/consul/* /tmp/cilium-consul-certs - $(QUIET)chmod -R a+rX /tmp/cilium-consul-certs - $(QUIET)$(CONTAINER_ENGINE) run -d \ - --name "cilium-consul-test-container" \ - -p 8501:8443 \ - -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true, "disable_update_check": true}' \ - -v /tmp/cilium-consul-certs:/cilium-consul/ \ - $(CONSUL_IMAGE) \ - agent -client=0.0.0.0 -server -bootstrap-expect 1 -config-file=/cilium-consul/consul-config.json endif -stop-kvstores: ## Forcefully removes running kvstore components (etcd and consul containers) for integration tests. +stop-kvstores: ## Forcefully removes running kvstore components (etcd container) for integration tests. ifeq ($(SKIP_KVSTORES),"false") $(QUIET)$(CONTAINER_ENGINE) rm -f "cilium-etcd-test-container" - $(QUIET)$(CONTAINER_ENGINE) rm -f "cilium-consul-test-container" - $(QUIET)rm -rf /tmp/cilium-consul-certs endif generate-cov: ## Generate HTML coverage report at coverage-all.html. diff --git a/Makefile.defs b/Makefile.defs index d4e24714c948b..bc6723c41e3ba 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -62,8 +62,6 @@ ETCD_IMAGE_VERSION = v3.5.15 ETCD_IMAGE_SHA = sha256:9a01b7da0a3cde485c03fcf58fef9b2a09c81b4926b2b7d7ae6d1e9b20a2a192 ETCD_IMAGE=gcr.io/etcd-development/etcd:$(ETCD_IMAGE_VERSION)@$(ETCD_IMAGE_SHA) -CONSUL_IMAGE=consul:1.7.2 - CILIUM_BUILDER_IMAGE=$(shell cat $(ROOT_DIR)/images/cilium/Dockerfile | grep "ARG CILIUM_BUILDER_IMAGE=" | cut -d"=" -f2) export CILIUM_CLI ?= cilium diff --git a/Vagrantfile b/Vagrantfile index 75c2db18d8ac9..47ef1a0524251 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -116,7 +116,6 @@ git config --global --add safe.directory /home/vagrant/go/src/github.com/cilium/ sudo -E make -C /home/vagrant/go/src/github.com/cilium/cilium/ install sudo mkdir -p /etc/sysconfig -sudo cp /home/vagrant/go/src/github.com/cilium/cilium/contrib/systemd/cilium-consul.service /lib/systemd/system sudo cp /home/vagrant/go/src/github.com/cilium/cilium/contrib/systemd/cilium-docker.service /lib/systemd/system sudo cp /home/vagrant/go/src/github.com/cilium/cilium/contrib/systemd/cilium-etcd.service /lib/systemd/system sudo cp /home/vagrant/go/src/github.com/cilium/cilium/contrib/systemd/cilium.service /lib/systemd/system diff --git a/contrib/systemd/cilium b/contrib/systemd/cilium index bcd758330a911..ad27c60e0d67a 100644 --- a/contrib/systemd/cilium +++ b/contrib/systemd/cilium @@ -14,16 +14,16 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin ## Default: "" ## ServiceRestart: cilium -# Set Key-value store(etcd/consul): -# --kvstore consul +# Set Key-value store (etcd): +# --kvstore etcd # Set Key-value store options: -# --kvstore-opt consul.address=127.0.0.1:8500 +# --kvstore-opt etcd.address=127.0.0.1:4001 # # Note: A key-value store is require for cilium to function. # Check more cli options using cilium-agent -h CILIUM_IMAGE=cilium/cilium:latest -CILIUM_OPTS=--kvstore consul --kvstore-opt consul.address=127.0.0.1:8500 -CILIUM_OPERATOR_OPTS=--kvstore consul --kvstore-opt consul.address=127.0.0.1:8500 --k8s-kubeconfig-path=/home/vagrant/.kube/config +CILIUM_OPTS=--kvstore etcd --kvstore-opt etcd.address=127.0.0.1:4001 +CILIUM_OPERATOR_OPTS=--kvstore etcd --kvstore-opt etcd.address=127.0.0.1:4001 --k8s-kubeconfig-path=/home/vagrant/.kube/config HOME=/home/vagrant diff --git a/contrib/systemd/cilium-consul.service b/contrib/systemd/cilium-consul.service deleted file mode 100644 index 3766347cf8174..0000000000000 --- a/contrib/systemd/cilium-consul.service +++ /dev/null @@ -1,21 +0,0 @@ -[Unit] -Description=cilium-consul -Documentation=https://github.com/cilium/cilium -Requires=docker.service - -[Service] -Type=oneshot -RemainAfterExit=yes -TimeoutStartSec=0 -ExecStartPre=/usr/bin/docker pull consul:1.1.0 -ExecStartPre=-/usr/bin/docker rm -f cilium-consul -ExecStartPre=/usr/bin/docker create \ - --name 'cilium-consul' -p 8500:8500 \ - -e CONSUL_LOCAL_CONFIG='{"skip_leave_on_interrupt": true, "disable_update_check": true}' \ - consul:1.1.0 agent -client=0.0.0.0 -server -bootstrap-expect 1 \ - -ExecStart= /usr/bin/docker start cilium-consul -ExecStop=-/usr/bin/docker rm -f cilium-consul - -[Install] -WantedBy=multi-user.target diff --git a/contrib/systemd/cilium.service b/contrib/systemd/cilium.service index 80c2d458f5deb..e6cb66bcb0591 100644 --- a/contrib/systemd/cilium.service +++ b/contrib/systemd/cilium.service @@ -1,7 +1,7 @@ [Unit] Description=cilium Documentation=http://docs.cilium.io -Requires=docker.service cilium-consul.service cilium-docker.service +Requires=docker.service cilium-docker.service [Service] Type=simple diff --git a/contrib/systemd/cilium.service-with-docker b/contrib/systemd/cilium.service-with-docker index 90ccca6ee26da..a8739679fb7b2 100644 --- a/contrib/systemd/cilium.service-with-docker +++ b/contrib/systemd/cilium.service-with-docker @@ -1,7 +1,7 @@ [Unit] Description=cilium Documentation=http://docs.cilium.io -Requires=docker.service cilium-consul.service cilium-docker.service +Requires=docker.service cilium-docker.service [Service] Type=oneshot diff --git a/contrib/vagrant/start.sh b/contrib/vagrant/start.sh index 77f9d213cf12a..ce7692f112bf7 100755 --- a/contrib/vagrant/start.sh +++ b/contrib/vagrant/start.sh @@ -334,14 +334,14 @@ function write_cilium_cfg() { cilium_operator_options+=" --identity-allocation-mode=crd" else if [[ "${IPV4}" -eq "1" ]]; then - cilium_options+=" --kvstore-opt consul.address=${MASTER_IPV4}:8500" - cilium_operator_options+=" --kvstore-opt consul.address=${MASTER_IPV4}:8500" + cilium_options+=" --kvstore-opt etcd.address=${MASTER_IPV4}:4001" + cilium_operator_options+=" --kvstore-opt etcd.address=${MASTER_IPV4}:4001" else - cilium_options+=" --kvstore-opt consul.address=[${ipv6_addr}]:8500" - cilium_operator_options+=" --kvstore-opt consul.address=[${ipv6_addr}]:8500" + cilium_options+=" --kvstore-opt etcd.address=[${ipv6_addr}]:4001" + cilium_operator_options+=" --kvstore-opt etcd.address=[${ipv6_addr}]:4001" fi - cilium_options+=" --kvstore consul" - cilium_operator_options+=" --kvstore consul" + cilium_options+=" --kvstore etcd" + cilium_operator_options+=" --kvstore etcd" fi cat <> "$filename" diff --git a/daemon/cmd/daemon_test.go b/daemon/cmd/daemon_test.go index 7c8c9d6343b44..016ff4d6ddee1 100644 --- a/daemon/cmd/daemon_test.go +++ b/daemon/cmd/daemon_test.go @@ -237,20 +237,6 @@ func setupDaemonEtcdSuite(tb testing.TB) *DaemonEtcdSuite { } } -type DaemonConsulSuite struct { - DaemonSuite -} - -func setupDaemonConsulSuite(tb testing.TB) *DaemonConsulSuite { - testutils.IntegrationTest(tb) - kvstore.SetupDummy(tb, "consul") - - ds := setupDaemonSuite(tb) - return &DaemonConsulSuite{ - DaemonSuite: *ds, - } -} - func TestMinimumWorkerThreadsIsSet(t *testing.T) { require.Equal(t, true, numWorkerThreads() >= 2) require.Equal(t, true, numWorkerThreads() >= runtime.NumCPU()) diff --git a/daemon/cmd/endpoint_test.go b/daemon/cmd/endpoint_test.go index 0f75fb2655d61..53f9daf580b80 100644 --- a/daemon/cmd/endpoint_test.go +++ b/daemon/cmd/endpoint_test.go @@ -43,11 +43,6 @@ func getEPTemplate(t *testing.T, d *Daemon) *models.EndpointChangeRequest { } } -func TestEndpointAddReservedLabelConsul(t *testing.T) { - ds := setupDaemonConsulSuite(t) - ds.testEndpointAddReservedLabel(t) -} - func TestEndpointAddReservedLabelEtcd(t *testing.T) { ds := setupDaemonEtcdSuite(t) ds.testEndpointAddReservedLabel(t) @@ -80,11 +75,6 @@ func (ds *DaemonSuite) testEndpointAddReservedLabel(t *testing.T) { assertOnMetric(t, string(models.EndpointStateInvalid), 0) } -func TestEndpointAddInvalidLabelConsul(t *testing.T) { - ds := setupDaemonConsulSuite(t) - ds.testEndpointAddInvalidLabel(t) -} - func TestEndpointAddInvalidLabelEtcd(t *testing.T) { ds := setupDaemonEtcdSuite(t) ds.testEndpointAddInvalidLabel(t) @@ -105,11 +95,6 @@ func (ds *DaemonSuite) testEndpointAddInvalidLabel(t *testing.T) { assertOnMetric(t, string(models.EndpointStateInvalid), 0) } -func TestEndpointAddNoLabelsConsul(t *testing.T) { - ds := setupDaemonConsulSuite(t) - ds.testEndpointAddNoLabels(t) -} - func TestEndpointAddNoLabelsEtcd(t *testing.T) { ds := setupDaemonEtcdSuite(t) ds.testEndpointAddNoLabels(t) @@ -155,11 +140,6 @@ func (ds *DaemonSuite) testUpdateSecLabels(t *testing.T) { require.Equal(t, apiEndpoint.PatchEndpointIDLabelsUpdateFailedCode, code) } -func TestUpdateSecLabelsConsul(t *testing.T) { - ds := setupDaemonConsulSuite(t) - ds.testUpdateSecLabels(t) -} - func TestUpdateSecLabelsEtcd(t *testing.T) { ds := setupDaemonEtcdSuite(t) ds.testUpdateSecLabels(t) @@ -177,11 +157,6 @@ func (ds *DaemonSuite) testUpdateLabelsFailed(t *testing.T) { assertOnMetric(t, string(models.EndpointStateReady), 0) } -func TestUpdateLabelsFailedConsul(t *testing.T) { - ds := setupDaemonConsulSuite(t) - ds.testUpdateLabelsFailed(t) -} - func TestUpdateLabelsFailedEtcd(t *testing.T) { ds := setupDaemonEtcdSuite(t) ds.testUpdateLabelsFailed(t) diff --git a/daemon/cmd/policy_test.go b/daemon/cmd/policy_test.go index bde400320a928..85bd7807685c1 100644 --- a/daemon/cmd/policy_test.go +++ b/daemon/cmd/policy_test.go @@ -243,11 +243,6 @@ func (ds *DaemonSuite) regenerateEndpoint(t *testing.T, e *endpoint.Endpoint) { require.Equal(t, true, buildSuccess) } -func TestUpdateConsumerMapConsul(t *testing.T) { - ds := setupDaemonConsulSuite(t) - ds.testUpdateConsumerMap(t) -} - func TestUpdateConsumerMapEtcd(t *testing.T) { ds := setupDaemonEtcdSuite(t) ds.testUpdateConsumerMap(t) @@ -446,11 +441,6 @@ func (ds *DaemonSuite) testUpdateConsumerMap(t *testing.T) { require.Equal(t, expectedNetworkPolicy, prodBarNetworkPolicy) } -func TestL4L7ShadowingConsul(t *testing.T) { - ds := setupDaemonConsulSuite(t) - ds.testL4L7Shadowing(t) -} - func TestL4L7ShadowingEtcd(t *testing.T) { ds := setupDaemonEtcdSuite(t) ds.testL4L7Shadowing(t) @@ -539,11 +529,6 @@ func (ds *DaemonSuite) testL4L7Shadowing(t *testing.T) { require.Equal(t, expectedNetworkPolicy, qaBarNetworkPolicy) } -func TestL4L7ShadowingShortCircuitConsul(t *testing.T) { - ds := setupDaemonConsulSuite(t) - ds.testL4L7ShadowingShortCircuit(t) -} - func TestL4L7ShadowingShortCircuitEtcd(t *testing.T) { ds := setupDaemonEtcdSuite(t) ds.testL4L7ShadowingShortCircuit(t) @@ -629,11 +614,6 @@ func (ds *DaemonSuite) testL4L7ShadowingShortCircuit(t *testing.T) { require.Equal(t, expectedNetworkPolicy, qaBarNetworkPolicy) } -func TestL3DependentL7Consul(t *testing.T) { - ds := setupDaemonConsulSuite(t) - ds.testL3DependentL7(t) -} - func TestL3DependentL7Etcd(t *testing.T) { ds := setupDaemonEtcdSuite(t) ds.testL3DependentL7(t) @@ -740,11 +720,6 @@ func (ds *DaemonSuite) testL3DependentL7(t *testing.T) { require.Equal(t, expectedNetworkPolicy, qaBarNetworkPolicy) } -func TestReplacePolicyConsul(t *testing.T) { - ds := setupDaemonConsulSuite(t) - ds.testReplacePolicy(t) -} - func TestReplacePolicyEtcd(t *testing.T) { ds := setupDaemonEtcdSuite(t) ds.testReplacePolicy(t) @@ -799,11 +774,6 @@ func (ds *DaemonSuite) testReplacePolicy(t *testing.T) { ds.d.policy.Mutex.RUnlock() } -func TestRemovePolicyConsul(t *testing.T) { - ds := setupDaemonConsulSuite(t) - ds.testRemovePolicy(t) -} - func TestRemovePolicyEtcd(t *testing.T) { ds := setupDaemonEtcdSuite(t) ds.testRemovePolicy(t) @@ -897,11 +867,6 @@ func (ds *DaemonSuite) testRemovePolicy(t *testing.T) { require.Len(t, networkPolicies, 0) } -func TestIncrementalPolicyConsul(t *testing.T) { - ds := setupDaemonConsulSuite(t) - ds.testIncrementalPolicy(t) -} - func TestIncrementalPolicyEtcd(t *testing.T) { ds := setupDaemonEtcdSuite(t) ds.testIncrementalPolicy(t) @@ -1058,11 +1023,6 @@ func (ds *DaemonSuite) testIncrementalPolicy(t *testing.T) { require.Len(t, networkPolicies, 0) } -func TestAddCiliumNetworkPolicyV2Consul(t *testing.T) { - ds := setupDaemonConsulSuite(t) - ds.testAddCiliumNetworkPolicyV2(t) -} - func TestAddCiliumNetworkPolicyV2Etcd(t *testing.T) { ds := setupDaemonEtcdSuite(t) ds.testAddCiliumNetworkPolicyV2(t) diff --git a/go.mod b/go.mod index efb42e8b78450..f6b00da89659c 100644 --- a/go.mod +++ b/go.mod @@ -60,7 +60,6 @@ require ( github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 - github.com/hashicorp/consul/api v1.29.2 github.com/hashicorp/go-hclog v1.6.3 github.com/hashicorp/go-immutable-radix/v2 v2.1.0 github.com/hashicorp/golang-lru/v2 v2.0.7 @@ -160,7 +159,6 @@ require ( github.com/Microsoft/hcsshim v0.11.4 // indirect github.com/alecthomas/participle/v2 v2.1.0 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect - github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.27 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 // indirect @@ -224,16 +222,8 @@ require ( github.com/gosuri/uitable v0.0.4 // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-msgpack v1.1.5 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-rootcerts v1.0.2 // indirect - github.com/hashicorp/go-sockaddr v1.0.5 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hashicorp/serf v0.10.1 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect diff --git a/go.sum b/go.sum index dd75c11524f7d..7060748f4fbf1 100644 --- a/go.sum +++ b/go.sum @@ -41,7 +41,6 @@ github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= @@ -68,9 +67,7 @@ github.com/alecthomas/participle/v2 v2.1.0/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9l github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= 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/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/aliyun/alibaba-cloud-sdk-go v1.62.808 h1:BnS1hiJ9dhbcAZuCCCpFV2C+Rspztne9hhhLcETA2NM= @@ -80,11 +77,6 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= -github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -123,7 +115,6 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 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/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bombsimon/logrusr/v4 v4.1.0 h1:uZNPbwusB0eUXlO8hIUwStE6Lr5bLN6IgYgG+75kuh4= @@ -183,8 +174,6 @@ github.com/cilium/stream v0.0.0-20240226091623-f979d32855f8 h1:j6VF1s6gz3etRH5Ob github.com/cilium/stream v0.0.0-20240226091623-f979d32855f8/go.mod h1:/e83AwqvNKpyg4n3C41qmnmj1x2G9DwzI+jb7GkF4lI= github.com/cilium/workerpool v1.2.0 h1:Wc2iOPTvCgWKQXeq4L5tnx4QFEI+z5q1+bSpSS0cnAY= github.com/cilium/workerpool v1.2.0/go.mod h1:GOYJhwlnIjR+jWSDNBb5kw47G1H/XA9X4WOBpgr4pQU= -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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cfssl v1.6.5 h1:46zpNkm6dlNkMZH/wMW22ejih6gIaJbzL2du6vD7ZeI= github.com/cloudflare/cfssl v1.6.5/go.mod h1:Bk1si7sq8h2+yVEDrFJiz3d7Aw+pfjjJSZVaD+Taky4= @@ -269,8 +258,6 @@ github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0 github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= -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.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= @@ -294,7 +281,6 @@ github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpj github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= 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-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.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= @@ -388,7 +374,6 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/cel-go v0.21.0 h1:cl6uW/gxN+Hy50tNYvI691+sXxioCnstFzLp2WO4GCI= @@ -462,58 +447,23 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= -github.com/hashicorp/consul/api v1.29.2 h1:aYyRn8EdE2mSfG14S1+L9Qkjtz8RzmaWh6AcNGRNwPw= -github.com/hashicorp/consul/api v1.29.2/go.mod h1:0YObcaLNDSbtlgzIRtmRXI1ZkeuK0trCBxwZQ4MYnIk= -github.com/hashicorp/consul/proto-public v0.6.2 h1:+DA/3g/IiKlJZb88NBn0ZgXrxJp2NlvCZdEyl+qxvL0= -github.com/hashicorp/consul/proto-public v0.6.2/go.mod h1:cXXbOg74KBNGajC+o8RlA502Esf0R9prcoJgiOX/2Tg= -github.com/hashicorp/consul/sdk v0.16.1 h1:V8TxTnImoPD5cj0U9Spl0TUxcytjcbbJeADFF07KdHg= -github.com/hashicorp/consul/sdk v0.16.1/go.mod h1:fSXvwxB2hmh1FMZCNl6PwX0Q/1wdWtHJcZ7Ea5tns0s= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.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.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/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 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix/v2 v2.1.0 h1:CUW5RYIcysz+D3B+l1mDeXrQ7fUvGGCwJfdASSzbrfo= github.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs= -github.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4= -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-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= -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.5 h1:dvk7TIXCZpmfOlM+9mlcrWmWjw/wlKT+VDq2wMvfPJU= -github.com/hashicorp/go-sockaddr v1.0.5/go.mod h1:uoUUmtwU7n9Dv3O4SNLeFvg0SxQ3lyjsj6+CCykpaxI= -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.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= -github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= -github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= -github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -544,7 +494,6 @@ github.com/jsimonetti/rtnetlink/v2 v2.0.1 h1:xda7qaHDSVOsADNouv7ukSuicKZO7GgVUCX github.com/jsimonetti/rtnetlink/v2 v2.0.1/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE= 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.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -593,16 +542,10 @@ github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= -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.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/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.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-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -632,13 +575,10 @@ github.com/mdlayher/packet v1.1.2/go.mod h1:GEu1+n9sG5VtiRE4SydOmX5GTwyyYlteZiFU github.com/mdlayher/socket v0.2.1/go.mod h1:QLlNPkFR88mRUNQIzRBMfXxwKal8H7u1h3bL1CV+f0E= github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U= github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= -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.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws= github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -646,7 +586,6 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= @@ -707,9 +646,6 @@ github.com/osrg/gobgp v2.0.0+incompatible h1:91ARQbE1AtO0U4TIxHPJ7wYVZIqduyBwS1+ github.com/osrg/gobgp v2.0.0+incompatible/go.mod h1:vGVJPLW6JFDD7WA1vJsjB8OKmbbC2TKwHtr90CZS/u4= github.com/osrg/gobgp/v3 v3.29.0 h1:ISWjY5YQ45THcvXWdG2ykzXWxS22rgE6U9YWdaI/ki8= github.com/osrg/gobgp/v3 v3.29.0/go.mod h1:ZGeSti9mURR/o5hf5R6T1FM5g1yiEBZbhP+TuqYJUpI= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= @@ -724,37 +660,30 @@ github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rK github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -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/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/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.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -767,7 +696,6 @@ github.com/rubenv/sql-migrate v1.5.2 h1:bMDqOnrJVV/6JQgQ/MxOpU+AdO8uzYYA/TxFUBzF github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= @@ -776,8 +704,6 @@ github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71e github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= @@ -788,7 +714,6 @@ github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5g github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -843,7 +768,6 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= 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.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= @@ -940,7 +864,6 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/W golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/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-20190510104115-cbcb75029529/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-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= @@ -989,7 +912,6 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn 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-20190923162816-aa69164e4478/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-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -999,7 +921,6 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= @@ -1025,25 +946,19 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -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-20181116152217-5ac8a444bdc5/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/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-20191005200804-aed5e4c7ecf9/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-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-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1053,8 +968,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201126233918-771906719818/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-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= @@ -1065,7 +978,6 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1088,7 +1000,6 @@ golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -1108,9 +1019,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm 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-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1191,7 +1100,6 @@ 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.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.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 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/pkg/command/map_string_test.go b/pkg/command/map_string_test.go index 142a1ca9de899..a949406e04270 100644 --- a/pkg/command/map_string_test.go +++ b/pkg/command/map_string_test.go @@ -292,7 +292,7 @@ func Test_isValidKeyValuePair(t *testing.T) { { name: "valid format with colon", args: args{ - str: "consul.address=127.0.0.1:8500", + str: "etcd.address=127.0.0.1:4001", }, want: true, }, diff --git a/pkg/defaults/defaults.go b/pkg/defaults/defaults.go index 7f10090579bc9..153c11ae244b5 100644 --- a/pkg/defaults/defaults.go +++ b/pkg/defaults/defaults.go @@ -407,7 +407,7 @@ const ( LockLeaseTTL = 25 * time.Second // KVstoreLeaseMaxTTL is the upper bound for KVStore lease TTL value. - // It is calculated as Min(int64 positive max, etcd MaxLeaseTTL, consul MaxLeaseTTL) + // It is calculated as Min(int64 positive max, etcd MaxLeaseTTL) KVstoreLeaseMaxTTL = 86400 * time.Second // IPAMPreAllocation is the default value for diff --git a/pkg/identity/cache/allocation_test.go b/pkg/identity/cache/allocation_test.go index 531573796ec2f..ac0b59e17d980 100644 --- a/pkg/identity/cache/allocation_test.go +++ b/pkg/identity/cache/allocation_test.go @@ -31,13 +31,9 @@ var fakeConfig = &option.DaemonConfig{ } func TestAllocateIdentityReserved(t *testing.T) { - for _, be := range []string{"etcd", "consul"} { - t.Run(be, func(t *testing.T) { - testutils.IntegrationTest(t) - kvstore.SetupDummy(t, be) - testAllocateIdentityReserved(t) - }) - } + testutils.IntegrationTest(t) + kvstore.SetupDummy(t, "etcd") + testAllocateIdentityReserved(t) } func testAllocateIdentityReserved(t *testing.T) { @@ -159,13 +155,9 @@ func (d *dummyOwner) WaitUntilID(target identity.NumericIdentity) int { } func TestEventWatcherBatching(t *testing.T) { - for _, be := range []string{"etcd", "consul"} { - t.Run(be, func(t *testing.T) { - testutils.IntegrationTest(t) - kvstore.SetupDummy(t, be) - testEventWatcherBatching(t) - }) - } + testutils.IntegrationTest(t) + kvstore.SetupDummy(t, "etcd") + testEventWatcherBatching(t) } func testEventWatcherBatching(t *testing.T) { @@ -222,13 +214,9 @@ func testEventWatcherBatching(t *testing.T) { } func TestGetIdentityCache(t *testing.T) { - for _, be := range []string{"etcd", "consul"} { - t.Run(be, func(t *testing.T) { - testutils.IntegrationTest(t) - kvstore.SetupDummy(t, be) - testGetIdentityCache(t) - }) - } + testutils.IntegrationTest(t) + kvstore.SetupDummy(t, "etcd") + testGetIdentityCache(t) } func testGetIdentityCache(t *testing.T) { @@ -245,13 +233,9 @@ func testGetIdentityCache(t *testing.T) { } func TestAllocator(t *testing.T) { - for _, be := range []string{"etcd", "consul"} { - t.Run(be, func(t *testing.T) { - testutils.IntegrationTest(t) - kvstore.SetupDummy(t, be) - testAllocator(t) - }) - } + testutils.IntegrationTest(t) + kvstore.SetupDummy(t, "etcd") + testAllocator(t) } func testAllocator(t *testing.T) { @@ -342,13 +326,9 @@ func testAllocator(t *testing.T) { } func TestLocalAllocation(t *testing.T) { - for _, be := range []string{"etcd", "consul"} { - t.Run(be, func(t *testing.T) { - testutils.IntegrationTest(t) - kvstore.SetupDummy(t, be) - testLocalAllocation(t) - }) - } + testutils.IntegrationTest(t) + kvstore.SetupDummy(t, "etcd") + testLocalAllocation(t) } func testLocalAllocation(t *testing.T) { @@ -416,13 +396,9 @@ func testLocalAllocation(t *testing.T) { } func TestAllocatorReset(t *testing.T) { - for _, be := range []string{"etcd", "consul"} { - t.Run(be, func(t *testing.T) { - testutils.IntegrationTest(t) - kvstore.SetupDummy(t, be) - testAllocatorReset(t) - }) - } + testutils.IntegrationTest(t) + kvstore.SetupDummy(t, "etcd") + testAllocatorReset(t) } // Test that we can close and reopen the allocator successfully. diff --git a/pkg/kvstore/allocator/allocator_test.go b/pkg/kvstore/allocator/allocator_test.go index 03e83be273436..63b0273abc478 100644 --- a/pkg/kvstore/allocator/allocator_test.go +++ b/pkg/kvstore/allocator/allocator_test.go @@ -31,6 +31,8 @@ const ( var ( tick = 10 * time.Millisecond timeout = 5 * time.Second + + etcdOpts = map[string]string{kvstore.EtcdRateLimitOption: "100"} ) // FIXME: this should be named better, it implements pkg/allocator.Backend @@ -66,12 +68,8 @@ func randomTestName() string { func BenchmarkAllocate(b *testing.B) { testutils.IntegrationTest(b) - for _, backendName := range []string{"etcd", "consul"} { - b.Run(backendName, func(b *testing.B) { - kvstore.SetupDummyWithConfigOpts(b, backendName, opts(backendName)) - benchmarkAllocate(b) - }) - } + kvstore.SetupDummyWithConfigOpts(b, "etcd", etcdOpts) + benchmarkAllocate(b) } func benchmarkAllocate(b *testing.B) { @@ -94,12 +92,8 @@ func benchmarkAllocate(b *testing.B) { func BenchmarkRunLocksGC(b *testing.B) { testutils.IntegrationTest(b) - for _, backendName := range []string{"etcd", "consul"} { - b.Run(backendName, func(b *testing.B) { - kvstore.SetupDummyWithConfigOpts(b, backendName, opts(backendName)) - benchmarkRunLocksGC(b, backendName) - }) - } + kvstore.SetupDummyWithConfigOpts(b, "etcd", etcdOpts) + benchmarkRunLocksGC(b, "etcd") } func benchmarkRunLocksGC(b *testing.B, backendName string) { @@ -129,26 +123,13 @@ func benchmarkRunLocksGC(b *testing.B, backendName string) { lock1, err = backend1.Lock(context.Background(), shortKey) require.NoError(b, err) close(gotLock1) - var client kvstore.BackendOperations - switch backendName { - case "etcd": - client, _ = kvstore.NewClient(context.Background(), - backendName, - map[string]string{ - kvstore.EtcdAddrOption: kvstore.EtcdDummyAddress(), - }, - nil, - ) - case "consul": - client, _ = kvstore.NewClient(context.Background(), - backendName, - map[string]string{ - kvstore.ConsulAddrOption: kvstore.ConsulDummyAddress(), - kvstore.ConsulOptionConfig: kvstore.ConsulDummyConfigFile(), - }, - nil, - ) - } + client, _ := kvstore.NewClient(context.Background(), + backendName, + map[string]string{ + kvstore.EtcdAddrOption: kvstore.EtcdDummyAddress(), + }, + nil, + ) lock2, err = client.LockPath(context.Background(), allocatorName+"/locks/"+kvstore.Client().Encode([]byte(shortKey.GetKey()))) require.NoError(b, err) close(gotLock2) @@ -169,14 +150,7 @@ func benchmarkRunLocksGC(b *testing.B, backendName string) { // Check which locks are stale, it should be lock1 and lock2 staleLocks, err = allocator.RunLocksGC(context.Background(), staleLocks) require.NoError(b, err) - switch backendName { - case "consul": - // Contrary to etcd, consul does not create a lock in the kvstore - // if a lock is already being held. - require.Len(b, staleLocks, 1) - case "etcd": - require.Len(b, staleLocks, 2) - } + require.Len(b, staleLocks, 2) var ( oldestRev = uint64(math.MaxUint64) @@ -207,17 +181,9 @@ func benchmarkRunLocksGC(b *testing.B, backendName string) { // GC lock1 because it's the oldest lock being held. staleLocks, err = allocator.RunLocksGC(context.Background(), staleLocks) require.NoError(b, err) - switch backendName { - case "consul": - // Contrary to etcd, consul does not create a lock in the kvstore - // if a lock is already being held. So we have GCed the only lock - // available. - require.Len(b, staleLocks, 0) - case "etcd": - // There are 2 clients trying to get the lock, we have GC one of them - // so that is way we have 1 staleLock in the map. - require.Len(b, staleLocks, 1) - } + // There are 2 clients trying to get the lock, we have GC one of them + // so that is way we have 1 staleLock in the map. + require.Len(b, staleLocks, 1) // Wait until lock2 is gotten as it should have happen since we have // GC lock1. @@ -236,12 +202,8 @@ func benchmarkRunLocksGC(b *testing.B, backendName string) { func BenchmarkGC(b *testing.B) { testutils.IntegrationTest(b) - for _, backendName := range []string{"etcd", "consul"} { - b.Run(backendName, func(b *testing.B) { - kvstore.SetupDummyWithConfigOpts(b, backendName, opts(backendName)) - benchmarkGC(b) - }) - } + kvstore.SetupDummyWithConfigOpts(b, "etcd", etcdOpts) + benchmarkGC(b) } func benchmarkGC(b *testing.B) { @@ -295,12 +257,8 @@ func benchmarkGC(b *testing.B) { func BenchmarkGCShouldSkipOutOfRangeIdentities(b *testing.B) { testutils.IntegrationTest(b) - for _, backendName := range []string{"etcd", "consul"} { - b.Run(backendName, func(b *testing.B) { - kvstore.SetupDummyWithConfigOpts(b, backendName, opts(backendName)) - benchmarkGCShouldSkipOutOfRangeIdentities(b) - }) - } + kvstore.SetupDummyWithConfigOpts(b, "etcd", etcdOpts) + benchmarkGCShouldSkipOutOfRangeIdentities(b) } func benchmarkGCShouldSkipOutOfRangeIdentities(b *testing.B) { @@ -378,12 +336,8 @@ func benchmarkGCShouldSkipOutOfRangeIdentities(b *testing.B) { func TestAllocateCached(t *testing.T) { testutils.IntegrationTest(t) - for _, backendName := range []string{"etcd", "consul"} { - t.Run(backendName, func(t *testing.T) { - kvstore.SetupDummyWithConfigOpts(t, backendName, opts(backendName)) - testAllocatorCached(t, idpool.ID(32), randomTestName()) // enable use of local cache - }) - } + kvstore.SetupDummyWithConfigOpts(t, "etcd", etcdOpts) + testAllocatorCached(t, idpool.ID(32), randomTestName()) // enable use of local cache } func testAllocatorCached(t *testing.T, maxID idpool.ID, allocatorName string) { @@ -476,12 +430,8 @@ func testAllocatorCached(t *testing.T, maxID idpool.ID, allocatorName string) { func TestKeyToID(t *testing.T) { testutils.IntegrationTest(t) - for _, backendName := range []string{"etcd", "consul"} { - t.Run(backendName, func(t *testing.T) { - kvstore.SetupDummyWithConfigOpts(t, backendName, opts(backendName)) - testKeyToID(t) - }) - } + kvstore.SetupDummyWithConfigOpts(t, "etcd", etcdOpts) + testKeyToID(t) } func testKeyToID(t *testing.T) { @@ -511,12 +461,8 @@ func testKeyToID(t *testing.T) { func TestGetNoCache(t *testing.T) { testutils.IntegrationTest(t) - for _, backendName := range []string{"etcd", "consul"} { - t.Run(backendName, func(t *testing.T) { - kvstore.SetupDummyWithConfigOpts(t, backendName, opts(backendName)) - testGetNoCache(t, idpool.ID(256)) - }) - } + kvstore.SetupDummyWithConfigOpts(t, "etcd", etcdOpts) + testGetNoCache(t, idpool.ID(256)) } func testGetNoCache(t *testing.T, maxID idpool.ID) { @@ -599,12 +545,8 @@ func TestPrefixMatchesKey(t *testing.T) { func TestRemoteCache(t *testing.T) { testutils.IntegrationTest(t) - for _, backendName := range []string{"etcd", "consul"} { - t.Run(backendName, func(t *testing.T) { - kvstore.SetupDummyWithConfigOpts(t, backendName, opts(backendName)) - testRemoteCache(t) - }) - } + kvstore.SetupDummyWithConfigOpts(t, "etcd", etcdOpts) + testRemoteCache(t) } func testRemoteCache(t *testing.T) { @@ -698,12 +640,3 @@ func testRemoteCache(t *testing.T) { require.Equal(t, 2, cache[i]) } } - -func opts(backendName string) map[string]string { - if backendName == "etcd" { - // Explicitly set higher QPS than the default to speedup the test - return map[string]string{kvstore.EtcdRateLimitOption: "100"} - } - - return nil -} diff --git a/pkg/kvstore/allocator/doublewrite/backend.go b/pkg/kvstore/allocator/doublewrite/backend.go index d71dcf514c52f..c597a974d9a94 100644 --- a/pkg/kvstore/allocator/doublewrite/backend.go +++ b/pkg/kvstore/allocator/doublewrite/backend.go @@ -262,6 +262,5 @@ func (d *doubleWriteBackend) Status() (string, error) { func (d *doubleWriteBackend) Encode(v string) string { // Works for both CRD and etcd as the KVStore. - // Note that this is not compatible with Consul as the KVStore. return v } diff --git a/pkg/kvstore/base_test.go b/pkg/kvstore/base_test.go index cecba5579677e..9a9e11346d999 100644 --- a/pkg/kvstore/base_test.go +++ b/pkg/kvstore/base_test.go @@ -14,14 +14,14 @@ import ( "github.com/cilium/cilium/pkg/testutils" ) +var ( + etcdOpts = map[string]string{EtcdRateLimitOption: "100"} +) + func TestLock(t *testing.T) { testutils.IntegrationTest(t) - for _, backendName := range []string{"etcd", "consul"} { - t.Run(backendName, func(t *testing.T) { - SetupDummyWithConfigOpts(t, backendName, opts(backendName)) - testLock(t) - }) - } + SetupDummyWithConfigOpts(t, "etcd", etcdOpts) + testLock(t) } func testLock(t *testing.T) { @@ -48,12 +48,8 @@ func testValue(i int) string { func TestGetSet(t *testing.T) { testutils.IntegrationTest(t) - for _, backendName := range []string{"etcd", "consul"} { - t.Run(backendName, func(t *testing.T) { - SetupDummyWithConfigOpts(t, backendName, opts(backendName)) - testGetSet(t) - }) - } + SetupDummyWithConfigOpts(t, "etcd", etcdOpts) + testGetSet(t) } func testGetSet(t *testing.T) { @@ -98,12 +94,8 @@ func testGetSet(t *testing.T) { func BenchmarkGet(b *testing.B) { testutils.IntegrationTest(b) - for _, backendName := range []string{"etcd", "consul"} { - b.Run(backendName, func(b *testing.B) { - SetupDummyWithConfigOpts(b, backendName, opts(backendName)) - benchmarkGet(b) - }) - } + SetupDummyWithConfigOpts(b, "etcd", etcdOpts) + benchmarkGet(b) } func benchmarkGet(b *testing.B) { @@ -123,12 +115,8 @@ func benchmarkGet(b *testing.B) { func BenchmarkSet(b *testing.B) { testutils.IntegrationTest(b) - for _, backendName := range []string{"etcd", "consul"} { - b.Run(backendName, func(b *testing.B) { - SetupDummyWithConfigOpts(b, backendName, opts(backendName)) - benchmarkSet(b) - }) - } + SetupDummyWithConfigOpts(b, "etcd", etcdOpts) + benchmarkSet(b) } func benchmarkSet(b *testing.B) { @@ -145,12 +133,8 @@ func benchmarkSet(b *testing.B) { func TestUpdate(t *testing.T) { testutils.IntegrationTest(t) - for _, backendName := range []string{"etcd", "consul"} { - t.Run(backendName, func(t *testing.T) { - SetupDummyWithConfigOpts(t, backendName, opts(backendName)) - testUpdate(t) - }) - } + SetupDummyWithConfigOpts(t, "etcd", etcdOpts) + testUpdate(t) } func testUpdate(t *testing.T) { @@ -176,12 +160,8 @@ func testUpdate(t *testing.T) { func TestCreateOnly(t *testing.T) { testutils.IntegrationTest(t) - for _, backendName := range []string{"etcd", "consul"} { - t.Run(backendName, func(t *testing.T) { - SetupDummyWithConfigOpts(t, backendName, opts(backendName)) - testCreateOnly(t) - }) - } + SetupDummyWithConfigOpts(t, "etcd", etcdOpts) + testCreateOnly(t) } func testCreateOnly(t *testing.T) { @@ -214,11 +194,7 @@ func expectEvent(t *testing.T, w *Watcher, typ EventType, key string, val string if event.Typ != EventTypeListDone { require.EqualValues(t, key, event.Key) - - // etcd does not provide the value of deleted keys - if selectedModule == "consul" { - require.EqualValues(t, val, event.Value) - } + // etcd does not provide the value of deleted keys so we can't check it. } case <-time.After(10 * time.Second): t.Fatal("timeout while waiting for kvstore watcher event") @@ -227,12 +203,8 @@ func expectEvent(t *testing.T, w *Watcher, typ EventType, key string, val string func TestListAndWatch(t *testing.T) { testutils.IntegrationTest(t) - for _, backendName := range []string{"etcd", "consul"} { - t.Run(backendName, func(t *testing.T) { - SetupDummyWithConfigOpts(t, backendName, opts(backendName)) - testListAndWatch(t) - }) - } + SetupDummyWithConfigOpts(t, "etcd", etcdOpts) + testListAndWatch(t) } func testListAndWatch(t *testing.T) { @@ -276,12 +248,3 @@ func testListAndWatch(t *testing.T) { w.Stop() } - -func opts(backendName string) map[string]string { - if backendName == "etcd" { - // Explicitly set higher QPS than the default to speedup the test - return map[string]string{EtcdRateLimitOption: "100"} - } - - return nil -} diff --git a/pkg/kvstore/config.go b/pkg/kvstore/config.go index 7e85d4f0669e8..401c0c2c99e48 100644 --- a/pkg/kvstore/config.go +++ b/pkg/kvstore/config.go @@ -11,11 +11,6 @@ import ( "github.com/cilium/cilium/pkg/logging/logfields" ) -var ( - // selectedModule is the name of the selected backend module - selectedModule string -) - // setOpts validates the specified options against the selected backend and // then modifies the configuration func setOpts(opts map[string]string, supportedOpts backendOptions) error { @@ -85,8 +80,6 @@ func setup(ctx context.Context, selectedBackend string, opts map[string]string, return err } - selectedModule = module.getName() - return initClient(ctx, module, goOpts) } diff --git a/pkg/kvstore/consul.go b/pkg/kvstore/consul.go deleted file mode 100644 index 7af1e8941a03b..0000000000000 --- a/pkg/kvstore/consul.go +++ /dev/null @@ -1,701 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package kvstore - -import ( - "bytes" - "context" - "encoding/base64" - "errors" - "fmt" - "os" - "strings" - - consulAPI "github.com/hashicorp/consul/api" - "github.com/sirupsen/logrus" - "gopkg.in/yaml.v3" - - "github.com/cilium/cilium/pkg/backoff" - "github.com/cilium/cilium/pkg/controller" - "github.com/cilium/cilium/pkg/inctimer" - "github.com/cilium/cilium/pkg/lock" - "github.com/cilium/cilium/pkg/logging/logfields" - "github.com/cilium/cilium/pkg/option" - "github.com/cilium/cilium/pkg/spanstat" - "github.com/cilium/cilium/pkg/time" -) - -const ( - consulName = "consul" - - // ConsulAddrOption is the string representing the key mapping to the value of the - // address for Consul. - ConsulAddrOption = "consul.address" - ConsulOptionConfig = "consul.tlsconfig" - - // maxLockRetries is the number of retries attempted when acquiring a lock - maxLockRetries = 10 -) - -type consulModule struct { - opts backendOptions - config *consulAPI.Config -} - -var ( - // consulDummyAddress can be overwritten from test invokers using ldflags - consulDummyAddress = "https://127.0.0.1:8501" - // consulDummyConfigFile can be overwritten from test invokers using ldflags - consulDummyConfigFile = "/tmp/cilium-consul-certs/cilium-consul.yaml" - - module = newConsulModule() - - // ErrNotImplemented is the error which is returned when a functionality is not implemented. - ErrNotImplemented = errors.New("not implemented") - - consulLeaseKeepaliveControllerGroup = controller.NewGroup("consul-lease-keepalive") -) - -func init() { - // register consul module for use - registerBackend(consulName, module) -} - -func newConsulModule() backendModule { - return &consulModule{ - opts: backendOptions{ - ConsulAddrOption: &backendOption{ - description: "Addresses of consul cluster", - }, - ConsulOptionConfig: &backendOption{ - description: "Path to consul tls configuration file", - }, - }, - } -} - -func ConsulDummyAddress() string { - return consulDummyAddress -} - -func ConsulDummyConfigFile() string { - return consulDummyConfigFile -} - -func (c *consulModule) createInstance() backendModule { - return newConsulModule() -} - -func (c *consulModule) getName() string { - return consulName -} - -func (c *consulModule) setConfigDummy() { - c.config = consulAPI.DefaultConfig() - c.config.Address = consulDummyAddress - yc := consulAPI.TLSConfig{} - b, err := os.ReadFile(consulDummyConfigFile) - if err != nil { - log.WithError(err).Warnf("unable to read consul tls configuration file %s", consulDummyConfigFile) - } - - err = yaml.Unmarshal(b, &yc) - if err != nil { - log.WithError(err).Warnf("invalid consul tls configuration in %s", consulDummyConfigFile) - } - - c.config.TLSConfig = yc -} - -func (c *consulModule) setConfig(opts map[string]string) error { - return setOpts(opts, c.opts) -} - -func (c *consulModule) setExtraConfig(opts *ExtraOptions) error { - return nil -} - -func (c *consulModule) getConfig() map[string]string { - return getOpts(c.opts) -} - -func (c *consulModule) newClient(ctx context.Context, opts *ExtraOptions) (BackendOperations, chan error) { - log.WithFields(logrus.Fields{ - logfields.URL: "https://slack.cilium.io", - }).Warning("Support for Consul as a kvstore backend has been deprecated due to lack of maintainers. If you are interested in helping to maintain Consul support in Cilium, please reach out on GitHub or the official Cilium slack") - - errChan := make(chan error, 1) - backend, err := c.connectConsulClient(ctx, opts) - if err != nil { - errChan <- err - } - close(errChan) - return backend, errChan -} - -func (c *consulModule) connectConsulClient(ctx context.Context, opts *ExtraOptions) (BackendOperations, error) { - if c.config == nil { - consulAddr, consulAddrSet := c.opts[ConsulAddrOption] - configPathOpt, configPathOptSet := c.opts[ConsulOptionConfig] - if !consulAddrSet { - return nil, fmt.Errorf("invalid consul configuration, please specify %s option", ConsulAddrOption) - } - - if consulAddr.value == "" { - return nil, fmt.Errorf("invalid consul configuration, please specify %s option", ConsulAddrOption) - } - - addr := consulAddr.value - c.config = consulAPI.DefaultConfig() - if configPathOptSet && configPathOpt.value != "" { - b, err := os.ReadFile(configPathOpt.value) - if err != nil { - return nil, fmt.Errorf("unable to read consul tls configuration file %s: %w", configPathOpt.value, err) - } - yc := consulAPI.TLSConfig{} - err = yaml.Unmarshal(b, &yc) - if err != nil { - return nil, fmt.Errorf("invalid consul tls configuration in %s: %w", configPathOpt.value, err) - } - c.config.TLSConfig = yc - } - - c.config.Address = addr - - } - client, err := newConsulClient(ctx, c.config, opts) - if err != nil { - return nil, err - } - - return client, nil -} - -var ( - maxRetries = 30 -) - -type consulClient struct { - *consulAPI.Client - lease string - controllers *controller.Manager - extraOptions *ExtraOptions - disconnectedMu lock.RWMutex - disconnected chan struct{} - statusCheckErrors chan error -} - -func newConsulClient(ctx context.Context, config *consulAPI.Config, opts *ExtraOptions) (BackendOperations, error) { - var ( - c *consulAPI.Client - err error - ) - if config != nil { - c, err = consulAPI.NewClient(config) - } else { - c, err = consulAPI.NewClient(consulAPI.DefaultConfig()) - } - if err != nil { - return nil, err - } - - boff := backoff.Exponential{Min: time.Duration(100) * time.Millisecond} - - for i := 0; i < maxRetries; i++ { - var leader string - leader, err = c.Status().Leader() - - if err == nil { - if leader != "" { - // happy path - break - } else { - err = errors.New("timeout while waiting for leader to be elected") - } - } - log.Info("Waiting for consul to elect a leader") - boff.Wait(ctx) - } - - if err != nil { - log.WithError(err).Fatal("Unable to contact consul server") - } - - entry := &consulAPI.SessionEntry{ - TTL: fmt.Sprintf("%ds", int(option.Config.KVstoreLeaseTTL.Seconds())), - Behavior: consulAPI.SessionBehaviorDelete, - } - - wo := &consulAPI.WriteOptions{} - lease, _, err := c.Session().Create(entry, wo.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("unable to create default lease: %w", err) - } - - client := &consulClient{ - Client: c, - lease: lease, - controllers: controller.NewManager(), - extraOptions: opts, - disconnected: make(chan struct{}), - statusCheckErrors: make(chan error, 128), - } - - client.controllers.UpdateController( - fmt.Sprintf("consul-lease-keepalive-%p", c), - controller.ControllerParams{ - Group: consulLeaseKeepaliveControllerGroup, - DoFunc: func(ctx context.Context) error { - wo := &consulAPI.WriteOptions{} - _, _, err := c.Session().Renew(lease, wo.WithContext(ctx)) - if err != nil { - // consider disconnected! - client.disconnectedMu.Lock() - close(client.disconnected) - client.disconnected = make(chan struct{}) - client.disconnectedMu.Unlock() - } - return err - }, - RunInterval: option.Config.KVstoreKeepAliveInterval, - }, - ) - - return client, nil -} - -type ConsulLocker struct { - *consulAPI.Lock -} - -func (cl *ConsulLocker) Unlock(ctx context.Context) error { - return cl.Lock.Unlock() -} - -func (cl *ConsulLocker) Comparator() interface{} { - return nil -} - -func (c *consulClient) LockPath(ctx context.Context, path string) (KVLocker, error) { - lockKey, err := c.LockOpts(&consulAPI.LockOptions{Key: getLockPath(path)}) - if err != nil { - return nil, err - } - - for retries := 0; retries < maxLockRetries; retries++ { - ch, err := lockKey.Lock(nil) - switch { - case err != nil: - return nil, err - case ch == nil: - Trace("Acquiring lock timed out, retrying", nil, logrus.Fields{fieldKey: path, logfields.Attempt: retries}) - default: - return &ConsulLocker{Lock: lockKey}, err - } - - select { - case <-ctx.Done(): - return nil, fmt.Errorf("lock cancelled via context: %w", ctx.Err()) - default: - } - } - - return nil, fmt.Errorf("maximum retries (%d) reached", maxLockRetries) -} - -// watch starts watching for changes in a prefix -func (c *consulClient) watch(ctx context.Context, w *Watcher) { - scope := GetScopeFromKey(strings.TrimRight(w.Prefix, "/")) - // Last known state of all KVPairs matching the prefix - localState := map[string]consulAPI.KVPair{} - nextIndex := uint64(0) - - q := &consulAPI.QueryOptions{ - WaitTime: time.Second, - } - - qo := q.WithContext(ctx) - - sleepTimer, sleepTimerDone := inctimer.New() - defer sleepTimerDone() - - for { - // Initialize sleep time to a millisecond as we don't - // want to sleep in between successful watch cycles - sleepTime := 1 * time.Millisecond - - qo.WaitIndex = nextIndex - pairs, q, err := c.KV().List(w.Prefix, qo) - if err != nil { - sleepTime = 5 * time.Second - Trace("List of Watch failed", err, logrus.Fields{fieldPrefix: w.Prefix}) - } - - if q != nil { - nextIndex = q.LastIndex - } - - // timeout while watching for changes, re-schedule - if qo.WaitIndex != 0 && (q == nil || q.LastIndex == qo.WaitIndex) { - goto wait - } - - for _, newPair := range pairs { - oldPair, ok := localState[newPair.Key] - - // Keys reported for the first time must be new - if !ok { - if newPair.CreateIndex != newPair.ModifyIndex { - log.Debugf("consul: Previously unknown key %s received with CreateIndex(%d) != ModifyIndex(%d)", - newPair.Key, newPair.CreateIndex, newPair.ModifyIndex) - } - - queueStart := spanstat.Start() - w.Events <- KeyValueEvent{ - Typ: EventTypeCreate, - Key: newPair.Key, - Value: newPair.Value, - } - trackEventQueued(scope, EventTypeCreate, queueStart.End(true).Total()) - } else if oldPair.ModifyIndex != newPair.ModifyIndex { - queueStart := spanstat.Start() - w.Events <- KeyValueEvent{ - Typ: EventTypeModify, - Key: newPair.Key, - Value: newPair.Value, - } - trackEventQueued(scope, EventTypeModify, queueStart.End(true).Total()) - } - - // Everything left on localState will be assumed to - // have been deleted, therefore remove all keys in - // localState that still exist in the kvstore - delete(localState, newPair.Key) - } - - for k, deletedPair := range localState { - queueStart := spanstat.Start() - w.Events <- KeyValueEvent{ - Typ: EventTypeDelete, - Key: deletedPair.Key, - Value: deletedPair.Value, - } - trackEventQueued(scope, EventTypeDelete, queueStart.End(true).Total()) - delete(localState, k) - } - - for _, newPair := range pairs { - localState[newPair.Key] = *newPair - - } - - // Initial list operation has been completed, signal this - if qo.WaitIndex == 0 { - w.Events <- KeyValueEvent{Typ: EventTypeListDone} - } - - wait: - select { - case <-sleepTimer.After(sleepTime): - case <-w.stopWatch: - close(w.Events) - w.stopWait.Done() - return - } - } -} - -func (c *consulClient) waitForInitLock(ctx context.Context) <-chan struct{} { - initLockSucceeded := make(chan struct{}) - - go func() { - for { - locker, err := c.LockPath(ctx, InitLockPath) - if err == nil { - locker.Unlock(context.Background()) - close(initLockSucceeded) - log.Info("Distributed lock successful, consul has quorum") - return - } - - time.Sleep(100 * time.Millisecond) - } - }() - - return initLockSucceeded -} - -// Connected closes the returned channel when the consul client is connected. -func (c *consulClient) Connected(ctx context.Context) <-chan error { - ch := make(chan error) - go func() { - for { - qo := &consulAPI.QueryOptions{} - // TODO find out if there's a better way to do this for consul - _, _, err := c.Session().Info(c.lease, qo.WithContext(ctx)) - if err == nil { - break - } - time.Sleep(100 * time.Millisecond) - } - <-c.waitForInitLock(ctx) - close(ch) - }() - return ch -} - -// Disconnected closes the returned channel when consul detects the client -// is disconnected from the server. -func (c *consulClient) Disconnected() <-chan struct{} { - c.disconnectedMu.RLock() - ch := c.disconnected - c.disconnectedMu.RUnlock() - return ch -} - -func (c *consulClient) Status() (string, error) { - leader, err := c.Client.Status().Leader() - return "Consul: " + leader, err -} - -func (c *consulClient) DeletePrefix(ctx context.Context, path string) (err error) { - defer func() { Trace("DeletePrefix", err, logrus.Fields{fieldPrefix: path}) }() - - duration := spanstat.Start() - wo := &consulAPI.WriteOptions{} - _, err = c.Client.KV().DeleteTree(path, wo.WithContext(ctx)) - increaseMetric(path, metricDelete, "DeletePrefix", duration.EndError(err).Total(), err) - return err -} - -// DeleteIfLocked deletes a key if the client is still holding the given lock. -func (c *consulClient) DeleteIfLocked(ctx context.Context, key string, lock KVLocker) (err error) { - defer func() { Trace("DeleteIfLocked", err, logrus.Fields{fieldKey: key}) }() - return c.delete(ctx, key) -} - -// Delete deletes a key -func (c *consulClient) Delete(ctx context.Context, key string) (err error) { - defer func() { Trace("Delete", err, logrus.Fields{fieldKey: key}) }() - return c.delete(ctx, key) -} - -func (c *consulClient) delete(ctx context.Context, key string) error { - duration := spanstat.Start() - wo := &consulAPI.WriteOptions{} - _, err := c.KV().Delete(key, wo.WithContext(ctx)) - increaseMetric(key, metricDelete, "Delete", duration.EndError(err).Total(), err) - return err -} - -// GetIfLocked returns value of key if the client is still holding the given lock. -func (c *consulClient) GetIfLocked(ctx context.Context, key string, lock KVLocker) (bv []byte, err error) { - defer func() { Trace("GetIfLocked", err, logrus.Fields{fieldKey: key, fieldValue: string(bv)}) }() - return c.Get(ctx, key) -} - -// Get returns value of key -func (c *consulClient) Get(ctx context.Context, key string) (bv []byte, err error) { - defer func() { Trace("Get", err, logrus.Fields{fieldKey: key, fieldValue: string(bv)}) }() - - duration := spanstat.Start() - qo := &consulAPI.QueryOptions{} - pair, _, err := c.KV().Get(key, qo.WithContext(ctx)) - increaseMetric(key, metricRead, "Get", duration.EndError(err).Total(), err) - if err != nil { - return nil, err - } - if pair == nil { - return nil, nil - } - return pair.Value, nil -} - -// UpdateIfLocked updates a key if the client is still holding the given lock. -func (c *consulClient) UpdateIfLocked(ctx context.Context, key string, value []byte, lease bool, lock KVLocker) error { - return c.Update(ctx, key, value, lease) -} - -// Update creates or updates a key with the value -func (c *consulClient) Update(ctx context.Context, key string, value []byte, lease bool) (err error) { - defer func() { - Trace("Update", err, logrus.Fields{fieldKey: key, fieldValue: string(value), fieldAttachLease: lease}) - }() - - k := &consulAPI.KVPair{Key: key, Value: value} - - if lease { - k.Session = c.lease - } - - opts := &consulAPI.WriteOptions{} - - duration := spanstat.Start() - _, err = c.KV().Put(k, opts.WithContext(ctx)) - increaseMetric(key, metricSet, "Update", duration.EndError(err).Total(), err) - return err -} - -// UpdateIfDifferentIfLocked updates a key if the value is different and if the client is still holding the given lock. -func (c *consulClient) UpdateIfDifferentIfLocked(ctx context.Context, key string, value []byte, lease bool, lock KVLocker) (recreated bool, err error) { - defer func() { - Trace("UpdateIfDifferentIfLocked", err, logrus.Fields{fieldKey: key, fieldValue: value, fieldAttachLease: lease, "recreated": recreated}) - }() - - return c.updateIfDifferent(ctx, key, value, lease) -} - -// UpdateIfDifferent updates a key if the value is different -func (c *consulClient) UpdateIfDifferent(ctx context.Context, key string, value []byte, lease bool) (recreated bool, err error) { - defer func() { - Trace("UpdateIfDifferent", err, logrus.Fields{fieldKey: key, fieldValue: value, fieldAttachLease: lease, "recreated": recreated}) - }() - - return c.updateIfDifferent(ctx, key, value, lease) -} - -func (c *consulClient) updateIfDifferent(ctx context.Context, key string, value []byte, lease bool) (bool, error) { - duration := spanstat.Start() - qo := &consulAPI.QueryOptions{} - getR, _, err := c.KV().Get(key, qo.WithContext(ctx)) - increaseMetric(key, metricRead, "Get", duration.EndError(err).Total(), err) - // On error, attempt update blindly - if err != nil || getR == nil { - return true, c.Update(ctx, key, value, lease) - } - - if lease && getR.Session != c.lease { - return true, c.Update(ctx, key, value, lease) - } - - // if lease is different and value is not equal then update. - if !bytes.Equal(getR.Value, value) { - return true, c.Update(ctx, key, value, lease) - } - - return false, nil -} - -// CreateOnlyIfLocked atomically creates a key if the client is still holding the given lock or fails if it already exists -func (c *consulClient) CreateOnlyIfLocked(ctx context.Context, key string, value []byte, lease bool, lock KVLocker) (success bool, err error) { - defer func() { - Trace("CreateOnlyIfLocked", err, logrus.Fields{fieldKey: key, fieldValue: value, fieldAttachLease: lease, "success": success}) - }() - return c.createOnly(ctx, key, value, lease) -} - -// CreateOnly creates a key with the value and will fail if the key already exists -func (c *consulClient) CreateOnly(ctx context.Context, key string, value []byte, lease bool) (success bool, err error) { - defer func() { - Trace("CreateOnly", err, logrus.Fields{fieldKey: key, fieldValue: value, fieldAttachLease: lease, "success": success}) - }() - - return c.createOnly(ctx, key, value, lease) -} - -func (c *consulClient) createOnly(ctx context.Context, key string, value []byte, lease bool) (bool, error) { - k := &consulAPI.KVPair{ - Key: key, - Value: value, - CreateIndex: 0, - } - - if lease { - k.Session = c.lease - } - opts := &consulAPI.WriteOptions{} - - duration := spanstat.Start() - success, _, err := c.KV().CAS(k, opts.WithContext(ctx)) - increaseMetric(key, metricSet, "CreateOnly", duration.EndError(err).Total(), err) - if err != nil { - return false, fmt.Errorf("unable to compare-and-swap: %w", err) - } - return success, nil -} - -// ListPrefixIfLocked returns a list of keys matching the prefix only if the client is still holding the given lock. -func (c *consulClient) ListPrefixIfLocked(ctx context.Context, prefix string, lock KVLocker) (v KeyValuePairs, err error) { - defer func() { Trace("ListPrefixIfLocked", err, logrus.Fields{fieldPrefix: prefix, fieldNumEntries: len(v)}) }() - return c.listPrefix(ctx, prefix) -} - -// ListPrefix returns a map of matching keys -func (c *consulClient) ListPrefix(ctx context.Context, prefix string) (v KeyValuePairs, err error) { - defer func() { Trace("ListPrefix", err, logrus.Fields{fieldPrefix: prefix, fieldNumEntries: len(v)}) }() - return c.listPrefix(ctx, prefix) -} - -func (c *consulClient) listPrefix(ctx context.Context, prefix string) (KeyValuePairs, error) { - duration := spanstat.Start() - qo := &consulAPI.QueryOptions{} - pairs, _, err := c.KV().List(prefix, qo.WithContext(ctx)) - increaseMetric(prefix, metricRead, "ListPrefix", duration.EndError(err).Total(), err) - if err != nil { - return nil, err - } - - p := KeyValuePairs(make(map[string]Value, len(pairs))) - for i := 0; i < len(pairs); i++ { - p[pairs[i].Key] = Value{ - Data: pairs[i].Value, - ModRevision: pairs[i].ModifyIndex, - SessionID: pairs[i].Session, - } - } - - return p, nil -} - -// Close closes the consul session -func (c *consulClient) Close() { - close(c.statusCheckErrors) - if c.controllers != nil { - c.controllers.RemoveAll() - } - if c.lease != "" { - c.Session().Destroy(c.lease, nil) - } -} - -// Encode encodes a binary slice into a character set that the backend supports -func (c *consulClient) Encode(in []byte) (out string) { - defer func() { Trace("Encode", nil, logrus.Fields{"in": in, "out": out}) }() - return base64.URLEncoding.EncodeToString([]byte(in)) -} - -// Decode decodes a key previously encoded back into the original binary slice -func (c *consulClient) Decode(in string) (out []byte, err error) { - defer func() { Trace("Decode", err, logrus.Fields{"in": in, "out": out}) }() - return base64.URLEncoding.DecodeString(in) -} - -// ListAndWatch implements the BackendOperations.ListAndWatch using consul -func (c *consulClient) ListAndWatch(ctx context.Context, prefix string, chanSize int) *Watcher { - w := newWatcher(prefix, chanSize) - - log.WithField(fieldPrefix, prefix).Debug("Starting watcher...") - - go c.watch(ctx, w) - - return w -} - -// StatusCheckErrors returns a channel which receives status check errors -func (c *consulClient) StatusCheckErrors() <-chan error { - return c.statusCheckErrors -} - -// RegisterLeaseExpiredObserver is not implemented for the consul backend -func (c *consulClient) RegisterLeaseExpiredObserver(prefix string, fn func(key string)) {} - -// UserEnforcePresence is not implemented for the consul backend -func (c *consulClient) UserEnforcePresence(ctx context.Context, name string, roles []string) error { - return ErrNotImplemented -} - -// UserEnforceAbsence is not implemented for the consul backend -func (c *consulClient) UserEnforceAbsence(ctx context.Context, name string) error { - return ErrNotImplemented -} diff --git a/pkg/kvstore/consul_test.go b/pkg/kvstore/consul_test.go deleted file mode 100644 index fa674f117afb1..0000000000000 --- a/pkg/kvstore/consul_test.go +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package kvstore - -import ( - "context" - "io" - "net/http" - "os" - "testing" - "time" - - consulAPI "github.com/hashicorp/consul/api" - - "github.com/cilium/cilium/pkg/testutils" -) - -var handler http.HandlerFunc - -func TestMain(m *testing.M) { - if !testutils.IntegrationTests() { - // Immediately run the test suite without manipulating the environment - // if integration tests are not requested. - os.Exit(m.Run()) - } - - mux := http.NewServeMux() - // path is hardcoded in consul - mux.HandleFunc("/v1/status/leader", func(w http.ResponseWriter, r *http.Request) { - handler(w, r) - }) - - mux.HandleFunc("/v1/session/create", func(w http.ResponseWriter, r *http.Request) { - io.WriteString(w, "{ \"ID\": \"adf4238a-882b-9ddc-4a9d-5b6758e4159e\"}") - }) - - // /v1/session/renew/{uuid} does not need to be handled for the basic - // test to succeed - - srv := &http.Server{ - Addr: ":8000", - Handler: mux, - } - - go srv.ListenAndServe() - - os.Exit(m.Run()) -} - -func TestConsulClientOk(t *testing.T) { - testutils.IntegrationTest(t) - - maxRetries = 3 - doneC := make(chan struct{}) - - handler = func(w http.ResponseWriter, _ *http.Request) { - io.WriteString(w, "\"nanananananananananleaaderrrr\"") - close(doneC) - } - - //exhaustruct:ignore // Consul API configuration does not need to be fully specified. - _, err := newConsulClient(context.TODO(), &consulAPI.Config{ - Address: ":8000", - }, nil) - - select { - case <-doneC: - case <-time.After(time.Second * 5): - t.Log("timeout") - t.FailNow() - } - - // we should not get a failure - if err != nil { - t.Log("error:" + err.Error()) - t.FailNow() - } -} diff --git a/pkg/kvstore/etcd_lease_test.go b/pkg/kvstore/etcd_lease_test.go index aac45efcf697c..dbf0dea8a9fca 100644 --- a/pkg/kvstore/etcd_lease_test.go +++ b/pkg/kvstore/etcd_lease_test.go @@ -5,6 +5,7 @@ package kvstore import ( "context" + "errors" "fmt" "sort" "testing" @@ -15,6 +16,11 @@ import ( client "go.etcd.io/etcd/client/v3" ) +var ( + // ErrNotImplemented is the error which is returned when a functionality is not implemented. + ErrNotImplemented = errors.New("not implemented") +) + type fakeEtcdLeaseClient struct { ctx context.Context expectedTTLSeconds int64 diff --git a/pkg/kvstore/etcd_test.go b/pkg/kvstore/etcd_test.go index c81cf3fc63c45..ca3dfb944c5f1 100644 --- a/pkg/kvstore/etcd_test.go +++ b/pkg/kvstore/etcd_test.go @@ -46,7 +46,7 @@ func TestHint(t *testing.T) { func setupEtcdLockedSuite(tb testing.TB) *etcdAPI.Client { testutils.IntegrationTest(tb) - SetupDummyWithConfigOpts(tb, "etcd", opts("etcd")) + SetupDummyWithConfigOpts(tb, "etcd", etcdOpts) // setup client cfg := etcdAPI.Config{} @@ -1426,7 +1426,7 @@ func (kvw *kvWrapper) Get(ctx context.Context, key string, opts ...etcdAPI.OpOpt func TestPaginatedList(t *testing.T) { testutils.IntegrationTest(t) - SetupDummyWithConfigOpts(t, "etcd", opts("etcd")) + SetupDummyWithConfigOpts(t, "etcd", etcdOpts) const prefix = "list/paginated" ctx := context.Background() diff --git a/pkg/kvstore/logfields.go b/pkg/kvstore/logfields.go index 3cef331fe3c90..c272cbb33c9a3 100644 --- a/pkg/kvstore/logfields.go +++ b/pkg/kvstore/logfields.go @@ -11,7 +11,7 @@ import ( var log = logging.DefaultLogger.WithField(logfields.LogSubsys, "kvstore") const ( - // fieldKVStoreModule is the name of the kvstore backend (etcd or consul) + // fieldKVStoreModule is the name of the kvstore backend (etcd) fieldKVStoreModule = "module" // key revision diff --git a/pkg/kvstore/store/store_test.go b/pkg/kvstore/store/store_test.go index 8ca30ba5cb490..2f93287b104ec 100644 --- a/pkg/kvstore/store/store_test.go +++ b/pkg/kvstore/store/store_test.go @@ -89,12 +89,8 @@ func newTestType() Key { func TestStoreCreation(t *testing.T) { testutils.IntegrationTest(t) - for _, backendName := range []string{"etcd", "consul"} { - t.Run(backendName, func(t *testing.T) { - kvstore.SetupDummy(t, backendName) - testStoreCreation(t) - }) - } + kvstore.SetupDummy(t, "etcd") + testStoreCreation(t) } func testStoreCreation(t *testing.T) { @@ -125,12 +121,8 @@ func testStoreCreation(t *testing.T) { func TestStoreOperations(t *testing.T) { testutils.IntegrationTest(t) - for _, backendName := range []string{"etcd", "consul"} { - t.Run(backendName, func(t *testing.T) { - kvstore.SetupDummy(t, backendName) - testStoreOperations(t) - }) - } + kvstore.SetupDummy(t, "etcd") + testStoreOperations(t) } func testStoreOperations(t *testing.T) { @@ -182,12 +174,8 @@ func testStoreOperations(t *testing.T) { func TestStorePeriodicSync(t *testing.T) { testutils.IntegrationTest(t) - for _, backendName := range []string{"etcd", "consul"} { - t.Run(backendName, func(t *testing.T) { - kvstore.SetupDummy(t, backendName) - testStorePeriodicSync(t) - }) - } + kvstore.SetupDummy(t, "etcd") + testStorePeriodicSync(t) } func testStorePeriodicSync(t *testing.T) { @@ -223,12 +211,8 @@ func testStorePeriodicSync(t *testing.T) { func TestStoreLocalKeyProtection(t *testing.T) { testutils.IntegrationTest(t) - for _, backendName := range []string{"etcd", "consul"} { - t.Run(backendName, func(t *testing.T) { - kvstore.SetupDummy(t, backendName) - testStoreLocalKeyProtection(t) - }) - } + kvstore.SetupDummy(t, "etcd") + testStoreLocalKeyProtection(t) } func testStoreLocalKeyProtection(t *testing.T) { @@ -286,12 +270,8 @@ func setupStoreCollaboration(t *testing.T, storePrefix, keyPrefix string) *Share func TestStoreCollaboration(t *testing.T) { testutils.IntegrationTest(t) - for _, backendName := range []string{"etcd", "consul"} { - t.Run(backendName, func(t *testing.T) { - kvstore.SetupDummy(t, backendName) - testStoreCollaboration(t) - }) - } + kvstore.SetupDummy(t, "etcd") + testStoreCollaboration(t) } func testStoreCollaboration(t *testing.T) { diff --git a/test/consul/ca-config.json b/test/consul/ca-config.json deleted file mode 100644 index bf2410fd136e4..0000000000000 --- a/test/consul/ca-config.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "signing": { - "default": { - "expiry": "43800h" - }, - "profiles": { - "server": { - "expiry": "43800h", - "usages": [ - "signing", - "key encipherment", - "server auth", - "any" - ] - }, - "client": { - "expiry": "43800h", - "usages": [ - "signing", - "key encipherment", - "client auth", - "any" - ] - }, - "peer": { - "expiry": "43800h", - "usages": [ - "signing", - "key encipherment", - "server auth", - "client auth", - "any" - ] - } - } - } -} diff --git a/test/consul/ca-csr.json b/test/consul/ca-csr.json deleted file mode 100644 index bc1a74f549f22..0000000000000 --- a/test/consul/ca-csr.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "CN": "Cilium-consul CA", - "key": { - "algo": "rsa", - "size": 2048 - }, - "names": [ - { - "C": "US", - "L": "CA", - "O": "My Company Name", - "ST": "San Francisco", - "OU": "Org Unit 1" - } - ] -} diff --git a/test/consul/cilium-consul.yaml b/test/consul/cilium-consul.yaml deleted file mode 100644 index 61fde09ceccc0..0000000000000 --- a/test/consul/cilium-consul.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -cafile: '/tmp/cilium-consul-certs/consul-client-ca.crt' -keyfile: '/tmp/cilium-consul-certs/consul-client.key' -certfile: '/tmp/cilium-consul-certs/consul-client.crt' diff --git a/test/consul/consul-client-ca.crt b/test/consul/consul-client-ca.crt deleted file mode 100644 index 2652f6234e020..0000000000000 --- a/test/consul/consul-client-ca.crt +++ /dev/null @@ -1,23 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDyDCCArCgAwIBAgIUZxbQnYUgzPJ2AW395z0WzebcowMwDQYJKoZIhvcNAQEL -BQAwfDELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDVNhbiBGcmFuY2lzY28xCzAJBgNV -BAcTAkNBMRgwFgYDVQQKEw9NeSBDb21wYW55IE5hbWUxEzARBgNVBAsTCk9yZyBV -bml0IDExGTAXBgNVBAMTEENpbGl1bS1jb25zdWwgQ0EwHhcNMjAwNTAyMTQwMTAw -WhcNMjUwNTAxMTQwMTAwWjB8MQswCQYDVQQGEwJVUzEWMBQGA1UECBMNU2FuIEZy -YW5jaXNjbzELMAkGA1UEBxMCQ0ExGDAWBgNVBAoTD015IENvbXBhbnkgTmFtZTET -MBEGA1UECxMKT3JnIFVuaXQgMTEZMBcGA1UEAxMQQ2lsaXVtLWNvbnN1bCBDQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOFo1JPiFcPJPmxnZOado01R -flwNgGAuLfA7Sc39jb3kvbizOl00C5e7PQzoyJRdj27MFWzLlZHDRDxWGNpoNvBo -PuCYzSUddZDSz7YdrtbdEBpC3ST4lnIeyNQvxyBhiZC8O6yhF3hqt8JbWXmGbL87 -3ATpBcfCAcHC6Hobsqno186oKNrC9h1l0hlKVfTszr0dYhVsDds0LrW2KD2wTGfP -RWYcir0jH4LNTXpJnVi233k+X4xCoj8r+EiGGyXt2A2b4EaUjjiUdvflJqLOVOL1 -j1c3kxJZ2cQ6/TrdSvZBel5/tyzVI2vxmS78+qAs9h5C30Q6bSz0eJtoxhV9qEkC -AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFP8SHMD2wUvfb7PTg2xgEsTnR+hiMA0GCSqGSIb3DQEBCwUAA4IBAQCleY2o -4gvXwiFxA29SMaq9OH9/yrQp8Hddt5ROIKC/WWfo19jB2PF21oobDXVcg55FjTZC -VkuVjlG0xOQOeEaUZYLxKt1uJ2H3X6dZvgq0hpvaHkDEbddxNt+tgoTrLM2Tqgmy -Q5XnVJZd5wcPzkXmWQknyNNrS7Bp8GR4K0dq1Y4X3Pu0yq6rX7b8svD2sLZV2PyH -gUTxTxSmTvG+BdgdG47LNgqDTmkgsIQpbaZ4fFENxp4fJUpTOHD6BccqyDbFkuUq -1sJhuYegpv6NIAE0guq7LIb8+flUIw8hZifYh+aajq+keNbVznANkjtBNdDXPiR+ -/JQ/GQmVDYZcnXOg ------END CERTIFICATE----- diff --git a/test/consul/consul-client.crt b/test/consul/consul-client.crt deleted file mode 100644 index 6276981a482b2..0000000000000 --- a/test/consul/consul-client.crt +++ /dev/null @@ -1,24 +0,0 @@ ------BEGIN CERTIFICATE----- -MIID7TCCAtWgAwIBAgIUBGJwgpsvcD1IJUmicJykO/FJSWwwDQYJKoZIhvcNAQEL -BQAwfDELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDVNhbiBGcmFuY2lzY28xCzAJBgNV -BAcTAkNBMRgwFgYDVQQKEw9NeSBDb21wYW55IE5hbWUxEzARBgNVBAsTCk9yZyBV -bml0IDExGTAXBgNVBAMTEENpbGl1bS1jb25zdWwgQ0EwHhcNMjAwNTAyMTQwMTAw -WhcNMjUwNTAxMTQwMTAwWjBKMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNU2FuIEZy -YW5jaXNjbzELMAkGA1UEBxMCQ0ExFjAUBgNVBAMTDWNvbnN1bCBjbGllbnQwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrqbGun0dY1VeDPeitcmNjeSrO -EhqTtbu8y44z1cqH8H3HCOYMmLcVaOPjoFuTlA6o7P1OI8tL9BGaU6zWbR4Cgpo2 -sPpKp3TtRKR8mvabZbislfDZaNrAL8/4BU0WJbxdEy8RDa2uc0JFWGaeAHqC2q2Z -ZEGf08tdMZozJBWv5UtM7J8NZj877NsQOKVQvStxLS0P3fwTgnkKoSklIt26dxB0 -NEa2Wz/dRbSDJ0GD8eAlBYZ4HXcRiN0S5ryHHLrFGTIeMla6RtJ9N12lZk052X3P -OxdrLb6IJD2XF7BhlZI2PiA9dYvCjhyTGZYe30jjWH7GcGNmtmysoDdu/55TAgMB -AAGjgZgwgZUwDgYDVR0PAQH/BAQDAgWgMBkGA1UdJQQSMBAGCCsGAQUFBwMCBgRV -HSUAMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFI2lgWNqHA03rUibcHrkzOYaEMNw -MB8GA1UdIwQYMBaAFP8SHMD2wUvfb7PTg2xgEsTnR+hiMBoGA1UdEQQTMBGCCWxv -Y2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAjx3jrF6J81HcIikA5MVb -KLT5UkUaeeZQ3xPEKVet7Xr1lyA9vf7hcR6YZAWzBtx9jiY1afwrOFetV3AB2Qga -5hrynlX8tqDTqDITjwvM4XgW+DHKQdf1LXec6ei53j+z+HDOp+mPAROpcE5gTleO -NOTmCMSGWMb3/AzbbTmx90eLTFSaMEjyHT6R0sPbcXClXgqvicE7uqMDrcdGuvVK -vCWW0/L89jAq2x6VXG+HzBKHwM9FmW5Ys4UzZUJ+cEQLcVJdCa/7gSG8kSot0xyN -nn3ue54LKoXoQOcKeffZGPHZI3BRywExd0Gn2SBJ1cRauPV2aZX10Jw0Zq0n7t69 -rg== ------END CERTIFICATE----- diff --git a/test/consul/consul-client.json b/test/consul/consul-client.json deleted file mode 100644 index 20da5cb2653ff..0000000000000 --- a/test/consul/consul-client.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "CN": "consul client", - "hosts": [ - "" - ], - "key": { - "algo": "rsa", - "size": 2048 - }, - "names": [ - { - "C": "US", - "L": "CA", - "ST": "San Francisco" - } - ] -} diff --git a/test/consul/consul-client.key b/test/consul/consul-client.key deleted file mode 100644 index 7df99ae3d387c..0000000000000 --- a/test/consul/consul-client.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAq6mxrp9HWNVXgz3orXJjY3kqzhIak7W7vMuOM9XKh/B9xwjm -DJi3FWjj46Bbk5QOqOz9TiPLS/QRmlOs1m0eAoKaNrD6Sqd07USkfJr2m2W4rJXw -2WjawC/P+AVNFiW8XRMvEQ2trnNCRVhmngB6gtqtmWRBn9PLXTGaMyQVr+VLTOyf -DWY/O+zbEDilUL0rcS0tD938E4J5CqEpJSLduncQdDRGtls/3UW0gydBg/HgJQWG -eB13EYjdEua8hxy6xRkyHjJWukbSfTddpWZNOdl9zzsXay2+iCQ9lxewYZWSNj4g -PXWLwo4ckxmWHt9I41h+xnBjZrZsrKA3bv+eUwIDAQABAoIBAQCm508C4YqVLJjx -2feo7FcGGIEt6xw8Ea5/WcrhSzSoB4PDSTujc7hO8LTiVL+1NXcrd4CxwMuhBaU3 -z7N0qJNNDX6zPk+c1kQxjVQAcwri/HwaEY8jU3ec9N/X3g+dQQNr24MfqZT80MPW -eKUNapmzMLspMPk9VMedzOSIZMVRRp+WLkVAXnPt/w1+ax5QB3pK4cXd/AhqtW6D -RJbigFwf5M8BHWau3dpGj7R9/Nfw6Y/sJK8NWVZELnKk8RLjPPH8/FUNWjfdQmo5 -V8p8zKxgd42a5BAWBEF7RbhszwKdSqoj58ttHZDk4g3m8RkKxMjcSKMTWVTVzfOW -dlif3iTBAoGBAMqe/U79r4WXCb8hdcSV02LEJf6PYQ6s4fSmIRSNXgSwu1mZQeBK -ZLLL1M0cg4CxjH0hBTg7qBo3Nl9dj24OWbqsUkvYxOTeNTNXEvk3uPIZv2SMpqfi -NPcx/hmhMMGY+iDoidSdXn0HhZgoAFE9vOIlvWtfq3m0NqrP2RUo1GDHAoGBANji -2Mzu4iE/YAaRvmxmjZApyBYsJLUxJ1eV88crdUXt7Ylid1Wgjx4yibRGRMk4NiMA -MKoV/AysBVN+foTN3ujZ8uRNyXl6pDeTq1XZrEpkQaOuDSTU94b19JCV7raNakUN -OPFCI5myYCdNkMSXOD4L3LWhmdf9wtx9P4lKvOIVAoGACFnHHNNNwZa4+xyY6vI1 -1RM6caRdHqq3YUrbgCpXXqAeCJJNab4HKmtGKPHs5Yfrv1h2C5xB0FrILeQAPkvv -HMdvWNrlOn2B+cyz5nuKbsfq4Gz/jVnATxPLYikHhmMUo/iRfabCtypxMhUr9i0y -NKvTg7JcsdZgjmekjb+yCQ8CgYBTwOYv3V/9rteKMeXzPncUYM4fodRbFCw5KnMF -SsbyxjqgfyHOMz6RTrrWnvwZKFfflEc2p166FgPIhmSdLFMUYHXnrBJNkwqvW5si -f/iEkcq3RpNU0dj0iS50VzHj1SBgogaHRB8zTyrKgq2Q/UR+0V3d1hXuztPdCZDr -l6zxMQKBgQCAsswwUKJiG3pVzbfxOevkZWouwIZe9Pkq9E/vV9O57KQW7fvraAe6 -fkr+io0Ze6F+umNkrmGOfEZt7htupJrgj/uwSkUdvHplxzt5WEQUkJoUd6RKxJd8 -Z4qD/b9OYHVp4BNGqFpT9vD+lbbY15HwnSxPWRF+XkpEATsR2HXutw== ------END RSA PRIVATE KEY----- diff --git a/test/consul/consul-config.json b/test/consul/consul-config.json deleted file mode 100644 index acab2a7a1b3f3..0000000000000 --- a/test/consul/consul-config.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "ports": { - "https": 8443 - }, - "verify_incoming": true, - "verify_outgoing": true, - "key_file": "/cilium-consul/server.key", - "cert_file": "/cilium-consul/server.crt", - "ca_file": "/cilium-consul/server-ca.crt" -} diff --git a/test/consul/gen-cert.sh b/test/consul/gen-cert.sh deleted file mode 100755 index d294748b2f76e..0000000000000 --- a/test/consul/gen-cert.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env bash - -clean() { - rm -f server.crt server.key server-ca.crt consul-client.crt consul-client.key consul-client-ca.crt cilium-consul.yaml - exit 0 -} - -gen_consul_config() { - cat > cilium-consul.yaml < "${CILIUM_DIR}/consul/consul-logs.txt" 2>/dev/null else # Get logs from each Cilium pod. local NAMESPACE="kube-system" @@ -1057,10 +1054,6 @@ function remove_cilium_docker_network { restore_flag $save "e" } -function remove_all_containers { - docker rm -f $(docker ps --format '{{.Names}}' | grep -v cilium-consul) > /dev/null 2>&1 || true -} - function test_succeeded { check_num_params "$#" "1" local TEST_NAME="$1" diff --git a/test/helpers/cilium.go b/test/helpers/cilium.go index 12eb5de5d68e6..db9b69bdc260b 100644 --- a/test/helpers/cilium.go +++ b/test/helpers/cilium.go @@ -738,7 +738,6 @@ func (s *SSHMeta) GatherLogs() { ciliumLogCommands := map[string]string{ fmt.Sprintf("sudo journalctl -au %s --no-pager", DaemonName): "cilium.log", fmt.Sprintf("sudo journalctl -au %s --no-pager", CiliumDockerDaemonName): "cilium-docker.log", - "sudo docker logs cilium-consul": "consul.log", } testPath, err := CreateReportDirectory() @@ -774,7 +773,7 @@ func (s *SSHMeta) SetUpCilium() error { func (s *SSHMeta) SetUpCiliumWithOptions(ciliumOpts string) error { // Default kvstore options if !strings.Contains(ciliumOpts, "--kvstore") { - ciliumOpts += " --kvstore consul --kvstore-opt consul.address=127.0.0.1:8500" + ciliumOpts += " --kvstore etcd --kvstore-opt etcd.address=127.0.0.1:4001" } ciliumOpts += " --exclude-local-address=" + DockerBridgeIP + "/32" diff --git a/test/provision/docker-run-cilium.sh b/test/provision/docker-run-cilium.sh index 0626da19694af..3740addfd4ab2 100755 --- a/test/provision/docker-run-cilium.sh +++ b/test/provision/docker-run-cilium.sh @@ -2,9 +2,9 @@ # all args are passed as cilium-agent options (except for "uninstall" below) CILIUM_OPTS=$@ -# Default kvstore to consul +# Default kvstore to etcd if [[ "${CILIUM_OPTS}" != *--kvstore* ]]; then - CILIUM_OPTS+=" --kvstore consul --kvstore-opt consul.address=127.0.0.1:8500" + CILIUM_OPTS+=" --kvstore etcd --kvstore-opt etcd.address=127.0.0.1:4001" fi CILIUM_IMAGE=${CILIUM_IMAGE:-cilium/cilium:latest} diff --git a/test/runtime/chaos.go b/test/runtime/chaos.go index fe831bfd57179..6641cb7d83a90 100644 --- a/test/runtime/chaos.go +++ b/test/runtime/chaos.go @@ -58,6 +58,4 @@ var _ = Describe("RuntimeAgentChaos", func() { }) Context("Cilium agent", agentChaosTests) - - Context("KVStore", kvstoreChaosTests) }) diff --git a/test/runtime/kvstore.go b/test/runtime/kvstore.go index 0148b5e13a1ef..759d9755b3a3f 100644 --- a/test/runtime/kvstore.go +++ b/test/runtime/kvstore.go @@ -4,12 +4,10 @@ package RuntimeTest import ( - "fmt" "time" . "github.com/onsi/gomega" - "github.com/cilium/cilium/pkg/identity" . "github.com/cilium/cilium/test/ginkgo-ext" "github.com/cilium/cilium/test/helpers" "github.com/cilium/cilium/test/helpers/constants" @@ -63,23 +61,6 @@ var _ = Describe("RuntimeAgentKVStoreTest", func() { }) Context("KVStore tests", func() { - It("Consul KVStore", func() { - By("Starting Cilium with consul as kvstore") - err := vm.SetUpCiliumWithOptions("--kvstore consul --kvstore-opt consul.address=127.0.0.1:8500") - Expect(err).Should(BeNil(), "Cilium failed to start") - - By("Restarting cilium-docker service") - vm.Exec("sudo systemctl restart cilium-docker") - Expect(vm.WaitDockerPluginReady()).Should(BeTrue(), "Docker plugin is not ready after timeout") - ExpectCiliumReady(vm) - - containers(helpers.Create) - Expect(vm.WaitEndpointsReady()).Should(BeTrue(), "Endpoints are not ready after timeout") - eps, err := vm.GetEndpointsNames() - Expect(err).Should(BeNil(), "Error getting names of endpoints from cilium") - Expect(len(eps)).To(Equal(1), "Number of endpoints in Cilium differs from what is expected") - }) - It("Etcd KVStore", func() { By("Starting Cilium with etcd as kvstore") err := vm.SetUpCiliumWithOptions("--kvstore etcd --kvstore-opt etcd.address=127.0.0.1:4001") @@ -100,86 +81,3 @@ var _ = Describe("RuntimeAgentKVStoreTest", func() { }) }) }) - -var kvstoreChaosTests = func() { - var vm *helpers.SSHMeta - - BeforeAll(func() { - vm = helpers.InitRuntimeHelper(helpers.Runtime, logger) - }) - - AfterAll(func() { - vm.CloseSSHClient() - }) - - It("Validate that delete events on KVStore do not release in use identities", func() { - // This validates that if a kvstore delete event is send the identity - // is not release if it is in use. For more info issue #7240 - - prefix := "http://127.0.0.1:8500/v1/kv/cilium/state/identities/v1/id" - identities, err := vm.GetEndpointsIdentityIds() - Expect(err).To(BeNil(), "Cannot get identities") - - By("Deleting identities from kvstore") - for _, identityID := range identities { - action := helpers.CurlFail("%s/%s -X DELETE", prefix, identityID) - vm.Exec(action).ExpectSuccess("Key %s cannot be deleted correctly", identityID) - } - - newidentities, err := vm.GetEndpointsIdentityIds() - Expect(err).To(BeNil(), "Cannot get identities after delete keys") - - Expect(newidentities).To(Equal(identities), - "Identities are not the same after delete keys from kvstore") - - By("Checking that identities were restored correctly after deletion") - for _, identityID := range newidentities { - id, err := identity.ParseNumericIdentity(identityID) - Expect(err).To(BeNil(), "Cannot parse identity") - if id.IsReservedIdentity() { - continue - } - action := helpers.CurlFail("%s/%s", prefix, identityID) - vm.Exec(action).ExpectSuccess("Key %s was not restored correctly", identityID) - } - }) - - It("Delete event on KVStore with CIDR identities", func() { - // Validate that if when a delete event happens on kvstore the CIDR - // identity (local one) is not deleted. This happens on the past where - // other cilium agent executes a deletion of a key that was used by - // another cilium agent, that means that on policy regeneration the - // identity was not present. - jqFilter := `jq -r '.[] | select(.labels|join("") | contains("cidr")) | .id'` - prefix := "http://127.0.0.1:8500/v1/kv/cilium/state/identities/v1/id" - - By("Installing CIDR policy") - policy := ` - [{ - "endpointSelector": {"matchLabels":{"test":""}}, - "egress": - [{ - "toCIDR": [ - "10.10.10.10/32" - ] - }] - }] - ` - _, err := vm.PolicyRenderAndImport(policy) - Expect(err).To(BeNil(), "Unable to import policy: %s", err) - - CIDRIdentities := vm.Exec(fmt.Sprintf(`cilium-dbg identity list -o json| %s`, jqFilter)) - CIDRIdentities.ExpectSuccess("Cannot get cidr identities") - - for _, identityID := range CIDRIdentities.ByLines() { - action := helpers.CurlFail("%s/%s -X DELETE", prefix, identityID) - vm.Exec(action).ExpectSuccess("Key %s cannot be deleted correctly", identityID) - } - - newCIDRIdentities := vm.Exec(fmt.Sprintf(`cilium-dbg identity list -o json| %s`, jqFilter)) - newCIDRIdentities.ExpectSuccess("Cannot get cidr identities") - - Expect(CIDRIdentities.ByLines()).To(Equal(newCIDRIdentities.ByLines()), - "Identities are deleted in kvstore delete event") - }) -} diff --git a/tools/licensecheck/allowed.go b/tools/licensecheck/allowed.go index f9e493f0a5575..409789be33cd2 100644 --- a/tools/licensecheck/allowed.go +++ b/tools/licensecheck/allowed.go @@ -21,7 +21,6 @@ var allowedLicenses = []string{ // Do not add all exceptions from the above link, only packages that we // actually use. var pkgExceptions = []string{ - "github.com/hashicorp/consul/api", "github.com/hashicorp/errwrap", "github.com/hashicorp/go-cleanhttp", "github.com/hashicorp/go-immutable-radix", diff --git a/vendor/github.com/armon/go-metrics/.gitignore b/vendor/github.com/armon/go-metrics/.gitignore deleted file mode 100644 index e5750f5720e33..0000000000000 --- a/vendor/github.com/armon/go-metrics/.gitignore +++ /dev/null @@ -1,26 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe - -/metrics.out - -.idea diff --git a/vendor/github.com/armon/go-metrics/.travis.yml b/vendor/github.com/armon/go-metrics/.travis.yml deleted file mode 100644 index 87d230c8d78e2..0000000000000 --- a/vendor/github.com/armon/go-metrics/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: go - -go: - - "1.x" - -env: - - GO111MODULE=on - -install: - - go get ./... - -script: - - go test ./... diff --git a/vendor/github.com/armon/go-metrics/LICENSE b/vendor/github.com/armon/go-metrics/LICENSE deleted file mode 100644 index 106569e542b0d..0000000000000 --- a/vendor/github.com/armon/go-metrics/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 Armon Dadgar - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/armon/go-metrics/README.md b/vendor/github.com/armon/go-metrics/README.md deleted file mode 100644 index aa73348c08df3..0000000000000 --- a/vendor/github.com/armon/go-metrics/README.md +++ /dev/null @@ -1,91 +0,0 @@ -go-metrics -========== - -This library provides a `metrics` package which can be used to instrument code, -expose application metrics, and profile runtime performance in a flexible manner. - -Current API: [![GoDoc](https://godoc.org/github.com/armon/go-metrics?status.svg)](https://godoc.org/github.com/armon/go-metrics) - -Sinks ------ - -The `metrics` package makes use of a `MetricSink` interface to support delivery -to any type of backend. Currently the following sinks are provided: - -* StatsiteSink : Sinks to a [statsite](https://github.com/armon/statsite/) instance (TCP) -* StatsdSink: Sinks to a [StatsD](https://github.com/etsy/statsd/) / statsite instance (UDP) -* PrometheusSink: Sinks to a [Prometheus](http://prometheus.io/) metrics endpoint (exposed via HTTP for scrapes) -* InmemSink : Provides in-memory aggregation, can be used to export stats -* FanoutSink : Sinks to multiple sinks. Enables writing to multiple statsite instances for example. -* BlackholeSink : Sinks to nowhere - -In addition to the sinks, the `InmemSignal` can be used to catch a signal, -and dump a formatted output of recent metrics. For example, when a process gets -a SIGUSR1, it can dump to stderr recent performance metrics for debugging. - -Labels ------- - -Most metrics do have an equivalent ending with `WithLabels`, such methods -allow to push metrics with labels and use some features of underlying Sinks -(ex: translated into Prometheus labels). - -Since some of these labels may increase greatly cardinality of metrics, the -library allow to filter labels using a blacklist/whitelist filtering system -which is global to all metrics. - -* If `Config.AllowedLabels` is not nil, then only labels specified in this value will be sent to underlying Sink, otherwise, all labels are sent by default. -* If `Config.BlockedLabels` is not nil, any label specified in this value will not be sent to underlying Sinks. - -By default, both `Config.AllowedLabels` and `Config.BlockedLabels` are nil, meaning that -no tags are filetered at all, but it allow to a user to globally block some tags with high -cardinality at application level. - -Examples --------- - -Here is an example of using the package: - -```go -func SlowMethod() { - // Profiling the runtime of a method - defer metrics.MeasureSince([]string{"SlowMethod"}, time.Now()) -} - -// Configure a statsite sink as the global metrics sink -sink, _ := metrics.NewStatsiteSink("statsite:8125") -metrics.NewGlobal(metrics.DefaultConfig("service-name"), sink) - -// Emit a Key/Value pair -metrics.EmitKey([]string{"questions", "meaning of life"}, 42) -``` - -Here is an example of setting up a signal handler: - -```go -// Setup the inmem sink and signal handler -inm := metrics.NewInmemSink(10*time.Second, time.Minute) -sig := metrics.DefaultInmemSignal(inm) -metrics.NewGlobal(metrics.DefaultConfig("service-name"), inm) - -// Run some code -inm.SetGauge([]string{"foo"}, 42) -inm.EmitKey([]string{"bar"}, 30) - -inm.IncrCounter([]string{"baz"}, 42) -inm.IncrCounter([]string{"baz"}, 1) -inm.IncrCounter([]string{"baz"}, 80) - -inm.AddSample([]string{"method", "wow"}, 42) -inm.AddSample([]string{"method", "wow"}, 100) -inm.AddSample([]string{"method", "wow"}, 22) - -.... -``` - -When a signal comes in, output like the following will be dumped to stderr: - - [2014-01-28 14:57:33.04 -0800 PST][G] 'foo': 42.000 - [2014-01-28 14:57:33.04 -0800 PST][P] 'bar': 30.000 - [2014-01-28 14:57:33.04 -0800 PST][C] 'baz': Count: 3 Min: 1.000 Mean: 41.000 Max: 80.000 Stddev: 39.509 - [2014-01-28 14:57:33.04 -0800 PST][S] 'method.wow': Count: 3 Min: 22.000 Mean: 54.667 Max: 100.000 Stddev: 40.513 \ No newline at end of file diff --git a/vendor/github.com/armon/go-metrics/const_unix.go b/vendor/github.com/armon/go-metrics/const_unix.go deleted file mode 100644 index 31098dd57e555..0000000000000 --- a/vendor/github.com/armon/go-metrics/const_unix.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build !windows - -package metrics - -import ( - "syscall" -) - -const ( - // DefaultSignal is used with DefaultInmemSignal - DefaultSignal = syscall.SIGUSR1 -) diff --git a/vendor/github.com/armon/go-metrics/const_windows.go b/vendor/github.com/armon/go-metrics/const_windows.go deleted file mode 100644 index 38136af3e4237..0000000000000 --- a/vendor/github.com/armon/go-metrics/const_windows.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build windows - -package metrics - -import ( - "syscall" -) - -const ( - // DefaultSignal is used with DefaultInmemSignal - // Windows has no SIGUSR1, use SIGBREAK - DefaultSignal = syscall.Signal(21) -) diff --git a/vendor/github.com/armon/go-metrics/inmem.go b/vendor/github.com/armon/go-metrics/inmem.go deleted file mode 100644 index 7c427aca97947..0000000000000 --- a/vendor/github.com/armon/go-metrics/inmem.go +++ /dev/null @@ -1,339 +0,0 @@ -package metrics - -import ( - "bytes" - "fmt" - "math" - "net/url" - "strings" - "sync" - "time" -) - -var spaceReplacer = strings.NewReplacer(" ", "_") - -// InmemSink provides a MetricSink that does in-memory aggregation -// without sending metrics over a network. It can be embedded within -// an application to provide profiling information. -type InmemSink struct { - // How long is each aggregation interval - interval time.Duration - - // Retain controls how many metrics interval we keep - retain time.Duration - - // maxIntervals is the maximum length of intervals. - // It is retain / interval. - maxIntervals int - - // intervals is a slice of the retained intervals - intervals []*IntervalMetrics - intervalLock sync.RWMutex - - rateDenom float64 -} - -// IntervalMetrics stores the aggregated metrics -// for a specific interval -type IntervalMetrics struct { - sync.RWMutex - - // The start time of the interval - Interval time.Time - - // Gauges maps the key to the last set value - Gauges map[string]GaugeValue - - // Points maps the string to the list of emitted values - // from EmitKey - Points map[string][]float32 - - // Counters maps the string key to a sum of the counter - // values - Counters map[string]SampledValue - - // Samples maps the key to an AggregateSample, - // which has the rolled up view of a sample - Samples map[string]SampledValue - - // done is closed when this interval has ended, and a new IntervalMetrics - // has been created to receive any future metrics. - done chan struct{} -} - -// NewIntervalMetrics creates a new IntervalMetrics for a given interval -func NewIntervalMetrics(intv time.Time) *IntervalMetrics { - return &IntervalMetrics{ - Interval: intv, - Gauges: make(map[string]GaugeValue), - Points: make(map[string][]float32), - Counters: make(map[string]SampledValue), - Samples: make(map[string]SampledValue), - done: make(chan struct{}), - } -} - -// AggregateSample is used to hold aggregate metrics -// about a sample -type AggregateSample struct { - Count int // The count of emitted pairs - Rate float64 // The values rate per time unit (usually 1 second) - Sum float64 // The sum of values - SumSq float64 `json:"-"` // The sum of squared values - Min float64 // Minimum value - Max float64 // Maximum value - LastUpdated time.Time `json:"-"` // When value was last updated -} - -// Computes a Stddev of the values -func (a *AggregateSample) Stddev() float64 { - num := (float64(a.Count) * a.SumSq) - math.Pow(a.Sum, 2) - div := float64(a.Count * (a.Count - 1)) - if div == 0 { - return 0 - } - return math.Sqrt(num / div) -} - -// Computes a mean of the values -func (a *AggregateSample) Mean() float64 { - if a.Count == 0 { - return 0 - } - return a.Sum / float64(a.Count) -} - -// Ingest is used to update a sample -func (a *AggregateSample) Ingest(v float64, rateDenom float64) { - a.Count++ - a.Sum += v - a.SumSq += (v * v) - if v < a.Min || a.Count == 1 { - a.Min = v - } - if v > a.Max || a.Count == 1 { - a.Max = v - } - a.Rate = float64(a.Sum) / rateDenom - a.LastUpdated = time.Now() -} - -func (a *AggregateSample) String() string { - if a.Count == 0 { - return "Count: 0" - } else if a.Stddev() == 0 { - return fmt.Sprintf("Count: %d Sum: %0.3f LastUpdated: %s", a.Count, a.Sum, a.LastUpdated) - } else { - return fmt.Sprintf("Count: %d Min: %0.3f Mean: %0.3f Max: %0.3f Stddev: %0.3f Sum: %0.3f LastUpdated: %s", - a.Count, a.Min, a.Mean(), a.Max, a.Stddev(), a.Sum, a.LastUpdated) - } -} - -// NewInmemSinkFromURL creates an InmemSink from a URL. It is used -// (and tested) from NewMetricSinkFromURL. -func NewInmemSinkFromURL(u *url.URL) (MetricSink, error) { - params := u.Query() - - interval, err := time.ParseDuration(params.Get("interval")) - if err != nil { - return nil, fmt.Errorf("Bad 'interval' param: %s", err) - } - - retain, err := time.ParseDuration(params.Get("retain")) - if err != nil { - return nil, fmt.Errorf("Bad 'retain' param: %s", err) - } - - return NewInmemSink(interval, retain), nil -} - -// NewInmemSink is used to construct a new in-memory sink. -// Uses an aggregation interval and maximum retention period. -func NewInmemSink(interval, retain time.Duration) *InmemSink { - rateTimeUnit := time.Second - i := &InmemSink{ - interval: interval, - retain: retain, - maxIntervals: int(retain / interval), - rateDenom: float64(interval.Nanoseconds()) / float64(rateTimeUnit.Nanoseconds()), - } - i.intervals = make([]*IntervalMetrics, 0, i.maxIntervals) - return i -} - -func (i *InmemSink) SetGauge(key []string, val float32) { - i.SetGaugeWithLabels(key, val, nil) -} - -func (i *InmemSink) SetGaugeWithLabels(key []string, val float32, labels []Label) { - k, name := i.flattenKeyLabels(key, labels) - intv := i.getInterval() - - intv.Lock() - defer intv.Unlock() - intv.Gauges[k] = GaugeValue{Name: name, Value: val, Labels: labels} -} - -func (i *InmemSink) EmitKey(key []string, val float32) { - k := i.flattenKey(key) - intv := i.getInterval() - - intv.Lock() - defer intv.Unlock() - vals := intv.Points[k] - intv.Points[k] = append(vals, val) -} - -func (i *InmemSink) IncrCounter(key []string, val float32) { - i.IncrCounterWithLabels(key, val, nil) -} - -func (i *InmemSink) IncrCounterWithLabels(key []string, val float32, labels []Label) { - k, name := i.flattenKeyLabels(key, labels) - intv := i.getInterval() - - intv.Lock() - defer intv.Unlock() - - agg, ok := intv.Counters[k] - if !ok { - agg = SampledValue{ - Name: name, - AggregateSample: &AggregateSample{}, - Labels: labels, - } - intv.Counters[k] = agg - } - agg.Ingest(float64(val), i.rateDenom) -} - -func (i *InmemSink) AddSample(key []string, val float32) { - i.AddSampleWithLabels(key, val, nil) -} - -func (i *InmemSink) AddSampleWithLabels(key []string, val float32, labels []Label) { - k, name := i.flattenKeyLabels(key, labels) - intv := i.getInterval() - - intv.Lock() - defer intv.Unlock() - - agg, ok := intv.Samples[k] - if !ok { - agg = SampledValue{ - Name: name, - AggregateSample: &AggregateSample{}, - Labels: labels, - } - intv.Samples[k] = agg - } - agg.Ingest(float64(val), i.rateDenom) -} - -// Data is used to retrieve all the aggregated metrics -// Intervals may be in use, and a read lock should be acquired -func (i *InmemSink) Data() []*IntervalMetrics { - // Get the current interval, forces creation - i.getInterval() - - i.intervalLock.RLock() - defer i.intervalLock.RUnlock() - - n := len(i.intervals) - intervals := make([]*IntervalMetrics, n) - - copy(intervals[:n-1], i.intervals[:n-1]) - current := i.intervals[n-1] - - // make its own copy for current interval - intervals[n-1] = &IntervalMetrics{} - copyCurrent := intervals[n-1] - current.RLock() - *copyCurrent = *current - // RWMutex is not safe to copy, so create a new instance on the copy - copyCurrent.RWMutex = sync.RWMutex{} - - copyCurrent.Gauges = make(map[string]GaugeValue, len(current.Gauges)) - for k, v := range current.Gauges { - copyCurrent.Gauges[k] = v - } - // saved values will be not change, just copy its link - copyCurrent.Points = make(map[string][]float32, len(current.Points)) - for k, v := range current.Points { - copyCurrent.Points[k] = v - } - copyCurrent.Counters = make(map[string]SampledValue, len(current.Counters)) - for k, v := range current.Counters { - copyCurrent.Counters[k] = v.deepCopy() - } - copyCurrent.Samples = make(map[string]SampledValue, len(current.Samples)) - for k, v := range current.Samples { - copyCurrent.Samples[k] = v.deepCopy() - } - current.RUnlock() - - return intervals -} - -// getInterval returns the current interval. A new interval is created if no -// previous interval exists, or if the current time is beyond the window for the -// current interval. -func (i *InmemSink) getInterval() *IntervalMetrics { - intv := time.Now().Truncate(i.interval) - - // Attempt to return the existing interval first, because it only requires - // a read lock. - i.intervalLock.RLock() - n := len(i.intervals) - if n > 0 && i.intervals[n-1].Interval == intv { - defer i.intervalLock.RUnlock() - return i.intervals[n-1] - } - i.intervalLock.RUnlock() - - i.intervalLock.Lock() - defer i.intervalLock.Unlock() - - // Re-check for an existing interval now that the lock is re-acquired. - n = len(i.intervals) - if n > 0 && i.intervals[n-1].Interval == intv { - return i.intervals[n-1] - } - - current := NewIntervalMetrics(intv) - i.intervals = append(i.intervals, current) - if n > 0 { - close(i.intervals[n-1].done) - } - - n++ - // Prune old intervals if the count exceeds the max. - if n >= i.maxIntervals { - copy(i.intervals[0:], i.intervals[n-i.maxIntervals:]) - i.intervals = i.intervals[:i.maxIntervals] - } - return current -} - -// Flattens the key for formatting, removes spaces -func (i *InmemSink) flattenKey(parts []string) string { - buf := &bytes.Buffer{} - - joined := strings.Join(parts, ".") - - spaceReplacer.WriteString(buf, joined) - - return buf.String() -} - -// Flattens the key for formatting along with its labels, removes spaces -func (i *InmemSink) flattenKeyLabels(parts []string, labels []Label) (string, string) { - key := i.flattenKey(parts) - buf := bytes.NewBufferString(key) - - for _, label := range labels { - spaceReplacer.WriteString(buf, fmt.Sprintf(";%s=%s", label.Name, label.Value)) - } - - return buf.String(), key -} diff --git a/vendor/github.com/armon/go-metrics/inmem_endpoint.go b/vendor/github.com/armon/go-metrics/inmem_endpoint.go deleted file mode 100644 index 24eefa96389bd..0000000000000 --- a/vendor/github.com/armon/go-metrics/inmem_endpoint.go +++ /dev/null @@ -1,162 +0,0 @@ -package metrics - -import ( - "context" - "fmt" - "net/http" - "sort" - "time" -) - -// MetricsSummary holds a roll-up of metrics info for a given interval -type MetricsSummary struct { - Timestamp string - Gauges []GaugeValue - Points []PointValue - Counters []SampledValue - Samples []SampledValue -} - -type GaugeValue struct { - Name string - Hash string `json:"-"` - Value float32 - - Labels []Label `json:"-"` - DisplayLabels map[string]string `json:"Labels"` -} - -type PointValue struct { - Name string - Points []float32 -} - -type SampledValue struct { - Name string - Hash string `json:"-"` - *AggregateSample - Mean float64 - Stddev float64 - - Labels []Label `json:"-"` - DisplayLabels map[string]string `json:"Labels"` -} - -// deepCopy allocates a new instance of AggregateSample -func (source *SampledValue) deepCopy() SampledValue { - dest := *source - if source.AggregateSample != nil { - dest.AggregateSample = &AggregateSample{} - *dest.AggregateSample = *source.AggregateSample - } - return dest -} - -// DisplayMetrics returns a summary of the metrics from the most recent finished interval. -func (i *InmemSink) DisplayMetrics(resp http.ResponseWriter, req *http.Request) (interface{}, error) { - data := i.Data() - - var interval *IntervalMetrics - n := len(data) - switch { - case n == 0: - return nil, fmt.Errorf("no metric intervals have been initialized yet") - case n == 1: - // Show the current interval if it's all we have - interval = data[0] - default: - // Show the most recent finished interval if we have one - interval = data[n-2] - } - - return newMetricSummaryFromInterval(interval), nil -} - -func newMetricSummaryFromInterval(interval *IntervalMetrics) MetricsSummary { - interval.RLock() - defer interval.RUnlock() - - summary := MetricsSummary{ - Timestamp: interval.Interval.Round(time.Second).UTC().String(), - Gauges: make([]GaugeValue, 0, len(interval.Gauges)), - Points: make([]PointValue, 0, len(interval.Points)), - } - - // Format and sort the output of each metric type, so it gets displayed in a - // deterministic order. - for name, points := range interval.Points { - summary.Points = append(summary.Points, PointValue{name, points}) - } - sort.Slice(summary.Points, func(i, j int) bool { - return summary.Points[i].Name < summary.Points[j].Name - }) - - for hash, value := range interval.Gauges { - value.Hash = hash - value.DisplayLabels = make(map[string]string) - for _, label := range value.Labels { - value.DisplayLabels[label.Name] = label.Value - } - value.Labels = nil - - summary.Gauges = append(summary.Gauges, value) - } - sort.Slice(summary.Gauges, func(i, j int) bool { - return summary.Gauges[i].Hash < summary.Gauges[j].Hash - }) - - summary.Counters = formatSamples(interval.Counters) - summary.Samples = formatSamples(interval.Samples) - - return summary -} - -func formatSamples(source map[string]SampledValue) []SampledValue { - output := make([]SampledValue, 0, len(source)) - for hash, sample := range source { - displayLabels := make(map[string]string) - for _, label := range sample.Labels { - displayLabels[label.Name] = label.Value - } - - output = append(output, SampledValue{ - Name: sample.Name, - Hash: hash, - AggregateSample: sample.AggregateSample, - Mean: sample.AggregateSample.Mean(), - Stddev: sample.AggregateSample.Stddev(), - DisplayLabels: displayLabels, - }) - } - sort.Slice(output, func(i, j int) bool { - return output[i].Hash < output[j].Hash - }) - - return output -} - -type Encoder interface { - Encode(interface{}) error -} - -// Stream writes metrics using encoder.Encode each time an interval ends. Runs -// until the request context is cancelled, or the encoder returns an error. -// The caller is responsible for logging any errors from encoder. -func (i *InmemSink) Stream(ctx context.Context, encoder Encoder) { - interval := i.getInterval() - - for { - select { - case <-interval.done: - summary := newMetricSummaryFromInterval(interval) - if err := encoder.Encode(summary); err != nil { - return - } - - // update interval to the next one - interval = i.getInterval() - case <-ctx.Done(): - return - } - } -} diff --git a/vendor/github.com/armon/go-metrics/inmem_signal.go b/vendor/github.com/armon/go-metrics/inmem_signal.go deleted file mode 100644 index 0937f4aedf7c7..0000000000000 --- a/vendor/github.com/armon/go-metrics/inmem_signal.go +++ /dev/null @@ -1,117 +0,0 @@ -package metrics - -import ( - "bytes" - "fmt" - "io" - "os" - "os/signal" - "strings" - "sync" - "syscall" -) - -// InmemSignal is used to listen for a given signal, and when received, -// to dump the current metrics from the InmemSink to an io.Writer -type InmemSignal struct { - signal syscall.Signal - inm *InmemSink - w io.Writer - sigCh chan os.Signal - - stop bool - stopCh chan struct{} - stopLock sync.Mutex -} - -// NewInmemSignal creates a new InmemSignal which listens for a given signal, -// and dumps the current metrics out to a writer -func NewInmemSignal(inmem *InmemSink, sig syscall.Signal, w io.Writer) *InmemSignal { - i := &InmemSignal{ - signal: sig, - inm: inmem, - w: w, - sigCh: make(chan os.Signal, 1), - stopCh: make(chan struct{}), - } - signal.Notify(i.sigCh, sig) - go i.run() - return i -} - -// DefaultInmemSignal returns a new InmemSignal that responds to SIGUSR1 -// and writes output to stderr. Windows uses SIGBREAK -func DefaultInmemSignal(inmem *InmemSink) *InmemSignal { - return NewInmemSignal(inmem, DefaultSignal, os.Stderr) -} - -// Stop is used to stop the InmemSignal from listening -func (i *InmemSignal) Stop() { - i.stopLock.Lock() - defer i.stopLock.Unlock() - - if i.stop { - return - } - i.stop = true - close(i.stopCh) - signal.Stop(i.sigCh) -} - -// run is a long running routine that handles signals -func (i *InmemSignal) run() { - for { - select { - case <-i.sigCh: - i.dumpStats() - case <-i.stopCh: - return - } - } -} - -// dumpStats is used to dump the data to output writer -func (i *InmemSignal) dumpStats() { - buf := bytes.NewBuffer(nil) - - data := i.inm.Data() - // Skip the last period which is still being aggregated - for j := 0; j < len(data)-1; j++ { - intv := data[j] - intv.RLock() - for _, val := range intv.Gauges { - name := i.flattenLabels(val.Name, val.Labels) - fmt.Fprintf(buf, "[%v][G] '%s': %0.3f\n", intv.Interval, name, val.Value) - } - for name, vals := range intv.Points { - for _, val := range vals { - fmt.Fprintf(buf, "[%v][P] '%s': %0.3f\n", intv.Interval, name, val) - } - } - for _, agg := range intv.Counters { - name := i.flattenLabels(agg.Name, agg.Labels) - fmt.Fprintf(buf, "[%v][C] '%s': %s\n", intv.Interval, name, agg.AggregateSample) - } - for _, agg := range intv.Samples { - name := i.flattenLabels(agg.Name, agg.Labels) - fmt.Fprintf(buf, "[%v][S] '%s': %s\n", intv.Interval, name, agg.AggregateSample) - } - intv.RUnlock() - } - - // Write out the bytes - i.w.Write(buf.Bytes()) -} - -// Flattens the key for formatting along with its labels, removes spaces -func (i *InmemSignal) flattenLabels(name string, labels []Label) string { - buf := bytes.NewBufferString(name) - replacer := strings.NewReplacer(" ", "_", ":", "_") - - for _, label := range labels { - replacer.WriteString(buf, ".") - replacer.WriteString(buf, label.Value) - } - - return buf.String() -} diff --git a/vendor/github.com/armon/go-metrics/metrics.go b/vendor/github.com/armon/go-metrics/metrics.go deleted file mode 100644 index 36642a42937b5..0000000000000 --- a/vendor/github.com/armon/go-metrics/metrics.go +++ /dev/null @@ -1,299 +0,0 @@ -package metrics - -import ( - "runtime" - "strings" - "time" - - iradix "github.com/hashicorp/go-immutable-radix" -) - -type Label struct { - Name string - Value string -} - -func (m *Metrics) SetGauge(key []string, val float32) { - m.SetGaugeWithLabels(key, val, nil) -} - -func (m *Metrics) SetGaugeWithLabels(key []string, val float32, labels []Label) { - if m.HostName != "" { - if m.EnableHostnameLabel { - labels = append(labels, Label{"host", m.HostName}) - } else if m.EnableHostname { - key = insert(0, m.HostName, key) - } - } - if m.EnableTypePrefix { - key = insert(0, "gauge", key) - } - if m.ServiceName != "" { - if m.EnableServiceLabel { - labels = append(labels, Label{"service", m.ServiceName}) - } else { - key = insert(0, m.ServiceName, key) - } - } - allowed, labelsFiltered := m.allowMetric(key, labels) - if !allowed { - return - } - m.sink.SetGaugeWithLabels(key, val, labelsFiltered) -} - -func (m *Metrics) EmitKey(key []string, val float32) { - if m.EnableTypePrefix { - key = insert(0, "kv", key) - } - if m.ServiceName != "" { - key = insert(0, m.ServiceName, key) - } - allowed, _ := m.allowMetric(key, nil) - if !allowed { - return - } - m.sink.EmitKey(key, val) -} - -func (m *Metrics) IncrCounter(key []string, val float32) { - m.IncrCounterWithLabels(key, val, nil) -} - -func (m *Metrics) IncrCounterWithLabels(key []string, val float32, labels []Label) { - if m.HostName != "" && m.EnableHostnameLabel { - labels = append(labels, Label{"host", m.HostName}) - } - if m.EnableTypePrefix { - key = insert(0, "counter", key) - } - if m.ServiceName != "" { - if m.EnableServiceLabel { - labels = append(labels, Label{"service", m.ServiceName}) - } else { - key = insert(0, m.ServiceName, key) - } - } - allowed, labelsFiltered := m.allowMetric(key, labels) - if !allowed { - return - } - m.sink.IncrCounterWithLabels(key, val, labelsFiltered) -} - -func (m *Metrics) AddSample(key []string, val float32) { - m.AddSampleWithLabels(key, val, nil) -} - -func (m *Metrics) AddSampleWithLabels(key []string, val float32, labels []Label) { - if m.HostName != "" && m.EnableHostnameLabel { - labels = append(labels, Label{"host", m.HostName}) - } - if m.EnableTypePrefix { - key = insert(0, "sample", key) - } - if m.ServiceName != "" { - if m.EnableServiceLabel { - labels = append(labels, Label{"service", m.ServiceName}) - } else { - key = insert(0, m.ServiceName, key) - } - } - allowed, labelsFiltered := m.allowMetric(key, labels) - if !allowed { - return - } - m.sink.AddSampleWithLabels(key, val, labelsFiltered) -} - -func (m *Metrics) MeasureSince(key []string, start time.Time) { - m.MeasureSinceWithLabels(key, start, nil) -} - -func (m *Metrics) MeasureSinceWithLabels(key []string, start time.Time, labels []Label) { - if m.HostName != "" && m.EnableHostnameLabel { - labels = append(labels, Label{"host", m.HostName}) - } - if m.EnableTypePrefix { - key = insert(0, "timer", key) - } - if m.ServiceName != "" { - if m.EnableServiceLabel { - labels = append(labels, Label{"service", m.ServiceName}) - } else { - key = insert(0, m.ServiceName, key) - } - } - allowed, labelsFiltered := m.allowMetric(key, labels) - if !allowed { - return - } - now := time.Now() - elapsed := now.Sub(start) - msec := float32(elapsed.Nanoseconds()) / float32(m.TimerGranularity) - m.sink.AddSampleWithLabels(key, msec, labelsFiltered) -} - -// UpdateFilter overwrites the existing filter with the given rules. -func (m *Metrics) UpdateFilter(allow, block []string) { - m.UpdateFilterAndLabels(allow, block, m.AllowedLabels, m.BlockedLabels) -} - -// UpdateFilterAndLabels overwrites the existing filter with the given rules. -func (m *Metrics) UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels []string) { - m.filterLock.Lock() - defer m.filterLock.Unlock() - - m.AllowedPrefixes = allow - m.BlockedPrefixes = block - - if allowedLabels == nil { - // Having a white list means we take only elements from it - m.allowedLabels = nil - } else { - m.allowedLabels = make(map[string]bool) - for _, v := range allowedLabels { - m.allowedLabels[v] = true - } - } - m.blockedLabels = make(map[string]bool) - for _, v := range blockedLabels { - m.blockedLabels[v] = true - } - m.AllowedLabels = allowedLabels - m.BlockedLabels = blockedLabels - - m.filter = iradix.New() - for _, prefix := range m.AllowedPrefixes { - m.filter, _, _ = m.filter.Insert([]byte(prefix), true) - } - for _, prefix := range m.BlockedPrefixes { - m.filter, _, _ = m.filter.Insert([]byte(prefix), false) - } -} - -func (m *Metrics) Shutdown() { - if ss, ok := m.sink.(ShutdownSink); ok { - ss.Shutdown() - } -} - -// labelIsAllowed return true if a should be included in metric -// the caller should lock m.filterLock while calling this method -func (m *Metrics) labelIsAllowed(label *Label) bool { - labelName := (*label).Name - if m.blockedLabels != nil { - _, ok := m.blockedLabels[labelName] - if ok { - // If present, let's remove this label - return false - } - } - if m.allowedLabels != nil { - _, ok := m.allowedLabels[labelName] - return ok - } - // Allow by default - return true -} - -// filterLabels return only allowed labels -// the caller should lock m.filterLock while calling this method -func (m *Metrics) filterLabels(labels []Label) []Label { - if labels == nil { - return nil - } - toReturn := []Label{} - for _, label := range labels { - if m.labelIsAllowed(&label) { - toReturn = append(toReturn, label) - } - } - return toReturn -} - -// Returns whether the metric should be allowed based on configured prefix filters -// Also return the applicable labels -func (m *Metrics) allowMetric(key []string, labels []Label) (bool, []Label) { - m.filterLock.RLock() - defer m.filterLock.RUnlock() - - if m.filter == nil || m.filter.Len() == 0 { - return m.Config.FilterDefault, m.filterLabels(labels) - } - - _, allowed, ok := m.filter.Root().LongestPrefix([]byte(strings.Join(key, "."))) - if !ok { - return m.Config.FilterDefault, m.filterLabels(labels) - } - - return allowed.(bool), m.filterLabels(labels) -} - -// Periodically collects runtime stats to publish -func (m *Metrics) collectStats() { - for { - time.Sleep(m.ProfileInterval) - m.EmitRuntimeStats() - } -} - -// Emits various runtime statsitics -func (m *Metrics) EmitRuntimeStats() { - // Export number of Goroutines - numRoutines := runtime.NumGoroutine() - m.SetGauge([]string{"runtime", "num_goroutines"}, float32(numRoutines)) - - // Export memory stats - var stats runtime.MemStats - runtime.ReadMemStats(&stats) - m.SetGauge([]string{"runtime", "alloc_bytes"}, float32(stats.Alloc)) - m.SetGauge([]string{"runtime", "sys_bytes"}, float32(stats.Sys)) - m.SetGauge([]string{"runtime", "malloc_count"}, float32(stats.Mallocs)) - m.SetGauge([]string{"runtime", "free_count"}, float32(stats.Frees)) - m.SetGauge([]string{"runtime", "heap_objects"}, float32(stats.HeapObjects)) - m.SetGauge([]string{"runtime", "total_gc_pause_ns"}, float32(stats.PauseTotalNs)) - m.SetGauge([]string{"runtime", "total_gc_runs"}, float32(stats.NumGC)) - - // Export info about the last few GC runs - num := stats.NumGC - - // Handle wrap around - if num < m.lastNumGC { - m.lastNumGC = 0 - } - - // Ensure we don't scan more than 256 - if num-m.lastNumGC >= 256 { - m.lastNumGC = num - 255 - } - - for i := m.lastNumGC; i < num; i++ { - pause := stats.PauseNs[i%256] - m.AddSample([]string{"runtime", "gc_pause_ns"}, float32(pause)) - } - m.lastNumGC = num -} - -// Creates a new slice with the provided string value as the first element -// and the provided slice values as the remaining values. -// Ordering of the values in the provided input slice is kept in tact in the output slice. -func insert(i int, v string, s []string) []string { - // Allocate new slice to avoid modifying the input slice - newS := make([]string, len(s)+1) - - // Copy s[0, i-1] into newS - for j := 0; j < i; j++ { - newS[j] = s[j] - } - - // Insert provided element at index i - newS[i] = v - - // Copy s[i, len(s)-1] into newS starting at newS[i+1] - for j := i; j < len(s); j++ { - newS[j+1] = s[j] - } - - return newS -} diff --git a/vendor/github.com/armon/go-metrics/sink.go b/vendor/github.com/armon/go-metrics/sink.go deleted file mode 100644 index 6f4108ff405a2..0000000000000 --- a/vendor/github.com/armon/go-metrics/sink.go +++ /dev/null @@ -1,132 +0,0 @@ -package metrics - -import ( - "fmt" - "net/url" -) - -// The MetricSink interface is used to transmit metrics information -// to an external system -type MetricSink interface { - // A Gauge should retain the last value it is set to - SetGauge(key []string, val float32) - SetGaugeWithLabels(key []string, val float32, labels []Label) - - // Should emit a Key/Value pair for each call - EmitKey(key []string, val float32) - - // Counters should accumulate values - IncrCounter(key []string, val float32) - IncrCounterWithLabels(key []string, val float32, labels []Label) - - // Samples are for timing information, where quantiles are used - AddSample(key []string, val float32) - AddSampleWithLabels(key []string, val float32, labels []Label) -} - -type ShutdownSink interface { - MetricSink - - // Shutdown the metric sink, flush metrics to storage, and cleanup resources. - // Called immediately prior to application exit. Implementations must block - // until metrics are flushed to storage. - Shutdown() -} - -// BlackholeSink is used to just blackhole messages -type BlackholeSink struct{} - -func (*BlackholeSink) SetGauge(key []string, val float32) {} -func (*BlackholeSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {} -func (*BlackholeSink) EmitKey(key []string, val float32) {} -func (*BlackholeSink) IncrCounter(key []string, val float32) {} -func (*BlackholeSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {} -func (*BlackholeSink) AddSample(key []string, val float32) {} -func (*BlackholeSink) AddSampleWithLabels(key []string, val float32, labels []Label) {} - -// FanoutSink is used to sink to fanout values to multiple sinks -type FanoutSink []MetricSink - -func (fh FanoutSink) SetGauge(key []string, val float32) { - fh.SetGaugeWithLabels(key, val, nil) -} - -func (fh FanoutSink) SetGaugeWithLabels(key []string, val float32, labels []Label) { - for _, s := range fh { - s.SetGaugeWithLabels(key, val, labels) - } -} - -func (fh FanoutSink) EmitKey(key []string, val float32) { - for _, s := range fh { - s.EmitKey(key, val) - } -} - -func (fh FanoutSink) IncrCounter(key []string, val float32) { - fh.IncrCounterWithLabels(key, val, nil) -} - -func (fh FanoutSink) IncrCounterWithLabels(key []string, val float32, labels []Label) { - for _, s := range fh { - s.IncrCounterWithLabels(key, val, labels) - } -} - -func (fh FanoutSink) AddSample(key []string, val float32) { - fh.AddSampleWithLabels(key, val, nil) -} - -func (fh FanoutSink) AddSampleWithLabels(key []string, val float32, labels []Label) { - for _, s := range fh { - s.AddSampleWithLabels(key, val, labels) - } -} - -func (fh FanoutSink) Shutdown() { - for _, s := range fh { - if ss, ok := s.(ShutdownSink); ok { - ss.Shutdown() - } - } -} - -// sinkURLFactoryFunc is an generic interface around the *SinkFromURL() function provided -// by each sink type -type sinkURLFactoryFunc func(*url.URL) (MetricSink, error) - -// sinkRegistry supports the generic NewMetricSink function by mapping URL -// schemes to metric sink factory functions -var sinkRegistry = map[string]sinkURLFactoryFunc{ - "statsd": NewStatsdSinkFromURL, - "statsite": NewStatsiteSinkFromURL, - "inmem": NewInmemSinkFromURL, -} - -// NewMetricSinkFromURL allows a generic URL input to configure any of the -// supported sinks. The scheme of the URL identifies the type of the sink, the -// and query parameters are used to set options. -// -// "statsd://" - Initializes a StatsdSink. The host and port are passed through -// as the "addr" of the sink -// -// "statsite://" - Initializes a StatsiteSink. The host and port become the -// "addr" of the sink -// -// "inmem://" - Initializes an InmemSink. The host and port are ignored. The -// "interval" and "duration" query parameters must be specified with valid -// durations, see NewInmemSink for details. -func NewMetricSinkFromURL(urlStr string) (MetricSink, error) { - u, err := url.Parse(urlStr) - if err != nil { - return nil, err - } - - sinkURLFactoryFunc := sinkRegistry[u.Scheme] - if sinkURLFactoryFunc == nil { - return nil, fmt.Errorf( - "cannot create metric sink, unrecognized sink name: %q", u.Scheme) - } - - return sinkURLFactoryFunc(u) -} diff --git a/vendor/github.com/armon/go-metrics/start.go b/vendor/github.com/armon/go-metrics/start.go deleted file mode 100644 index 38976f8dc9359..0000000000000 --- a/vendor/github.com/armon/go-metrics/start.go +++ /dev/null @@ -1,158 +0,0 @@ -package metrics - -import ( - "os" - "sync" - "sync/atomic" - "time" - - iradix "github.com/hashicorp/go-immutable-radix" -) - -// Config is used to configure metrics settings -type Config struct { - ServiceName string // Prefixed with keys to separate services - HostName string // Hostname to use. If not provided and EnableHostname, it will be os.Hostname - EnableHostname bool // Enable prefixing gauge values with hostname - EnableHostnameLabel bool // Enable adding hostname to labels - EnableServiceLabel bool // Enable adding service to labels - EnableRuntimeMetrics bool // Enables profiling of runtime metrics (GC, Goroutines, Memory) - EnableTypePrefix bool // Prefixes key with a type ("counter", "gauge", "timer") - TimerGranularity time.Duration // Granularity of timers. - ProfileInterval time.Duration // Interval to profile runtime metrics - - AllowedPrefixes []string // A list of metric prefixes to allow, with '.' as the separator - BlockedPrefixes []string // A list of metric prefixes to block, with '.' as the separator - AllowedLabels []string // A list of metric labels to allow, with '.' as the separator - BlockedLabels []string // A list of metric labels to block, with '.' as the separator - FilterDefault bool // Whether to allow metrics by default -} - -// Metrics represents an instance of a metrics sink that can -// be used to emit -type Metrics struct { - Config - lastNumGC uint32 - sink MetricSink - filter *iradix.Tree - allowedLabels map[string]bool - blockedLabels map[string]bool - filterLock sync.RWMutex // Lock filters and allowedLabels/blockedLabels access -} - -// Shared global metrics instance -var globalMetrics atomic.Value // *Metrics - -func init() { - // Initialize to a blackhole sink to avoid errors - globalMetrics.Store(&Metrics{sink: &BlackholeSink{}}) -} - -// Default returns the shared global metrics instance. -func Default() *Metrics { - return globalMetrics.Load().(*Metrics) -} - -// DefaultConfig provides a sane default configuration -func DefaultConfig(serviceName string) *Config { - c := &Config{ - ServiceName: serviceName, // Use client provided service - HostName: "", - EnableHostname: true, // Enable hostname prefix - EnableRuntimeMetrics: true, // Enable runtime profiling - EnableTypePrefix: false, // Disable type prefix - TimerGranularity: time.Millisecond, // Timers are in milliseconds - ProfileInterval: time.Second, // Poll runtime every second - FilterDefault: true, // Don't filter metrics by default - } - - // Try to get the hostname - name, _ := os.Hostname() - c.HostName = name - return c -} - -// New is used to create a new instance of Metrics -func New(conf *Config, sink MetricSink) (*Metrics, error) { - met := &Metrics{} - met.Config = *conf - met.sink = sink - met.UpdateFilterAndLabels(conf.AllowedPrefixes, conf.BlockedPrefixes, conf.AllowedLabels, conf.BlockedLabels) - - // Start the runtime collector - if conf.EnableRuntimeMetrics { - go met.collectStats() - } - return met, nil -} - -// NewGlobal is the same as New, but it assigns the metrics object to be -// used globally as well as returning it. -func NewGlobal(conf *Config, sink MetricSink) (*Metrics, error) { - metrics, err := New(conf, sink) - if err == nil { - globalMetrics.Store(metrics) - } - return metrics, err -} - -// Proxy all the methods to the globalMetrics instance -func SetGauge(key []string, val float32) { - globalMetrics.Load().(*Metrics).SetGauge(key, val) -} - -func SetGaugeWithLabels(key []string, val float32, labels []Label) { - globalMetrics.Load().(*Metrics).SetGaugeWithLabels(key, val, labels) -} - -func EmitKey(key []string, val float32) { - globalMetrics.Load().(*Metrics).EmitKey(key, val) -} - -func IncrCounter(key []string, val float32) { - globalMetrics.Load().(*Metrics).IncrCounter(key, val) -} - -func IncrCounterWithLabels(key []string, val float32, labels []Label) { - globalMetrics.Load().(*Metrics).IncrCounterWithLabels(key, val, labels) -} - -func AddSample(key []string, val float32) { - globalMetrics.Load().(*Metrics).AddSample(key, val) -} - -func AddSampleWithLabels(key []string, val float32, labels []Label) { - globalMetrics.Load().(*Metrics).AddSampleWithLabels(key, val, labels) -} - -func MeasureSince(key []string, start time.Time) { - globalMetrics.Load().(*Metrics).MeasureSince(key, start) -} - -func MeasureSinceWithLabels(key []string, start time.Time, labels []Label) { - globalMetrics.Load().(*Metrics).MeasureSinceWithLabels(key, start, labels) -} - -func UpdateFilter(allow, block []string) { - globalMetrics.Load().(*Metrics).UpdateFilter(allow, block) -} - -// UpdateFilterAndLabels set allow/block prefixes of metrics while allowedLabels -// and blockedLabels - when not nil - allow filtering of labels in order to -// block/allow globally labels (especially useful when having large number of -// values for a given label). See README.md for more information about usage. -func UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels []string) { - globalMetrics.Load().(*Metrics).UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels) -} - -// Shutdown disables metric collection, then blocks while attempting to flush metrics to storage. -// WARNING: Not all MetricSink backends support this functionality, and calling this will cause them to leak resources. -// This is intended for use immediately prior to application exit. -func Shutdown() { - m := globalMetrics.Load().(*Metrics) - // Swap whatever MetricSink is currently active with a BlackholeSink. Callers must not have a - // reason to expect that calls to the library will successfully collect metrics after Shutdown - // has been called. - globalMetrics.Store(&Metrics{sink: &BlackholeSink{}}) - m.Shutdown() -} diff --git a/vendor/github.com/armon/go-metrics/statsd.go b/vendor/github.com/armon/go-metrics/statsd.go deleted file mode 100644 index 1bfffce46e217..0000000000000 --- a/vendor/github.com/armon/go-metrics/statsd.go +++ /dev/null @@ -1,184 +0,0 @@ -package metrics - -import ( - "bytes" - "fmt" - "log" - "net" - "net/url" - "strings" - "time" -) - -const ( - // statsdMaxLen is the maximum size of a packet - // to send to statsd - statsdMaxLen = 1400 -) - -// StatsdSink provides a MetricSink that can be used -// with a statsite or statsd metrics server. It uses -// only UDP packets, while StatsiteSink uses TCP. -type StatsdSink struct { - addr string - metricQueue chan string -} - -// NewStatsdSinkFromURL creates an StatsdSink from a URL. It is used -// (and tested) from NewMetricSinkFromURL. -func NewStatsdSinkFromURL(u *url.URL) (MetricSink, error) { - return NewStatsdSink(u.Host) -} - -// NewStatsdSink is used to create a new StatsdSink -func NewStatsdSink(addr string) (*StatsdSink, error) { - s := &StatsdSink{ - addr: addr, - metricQueue: make(chan string, 4096), - } - go s.flushMetrics() - return s, nil -} - -// Close is used to stop flushing to statsd -func (s *StatsdSink) Shutdown() { - close(s.metricQueue) -} - -func (s *StatsdSink) SetGauge(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val)) -} - -func (s *StatsdSink) SetGaugeWithLabels(key []string, val float32, labels []Label) { - flatKey := s.flattenKeyLabels(key, labels) - s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val)) -} - -func (s *StatsdSink) EmitKey(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|kv\n", flatKey, val)) -} - -func (s *StatsdSink) IncrCounter(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val)) -} - -func (s *StatsdSink) IncrCounterWithLabels(key []string, val float32, labels []Label) { - flatKey := s.flattenKeyLabels(key, labels) - s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val)) -} - -func (s *StatsdSink) AddSample(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val)) -} - -func (s *StatsdSink) AddSampleWithLabels(key []string, val float32, labels []Label) { - flatKey := s.flattenKeyLabels(key, labels) - s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val)) -} - -// Flattens the key for formatting, removes spaces -func (s *StatsdSink) flattenKey(parts []string) string { - joined := strings.Join(parts, ".") - return strings.Map(func(r rune) rune { - switch r { - case ':': - fallthrough - case ' ': - return '_' - default: - return r - } - }, joined) -} - -// Flattens the key along with labels for formatting, removes spaces -func (s *StatsdSink) flattenKeyLabels(parts []string, labels []Label) string { - for _, label := range labels { - parts = append(parts, label.Value) - } - return s.flattenKey(parts) -} - -// Does a non-blocking push to the metrics queue -func (s *StatsdSink) pushMetric(m string) { - select { - case s.metricQueue <- m: - default: - } -} - -// Flushes metrics -func (s *StatsdSink) flushMetrics() { - var sock net.Conn - var err error - var wait <-chan time.Time - ticker := time.NewTicker(flushInterval) - defer ticker.Stop() - -CONNECT: - // Create a buffer - buf := bytes.NewBuffer(nil) - - // Attempt to connect - sock, err = net.Dial("udp", s.addr) - if err != nil { - log.Printf("[ERR] Error connecting to statsd! Err: %s", err) - goto WAIT - } - - for { - select { - case metric, ok := <-s.metricQueue: - // Get a metric from the queue - if !ok { - goto QUIT - } - - // Check if this would overflow the packet size - if len(metric)+buf.Len() > statsdMaxLen { - _, err := sock.Write(buf.Bytes()) - buf.Reset() - if err != nil { - log.Printf("[ERR] Error writing to statsd! Err: %s", err) - goto WAIT - } - } - - // Append to the buffer - buf.WriteString(metric) - - case <-ticker.C: - if buf.Len() == 0 { - continue - } - - _, err := sock.Write(buf.Bytes()) - buf.Reset() - if err != nil { - log.Printf("[ERR] Error flushing to statsd! Err: %s", err) - goto WAIT - } - } - } - -WAIT: - // Wait for a while - wait = time.After(time.Duration(5) * time.Second) - for { - select { - // Dequeue the messages to avoid backlog - case _, ok := <-s.metricQueue: - if !ok { - goto QUIT - } - case <-wait: - goto CONNECT - } - } -QUIT: - s.metricQueue = nil -} diff --git a/vendor/github.com/armon/go-metrics/statsite.go b/vendor/github.com/armon/go-metrics/statsite.go deleted file mode 100644 index 6c0d284d2ddb8..0000000000000 --- a/vendor/github.com/armon/go-metrics/statsite.go +++ /dev/null @@ -1,172 +0,0 @@ -package metrics - -import ( - "bufio" - "fmt" - "log" - "net" - "net/url" - "strings" - "time" -) - -const ( - // We force flush the statsite metrics after this period of - // inactivity. Prevents stats from getting stuck in a buffer - // forever. - flushInterval = 100 * time.Millisecond -) - -// NewStatsiteSinkFromURL creates an StatsiteSink from a URL. It is used -// (and tested) from NewMetricSinkFromURL. -func NewStatsiteSinkFromURL(u *url.URL) (MetricSink, error) { - return NewStatsiteSink(u.Host) -} - -// StatsiteSink provides a MetricSink that can be used with a -// statsite metrics server -type StatsiteSink struct { - addr string - metricQueue chan string -} - -// NewStatsiteSink is used to create a new StatsiteSink -func NewStatsiteSink(addr string) (*StatsiteSink, error) { - s := &StatsiteSink{ - addr: addr, - metricQueue: make(chan string, 4096), - } - go s.flushMetrics() - return s, nil -} - -// Close is used to stop flushing to statsite -func (s *StatsiteSink) Shutdown() { - close(s.metricQueue) -} - -func (s *StatsiteSink) SetGauge(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val)) -} - -func (s *StatsiteSink) SetGaugeWithLabels(key []string, val float32, labels []Label) { - flatKey := s.flattenKeyLabels(key, labels) - s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val)) -} - -func (s *StatsiteSink) EmitKey(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|kv\n", flatKey, val)) -} - -func (s *StatsiteSink) IncrCounter(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val)) -} - -func (s *StatsiteSink) IncrCounterWithLabels(key []string, val float32, labels []Label) { - flatKey := s.flattenKeyLabels(key, labels) - s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val)) -} - -func (s *StatsiteSink) AddSample(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val)) -} - -func (s *StatsiteSink) AddSampleWithLabels(key []string, val float32, labels []Label) { - flatKey := s.flattenKeyLabels(key, labels) - s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val)) -} - -// Flattens the key for formatting, removes spaces -func (s *StatsiteSink) flattenKey(parts []string) string { - joined := strings.Join(parts, ".") - return strings.Map(func(r rune) rune { - switch r { - case ':': - fallthrough - case ' ': - return '_' - default: - return r - } - }, joined) -} - -// Flattens the key along with labels for formatting, removes spaces -func (s *StatsiteSink) flattenKeyLabels(parts []string, labels []Label) string { - for _, label := range labels { - parts = append(parts, label.Value) - } - return s.flattenKey(parts) -} - -// Does a non-blocking push to the metrics queue -func (s *StatsiteSink) pushMetric(m string) { - select { - case s.metricQueue <- m: - default: - } -} - -// Flushes metrics -func (s *StatsiteSink) flushMetrics() { - var sock net.Conn - var err error - var wait <-chan time.Time - var buffered *bufio.Writer - ticker := time.NewTicker(flushInterval) - defer ticker.Stop() - -CONNECT: - // Attempt to connect - sock, err = net.Dial("tcp", s.addr) - if err != nil { - log.Printf("[ERR] Error connecting to statsite! Err: %s", err) - goto WAIT - } - - // Create a buffered writer - buffered = bufio.NewWriter(sock) - - for { - select { - case metric, ok := <-s.metricQueue: - // Get a metric from the queue - if !ok { - goto QUIT - } - - // Try to send to statsite - _, err := buffered.Write([]byte(metric)) - if err != nil { - log.Printf("[ERR] Error writing to statsite! Err: %s", err) - goto WAIT - } - case <-ticker.C: - if err := buffered.Flush(); err != nil { - log.Printf("[ERR] Error flushing to statsite! Err: %s", err) - goto WAIT - } - } - } - -WAIT: - // Wait for a while - wait = time.After(time.Duration(5) * time.Second) - for { - select { - // Dequeue the messages to avoid backlog - case _, ok := <-s.metricQueue: - if !ok { - goto QUIT - } - case <-wait: - goto CONNECT - } - } -QUIT: - s.metricQueue = nil -} diff --git a/vendor/github.com/hashicorp/consul/api/.copywrite.hcl b/vendor/github.com/hashicorp/consul/api/.copywrite.hcl deleted file mode 100644 index 7e4c0b58a8a36..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/.copywrite.hcl +++ /dev/null @@ -1,8 +0,0 @@ -schema_version = 1 - -project { - license = "MPL-2.0" - copyright_year = 2024 - - header_ignore = [] -} diff --git a/vendor/github.com/hashicorp/consul/api/LICENSE b/vendor/github.com/hashicorp/consul/api/LICENSE deleted file mode 100644 index 7c5baa45e1c29..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/LICENSE +++ /dev/null @@ -1,365 +0,0 @@ -Copyright (c) 2020 HashiCorp, Inc. - -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. "Contributor" - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. "Contributor Version" - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. - -1.6. "Executable Form" - - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. - -1.8. "License" - - means this document. - -1.9. "Licensable" - - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. - -1.10. "Modifications" - - means any of the following: - - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. "Patent Claims" of a Contributor - - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. - -1.12. "Secondary License" - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. "Source Code Form" - - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. - - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice - - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. - diff --git a/vendor/github.com/hashicorp/consul/api/README.md b/vendor/github.com/hashicorp/consul/api/README.md deleted file mode 100644 index 96a867f279dfb..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# Consul API Client - -This package provides the `api` package which provides programmatic access to the full Consul API. - -The full documentation is available on [Godoc](https://godoc.org/github.com/hashicorp/consul/api). - -## Usage - -Below is an example of using the Consul client. To run the example, you must first -[install Consul](https://developer.hashicorp.com/consul/downloads) and -[Go](https://go.dev/doc/install). - -To run the client API, create a new Go module. - -```shell -go mod init consul-demo -``` - -Copy the example code into a file called `main.go` in the directory where the module is defined. -As seen in the example, the Consul API is often imported with the alias `capi`. - -```go -package main - -import ( - "fmt" - - capi "github.com/hashicorp/consul/api" -) - -func main() { - // Get a new client - client, err := capi.NewClient(capi.DefaultConfig()) - if err != nil { - panic(err) - } - - // Get a handle to the KV API - kv := client.KV() - - // PUT a new KV pair - p := &capi.KVPair{Key: "REDIS_MAXCLIENTS", Value: []byte("1000")} - _, err = kv.Put(p, nil) - if err != nil { - panic(err) - } - - // Lookup the pair - pair, _, err := kv.Get("REDIS_MAXCLIENTS", nil) - if err != nil { - panic(err) - } - fmt.Printf("KV: %v %s\n", pair.Key, pair.Value) -} -``` - -Install the Consul API dependency with `go mod tidy`. - -In a separate terminal window, start a local Consul server. - -```shell -consul agent -dev -node machine -``` - -Run the example. - -```shell -go run . -``` - -You should get the following result printed to the terminal. - -```shell -KV: REDIS_MAXCLIENTS 1000 -``` - -After running the code, you can also view the values in the Consul UI on your local machine at http://localhost:8500/ui/dc1/kv diff --git a/vendor/github.com/hashicorp/consul/api/acl.go b/vendor/github.com/hashicorp/consul/api/acl.go deleted file mode 100644 index fcea0fdde0828..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/acl.go +++ /dev/null @@ -1,1744 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "encoding/json" - "fmt" - "io" - "net/url" - "time" - - "github.com/mitchellh/mapstructure" -) - -const ( - // ACLClientType is the client type token - ACLClientType = "client" - - // ACLManagementType is the management type token - ACLManagementType = "management" - - // ACLTemplatedPolicy names - ACLTemplatedPolicyServiceName = "builtin/service" - ACLTemplatedPolicyNodeName = "builtin/node" - ACLTemplatedPolicyDNSName = "builtin/dns" - ACLTemplatedPolicyNomadServerName = "builtin/nomad-server" - ACLTemplatedPolicyWorkloadIdentityName = "builtin/workload-identity" - ACLTemplatedPolicyAPIGatewayName = "builtin/api-gateway" - ACLTemplatedPolicyNomadClientName = "builtin/nomad-client" -) - -type ACLLink struct { - ID string - Name string -} - -type ACLTokenPolicyLink = ACLLink -type ACLTokenRoleLink = ACLLink - -// ACLToken represents an ACL Token -type ACLToken struct { - CreateIndex uint64 - ModifyIndex uint64 - AccessorID string - SecretID string - Description string - Policies []*ACLTokenPolicyLink `json:",omitempty"` - Roles []*ACLTokenRoleLink `json:",omitempty"` - ServiceIdentities []*ACLServiceIdentity `json:",omitempty"` - NodeIdentities []*ACLNodeIdentity `json:",omitempty"` - TemplatedPolicies []*ACLTemplatedPolicy `json:",omitempty"` - Local bool - AuthMethod string `json:",omitempty"` - ExpirationTTL time.Duration `json:",omitempty"` - ExpirationTime *time.Time `json:",omitempty"` - CreateTime time.Time `json:",omitempty"` - Hash []byte `json:",omitempty"` - - // DEPRECATED (ACL-Legacy-Compat) - // Rules are an artifact of legacy tokens deprecated in Consul 1.4 - Rules string `json:"-"` - - // Namespace is the namespace the ACLToken is associated with. - // Namespaces are a Consul Enterprise feature. - Namespace string `json:",omitempty"` - - // Partition is the partition the ACLToken is associated with. - // Partitions are a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // AuthMethodNamespace is the namespace the token's AuthMethod is associated with. - // Namespacing is a Consul Enterprise feature. - AuthMethodNamespace string `json:",omitempty"` -} - -type ACLTokenExpanded struct { - ExpandedPolicies []ACLPolicy - ExpandedRoles []ACLRole - - NamespaceDefaultPolicyIDs []string - NamespaceDefaultRoleIDs []string - - AgentACLDefaultPolicy string - AgentACLDownPolicy string - ResolvedByAgent string - - ACLToken -} - -type ACLTokenListEntry struct { - CreateIndex uint64 - ModifyIndex uint64 - AccessorID string - SecretID string - Description string - Policies []*ACLTokenPolicyLink `json:",omitempty"` - Roles []*ACLTokenRoleLink `json:",omitempty"` - ServiceIdentities []*ACLServiceIdentity `json:",omitempty"` - NodeIdentities []*ACLNodeIdentity `json:",omitempty"` - TemplatedPolicies []*ACLTemplatedPolicy `json:",omitempty"` - Local bool - AuthMethod string `json:",omitempty"` - ExpirationTime *time.Time `json:",omitempty"` - CreateTime time.Time - Hash []byte - Legacy bool `json:"-"` // DEPRECATED - - // Namespace is the namespace the ACLTokenListEntry is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` - - // Partition is the partition the ACLTokenListEntry is associated with. - // Partitions are a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // AuthMethodNamespace is the namespace the token's AuthMethod is associated with. - // Namespacing is a Consul Enterprise feature. - AuthMethodNamespace string `json:",omitempty"` -} - -// ACLEntry is used to represent a legacy ACL token -// The legacy tokens are deprecated. -type ACLEntry struct { - CreateIndex uint64 - ModifyIndex uint64 - ID string - Name string - Type string - Rules string -} - -// ACLReplicationStatus is used to represent the status of ACL replication. -type ACLReplicationStatus struct { - Enabled bool - Running bool - SourceDatacenter string - ReplicationType string - ReplicatedIndex uint64 - ReplicatedRoleIndex uint64 - ReplicatedTokenIndex uint64 - LastSuccess time.Time - LastError time.Time - LastErrorMessage string -} - -// ACLServiceIdentity represents a high-level grant of all necessary privileges -// to assume the identity of the named Service in the Catalog and within -// Connect. -type ACLServiceIdentity struct { - ServiceName string - Datacenters []string `json:",omitempty"` -} - -// ACLNodeIdentity represents a high-level grant of all necessary privileges -// to assume the identity of the named Node in the Catalog and within Connect. -type ACLNodeIdentity struct { - NodeName string - Datacenter string -} - -// ACLTemplatedPolicy represents a template used to generate a `synthetic` policy -// given some input variables. -type ACLTemplatedPolicy struct { - TemplateName string - TemplateVariables *ACLTemplatedPolicyVariables `json:",omitempty"` - - // Datacenters are an artifact of Nodeidentity & ServiceIdentity. - // It is used to facilitate the future migration away from both - Datacenters []string `json:",omitempty"` -} - -type ACLTemplatedPolicyResponse struct { - TemplateName string - Schema string - Template string - Description string -} - -type ACLTemplatedPolicyVariables struct { - Name string -} - -// ACLPolicy represents an ACL Policy. -type ACLPolicy struct { - ID string - Name string - Description string - Rules string - Datacenters []string - Hash []byte - CreateIndex uint64 - ModifyIndex uint64 - - // Namespace is the namespace the ACLPolicy is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` - - // Partition is the partition the ACLPolicy is associated with. - // Partitions are a Consul Enterprise feature. - Partition string `json:",omitempty"` -} - -type ACLPolicyListEntry struct { - ID string - Name string - Description string - Datacenters []string - Hash []byte - CreateIndex uint64 - ModifyIndex uint64 - - // Namespace is the namespace the ACLPolicyListEntry is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` - - // Partition is the partition the ACLPolicyListEntry is associated with. - // Partitions are a Consul Enterprise feature. - Partition string `json:",omitempty"` -} - -type ACLRolePolicyLink = ACLLink - -// ACLRole represents an ACL Role. -type ACLRole struct { - ID string - Name string - Description string - Policies []*ACLRolePolicyLink `json:",omitempty"` - ServiceIdentities []*ACLServiceIdentity `json:",omitempty"` - NodeIdentities []*ACLNodeIdentity `json:",omitempty"` - TemplatedPolicies []*ACLTemplatedPolicy `json:",omitempty"` - Hash []byte - CreateIndex uint64 - ModifyIndex uint64 - - // Namespace is the namespace the ACLRole is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` - - // Partition is the partition the ACLRole is associated with. - // Partitions are a Consul Enterprise feature. - Partition string `json:",omitempty"` -} - -// BindingRuleBindType is the type of binding rule mechanism used. -type BindingRuleBindType string - -const ( - // BindingRuleBindTypeService binds to a service identity with the given name. - BindingRuleBindTypeService BindingRuleBindType = "service" - - // BindingRuleBindTypeRole binds to pre-existing roles with the given name. - BindingRuleBindTypeRole BindingRuleBindType = "role" - - // BindingRuleBindTypeNode binds to a node identity with given name. - BindingRuleBindTypeNode BindingRuleBindType = "node" - - // BindingRuleBindTypePolicy binds to a specific policy with given name. - BindingRuleBindTypePolicy BindingRuleBindType = "policy" - - // BindingRuleBindTypeTemplatedPolicy binds to a templated policy with given template name and variables. - BindingRuleBindTypeTemplatedPolicy BindingRuleBindType = "templated-policy" -) - -type ACLBindingRule struct { - ID string - Description string - AuthMethod string - Selector string - BindType BindingRuleBindType - BindName string - BindVars *ACLTemplatedPolicyVariables `json:",omitempty"` - - CreateIndex uint64 - ModifyIndex uint64 - - // Namespace is the namespace the ACLBindingRule is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` - - // Partition is the partition the ACLBindingRule is associated with. - // Partitions are a Consul Enterprise feature. - Partition string `json:",omitempty"` -} - -type ACLAuthMethod struct { - Name string - Type string - DisplayName string `json:",omitempty"` - Description string `json:",omitempty"` - MaxTokenTTL time.Duration `json:",omitempty"` - - // TokenLocality defines the kind of token that this auth method produces. - // This can be either 'local' or 'global'. If empty 'local' is assumed. - TokenLocality string `json:",omitempty"` - - // Configuration is arbitrary configuration for the auth method. This - // should only contain primitive values and containers (such as lists and - // maps). - Config map[string]interface{} - - CreateIndex uint64 - ModifyIndex uint64 - - // NamespaceRules apply only on auth methods defined in the default namespace. - // Namespacing is a Consul Enterprise feature. - NamespaceRules []*ACLAuthMethodNamespaceRule `json:",omitempty"` - - // Namespace is the namespace the ACLAuthMethod is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` - - // Partition is the partition the ACLAuthMethod is associated with. - // Partitions are a Consul Enterprise feature. - Partition string `json:",omitempty"` -} - -type ACLTokenFilterOptions struct { - AuthMethod string `json:",omitempty"` - Policy string `json:",omitempty"` - Role string `json:",omitempty"` - ServiceName string `json:",omitempty"` -} - -func (m *ACLAuthMethod) MarshalJSON() ([]byte, error) { - type Alias ACLAuthMethod - exported := &struct { - MaxTokenTTL string `json:",omitempty"` - *Alias - }{ - MaxTokenTTL: m.MaxTokenTTL.String(), - Alias: (*Alias)(m), - } - if m.MaxTokenTTL == 0 { - exported.MaxTokenTTL = "" - } - - return json.Marshal(exported) -} - -func (m *ACLAuthMethod) UnmarshalJSON(data []byte) error { - type Alias ACLAuthMethod - aux := &struct { - MaxTokenTTL string - *Alias - }{ - Alias: (*Alias)(m), - } - if err := json.Unmarshal(data, &aux); err != nil { - return err - } - var err error - if aux.MaxTokenTTL != "" { - if m.MaxTokenTTL, err = time.ParseDuration(aux.MaxTokenTTL); err != nil { - return err - } - } - - return nil -} - -type ACLAuthMethodNamespaceRule struct { - // Selector is an expression that matches against verified identity - // attributes returned from the auth method during login. - Selector string `json:",omitempty"` - - // BindNamespace is the target namespace of the binding. Can be lightly - // templated using HIL ${foo} syntax from available field names. - // - // If empty it's created in the same namespace as the auth method. - BindNamespace string `json:",omitempty"` -} - -type ACLAuthMethodListEntry struct { - Name string - Type string - DisplayName string `json:",omitempty"` - Description string `json:",omitempty"` - MaxTokenTTL time.Duration `json:",omitempty"` - - // TokenLocality defines the kind of token that this auth method produces. - // This can be either 'local' or 'global'. If empty 'local' is assumed. - TokenLocality string `json:",omitempty"` - CreateIndex uint64 - ModifyIndex uint64 - - // Namespace is the namespace the ACLAuthMethodListEntry is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` - - // Partition is the partition the ACLAuthMethodListEntry is associated with. - // Partitions are a Consul Enterprise feature. - Partition string `json:",omitempty"` -} - -// This is nearly identical to the ACLAuthMethod MarshalJSON -func (m *ACLAuthMethodListEntry) MarshalJSON() ([]byte, error) { - type Alias ACLAuthMethodListEntry - exported := &struct { - MaxTokenTTL string `json:",omitempty"` - *Alias - }{ - MaxTokenTTL: m.MaxTokenTTL.String(), - Alias: (*Alias)(m), - } - if m.MaxTokenTTL == 0 { - exported.MaxTokenTTL = "" - } - - return json.Marshal(exported) -} - -// This is nearly identical to the ACLAuthMethod UnmarshalJSON -func (m *ACLAuthMethodListEntry) UnmarshalJSON(data []byte) error { - type Alias ACLAuthMethodListEntry - aux := &struct { - MaxTokenTTL string - *Alias - }{ - Alias: (*Alias)(m), - } - - if err := json.Unmarshal(data, &aux); err != nil { - return err - } - var err error - if aux.MaxTokenTTL != "" { - if m.MaxTokenTTL, err = time.ParseDuration(aux.MaxTokenTTL); err != nil { - return err - } - } - - return nil -} - -// ParseKubernetesAuthMethodConfig takes a raw config map and returns a parsed -// KubernetesAuthMethodConfig. -func ParseKubernetesAuthMethodConfig(raw map[string]interface{}) (*KubernetesAuthMethodConfig, error) { - var config KubernetesAuthMethodConfig - decodeConf := &mapstructure.DecoderConfig{ - Result: &config, - WeaklyTypedInput: true, - } - - decoder, err := mapstructure.NewDecoder(decodeConf) - if err != nil { - return nil, err - } - - if err := decoder.Decode(raw); err != nil { - return nil, fmt.Errorf("error decoding config: %s", err) - } - - return &config, nil -} - -// KubernetesAuthMethodConfig is the config for the built-in Consul auth method -// for Kubernetes. -type KubernetesAuthMethodConfig struct { - Host string `json:",omitempty"` - CACert string `json:",omitempty"` - ServiceAccountJWT string `json:",omitempty"` -} - -// RenderToConfig converts this into a map[string]interface{} suitable for use -// in the ACLAuthMethod.Config field. -func (c *KubernetesAuthMethodConfig) RenderToConfig() map[string]interface{} { - return map[string]interface{}{ - "Host": c.Host, - "CACert": c.CACert, - "ServiceAccountJWT": c.ServiceAccountJWT, - } -} - -// OIDCAuthMethodConfig is the config for the built-in Consul auth method for -// OIDC and JWT. -type OIDCAuthMethodConfig struct { - // common for type=oidc and type=jwt - JWTSupportedAlgs []string `json:",omitempty"` - BoundAudiences []string `json:",omitempty"` - ClaimMappings map[string]string `json:",omitempty"` - ListClaimMappings map[string]string `json:",omitempty"` - OIDCDiscoveryURL string `json:",omitempty"` - OIDCDiscoveryCACert string `json:",omitempty"` - // just for type=oidc - OIDCClientID string `json:",omitempty"` - OIDCClientSecret string `json:",omitempty"` - OIDCScopes []string `json:",omitempty"` - OIDCACRValues []string `json:",omitempty"` - AllowedRedirectURIs []string `json:",omitempty"` - VerboseOIDCLogging bool `json:",omitempty"` - // just for type=jwt - JWKSURL string `json:",omitempty"` - JWKSCACert string `json:",omitempty"` - JWTValidationPubKeys []string `json:",omitempty"` - BoundIssuer string `json:",omitempty"` - ExpirationLeeway time.Duration `json:",omitempty"` - NotBeforeLeeway time.Duration `json:",omitempty"` - ClockSkewLeeway time.Duration `json:",omitempty"` -} - -// RenderToConfig converts this into a map[string]interface{} suitable for use -// in the ACLAuthMethod.Config field. -func (c *OIDCAuthMethodConfig) RenderToConfig() map[string]interface{} { - return map[string]interface{}{ - // common for type=oidc and type=jwt - "JWTSupportedAlgs": c.JWTSupportedAlgs, - "BoundAudiences": c.BoundAudiences, - "ClaimMappings": c.ClaimMappings, - "ListClaimMappings": c.ListClaimMappings, - "OIDCDiscoveryURL": c.OIDCDiscoveryURL, - "OIDCDiscoveryCACert": c.OIDCDiscoveryCACert, - // just for type=oidc - "OIDCClientID": c.OIDCClientID, - "OIDCClientSecret": c.OIDCClientSecret, - "OIDCScopes": c.OIDCScopes, - "OIDCACRValues": c.OIDCACRValues, - "AllowedRedirectURIs": c.AllowedRedirectURIs, - "VerboseOIDCLogging": c.VerboseOIDCLogging, - // just for type=jwt - "JWKSURL": c.JWKSURL, - "JWKSCACert": c.JWKSCACert, - "JWTValidationPubKeys": c.JWTValidationPubKeys, - "BoundIssuer": c.BoundIssuer, - "ExpirationLeeway": c.ExpirationLeeway, - "NotBeforeLeeway": c.NotBeforeLeeway, - "ClockSkewLeeway": c.ClockSkewLeeway, - } -} - -type ACLLoginParams struct { - AuthMethod string - BearerToken string - Meta map[string]string `json:",omitempty"` -} - -type ACLOIDCAuthURLParams struct { - AuthMethod string - RedirectURI string - ClientNonce string - Meta map[string]string `json:",omitempty"` -} - -// ACL can be used to query the ACL endpoints -type ACL struct { - c *Client -} - -// ACL returns a handle to the ACL endpoints -func (c *Client) ACL() *ACL { - return &ACL{c} -} - -// BootstrapRequest is used for when operators provide an ACL Bootstrap Token -type BootstrapRequest struct { - BootstrapSecret string -} - -// Bootstrap is used to perform a one-time ACL bootstrap operation on a cluster -// to get the first management token. -func (a *ACL) Bootstrap() (*ACLToken, *WriteMeta, error) { - return a.BootstrapWithToken("") -} - -// BootstrapWithToken is used to get the initial bootstrap token or pass in the one that was provided in the API -func (a *ACL) BootstrapWithToken(btoken string) (*ACLToken, *WriteMeta, error) { - r := a.c.newRequest("PUT", "/v1/acl/bootstrap") - if btoken != "" { - r.obj = &BootstrapRequest{ - BootstrapSecret: btoken, - } - } - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLToken - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return &out, wm, nil -} - -// Create is used to generate a new token with the given parameters -// -// Deprecated: Use TokenCreate instead. -func (a *ACL) Create(acl *ACLEntry, q *WriteOptions) (string, *WriteMeta, error) { - r := a.c.newRequest("PUT", "/v1/acl/create") - r.setWriteOptions(q) - r.obj = acl - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return "", nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return "", nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - var out struct{ ID string } - if err := decodeBody(resp, &out); err != nil { - return "", nil, err - } - return out.ID, wm, nil -} - -// Update is used to update the rules of an existing token -// -// Deprecated: Use TokenUpdate instead. -func (a *ACL) Update(acl *ACLEntry, q *WriteOptions) (*WriteMeta, error) { - r := a.c.newRequest("PUT", "/v1/acl/update") - r.setWriteOptions(q) - r.obj = acl - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - wm := &WriteMeta{RequestTime: rtt} - return wm, nil -} - -// Destroy is used to destroy a given ACL token ID -// -// Deprecated: Use TokenDelete instead. -func (a *ACL) Destroy(id string, q *WriteOptions) (*WriteMeta, error) { - r := a.c.newRequest("PUT", "/v1/acl/destroy/"+id) - r.setWriteOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - if err := requireOK(resp); err != nil { - return nil, err - } - closeResponseBody(resp) - - wm := &WriteMeta{RequestTime: rtt} - return wm, nil -} - -// Clone is used to return a new token cloned from an existing one -// -// Deprecated: Use TokenClone instead. -func (a *ACL) Clone(id string, q *WriteOptions) (string, *WriteMeta, error) { - r := a.c.newRequest("PUT", "/v1/acl/clone/"+id) - r.setWriteOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return "", nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return "", nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - var out struct{ ID string } - if err := decodeBody(resp, &out); err != nil { - return "", nil, err - } - return out.ID, wm, nil -} - -// Info is used to query for information about an ACL token -// -// Deprecated: Use TokenRead instead. -func (a *ACL) Info(id string, q *QueryOptions) (*ACLEntry, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/info/"+id) - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var entries []*ACLEntry - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, err - } - if len(entries) > 0 { - return entries[0], qm, nil - } - return nil, qm, nil -} - -// List is used to get all the ACL tokens -// -// Deprecated: Use TokenList instead. -func (a *ACL) List(q *QueryOptions) ([]*ACLEntry, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/list") - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var entries []*ACLEntry - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, err - } - return entries, qm, nil -} - -// Replication returns the status of the ACL replication process in the datacenter -func (a *ACL) Replication(q *QueryOptions) (*ACLReplicationStatus, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/replication") - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var entries *ACLReplicationStatus - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, err - } - return entries, qm, nil -} - -// TokenCreate creates a new ACL token. If either the AccessorID or SecretID fields -// of the ACLToken structure are empty they will be filled in by Consul. -func (a *ACL) TokenCreate(token *ACLToken, q *WriteOptions) (*ACLToken, *WriteMeta, error) { - r := a.c.newRequest("PUT", "/v1/acl/token") - r.setWriteOptions(q) - r.obj = token - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLToken - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -// TokenUpdate updates a token in place without modifying its AccessorID or SecretID. A valid -// AccessorID must be set in the ACLToken structure passed to this function but the SecretID may -// be omitted and will be filled in by Consul with its existing value. -func (a *ACL) TokenUpdate(token *ACLToken, q *WriteOptions) (*ACLToken, *WriteMeta, error) { - if token.AccessorID == "" { - return nil, nil, fmt.Errorf("Must specify an AccessorID for Token Updating") - } - r := a.c.newRequest("PUT", "/v1/acl/token/"+token.AccessorID) - r.setWriteOptions(q) - r.obj = token - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLToken - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -// TokenClone will create a new token with the same policies and locality as the original -// token but will have its own auto-generated AccessorID and SecretID as well having the -// description passed to this function. The accessorID parameter must be a valid Accessor ID -// of an existing token. -func (a *ACL) TokenClone(accessorID string, description string, q *WriteOptions) (*ACLToken, *WriteMeta, error) { - if accessorID == "" { - return nil, nil, fmt.Errorf("Must specify a token AccessorID for Token Cloning") - } - - r := a.c.newRequest("PUT", "/v1/acl/token/"+accessorID+"/clone") - r.setWriteOptions(q) - r.obj = struct{ Description string }{description} - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLToken - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -// TokenDelete removes a single ACL token. The accessorID parameter must be a valid -// Accessor ID of an existing token. -func (a *ACL) TokenDelete(accessorID string, q *WriteOptions) (*WriteMeta, error) { - r := a.c.newRequest("DELETE", "/v1/acl/token/"+accessorID) - r.setWriteOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - if err := requireOK(resp); err != nil { - return nil, err - } - closeResponseBody(resp) - - wm := &WriteMeta{RequestTime: rtt} - return wm, nil -} - -// TokenRead retrieves the full token details. The accessorID parameter must be a valid -// Accessor ID of an existing token. -func (a *ACL) TokenRead(accessorID string, q *QueryOptions) (*ACLToken, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/token/"+accessorID) - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out ACLToken - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, qm, nil -} - -// TokenReadExpanded retrieves the full token details, as well as the contents of any policies affecting the token. -// The accessorID parameter must be a valid Accessor ID of an existing token. -func (a *ACL) TokenReadExpanded(accessorID string, q *QueryOptions) (*ACLTokenExpanded, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/token/"+accessorID) - r.setQueryOptions(q) - r.params.Set("expanded", "true") - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out ACLTokenExpanded - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, qm, nil -} - -// TokenReadSelf retrieves the full token details of the token currently -// assigned to the API Client. In this manner its possible to read a token -// by its Secret ID. -func (a *ACL) TokenReadSelf(q *QueryOptions) (*ACLToken, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/token/self") - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out ACLToken - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, qm, nil -} - -// TokenList lists all tokens. The listing does not contain any SecretIDs as those -// may only be retrieved by a call to TokenRead. -func (a *ACL) TokenList(q *QueryOptions) ([]*ACLTokenListEntry, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/tokens") - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var entries []*ACLTokenListEntry - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, err - } - return entries, qm, nil -} - -// TokenListFiltered lists all tokens that match the given filter options. -// The listing does not contain any SecretIDs as those may only be retrieved by a call to TokenRead. -func (a *ACL) TokenListFiltered(t ACLTokenFilterOptions, q *QueryOptions) ([]*ACLTokenListEntry, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/tokens") - r.setQueryOptions(q) - - if t.AuthMethod != "" { - r.params.Set("authmethod", t.AuthMethod) - } - if t.Policy != "" { - r.params.Set("policy", t.Policy) - } - if t.Role != "" { - r.params.Set("role", t.Role) - } - if t.ServiceName != "" { - r.params.Set("servicename", t.ServiceName) - } - - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var entries []*ACLTokenListEntry - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, err - } - return entries, qm, nil -} - -// PolicyCreate will create a new policy. It is not allowed for the policy parameters -// ID field to be set as this will be generated by Consul while processing the request. -func (a *ACL) PolicyCreate(policy *ACLPolicy, q *WriteOptions) (*ACLPolicy, *WriteMeta, error) { - if policy.ID != "" { - return nil, nil, fmt.Errorf("Cannot specify an ID in Policy Creation") - } - r := a.c.newRequest("PUT", "/v1/acl/policy") - r.setWriteOptions(q) - r.obj = policy - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLPolicy - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -// PolicyUpdate updates a policy. The ID field of the policy parameter must be set to an -// existing policy ID -func (a *ACL) PolicyUpdate(policy *ACLPolicy, q *WriteOptions) (*ACLPolicy, *WriteMeta, error) { - if policy.ID == "" { - return nil, nil, fmt.Errorf("Must specify an ID in Policy Update") - } - - r := a.c.newRequest("PUT", "/v1/acl/policy/"+policy.ID) - r.setWriteOptions(q) - r.obj = policy - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLPolicy - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -// PolicyDelete deletes a policy given its ID. -func (a *ACL) PolicyDelete(policyID string, q *WriteOptions) (*WriteMeta, error) { - r := a.c.newRequest("DELETE", "/v1/acl/policy/"+policyID) - r.setWriteOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - return wm, nil -} - -// PolicyRead retrieves the policy details including the rule set. -func (a *ACL) PolicyRead(policyID string, q *QueryOptions) (*ACLPolicy, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/policy/"+policyID) - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out ACLPolicy - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, qm, nil -} - -// PolicyReadByName retrieves the policy details including the rule set with name. -func (a *ACL) PolicyReadByName(policyName string, q *QueryOptions) (*ACLPolicy, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/policy/name/"+url.QueryEscape(policyName)) - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - found, resp, err := requireNotFoundOrOK(resp) - if err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if !found { - return nil, qm, nil - } - - var out ACLPolicy - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, qm, nil -} - -// PolicyList retrieves a listing of all policies. The listing does not include the -// rules for any policy as those should be retrieved by subsequent calls to PolicyRead. -func (a *ACL) PolicyList(q *QueryOptions) ([]*ACLPolicyListEntry, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/policies") - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var entries []*ACLPolicyListEntry - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, err - } - return entries, qm, nil -} - -// RulesTranslate translates the legacy rule syntax into the current syntax. -// -// Deprecated: Support for the legacy syntax translation has been removed. -// This function always returns an error. -func (a *ACL) RulesTranslate(rules io.Reader) (string, error) { - return "", fmt.Errorf("Legacy ACL rules were deprecated in Consul 1.4") -} - -// RulesTranslateToken translates the rules associated with the legacy syntax -// into the current syntax and returns the results. -// -// Deprecated: Support for the legacy syntax translation has been removed. -// This function always returns an error. -func (a *ACL) RulesTranslateToken(tokenID string) (string, error) { - return "", fmt.Errorf("Legacy ACL tokens and rules were deprecated in Consul 1.4") -} - -// RoleCreate will create a new role. It is not allowed for the role parameters -// ID field to be set as this will be generated by Consul while processing the request. -func (a *ACL) RoleCreate(role *ACLRole, q *WriteOptions) (*ACLRole, *WriteMeta, error) { - if role.ID != "" { - return nil, nil, fmt.Errorf("Cannot specify an ID in Role Creation") - } - - r := a.c.newRequest("PUT", "/v1/acl/role") - r.setWriteOptions(q) - r.obj = role - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLRole - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -// RoleUpdate updates a role. The ID field of the role parameter must be set to an -// existing role ID -func (a *ACL) RoleUpdate(role *ACLRole, q *WriteOptions) (*ACLRole, *WriteMeta, error) { - if role.ID == "" { - return nil, nil, fmt.Errorf("Must specify an ID in Role Update") - } - - r := a.c.newRequest("PUT", "/v1/acl/role/"+role.ID) - r.setWriteOptions(q) - r.obj = role - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLRole - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -// RoleDelete deletes a role given its ID. -func (a *ACL) RoleDelete(roleID string, q *WriteOptions) (*WriteMeta, error) { - r := a.c.newRequest("DELETE", "/v1/acl/role/"+roleID) - r.setWriteOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - if err := requireOK(resp); err != nil { - return nil, err - } - closeResponseBody(resp) - - wm := &WriteMeta{RequestTime: rtt} - return wm, nil -} - -// RoleRead retrieves the role details (by ID). Returns nil if not found. -func (a *ACL) RoleRead(roleID string, q *QueryOptions) (*ACLRole, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/role/"+roleID) - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - found, resp, err := requireNotFoundOrOK(resp) - if err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if !found { - return nil, qm, nil - } - - var out ACLRole - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, qm, nil -} - -// RoleReadByName retrieves the role details (by name). Returns nil if not found. -func (a *ACL) RoleReadByName(roleName string, q *QueryOptions) (*ACLRole, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/role/name/"+url.QueryEscape(roleName)) - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - found, resp, err := requireNotFoundOrOK(resp) - if err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if !found { - return nil, qm, nil - } - - var out ACLRole - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, qm, nil -} - -// RoleList retrieves a listing of all roles. The listing does not include some -// metadata for the role as those should be retrieved by subsequent calls to -// RoleRead. -func (a *ACL) RoleList(q *QueryOptions) ([]*ACLRole, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/roles") - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var entries []*ACLRole - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, err - } - return entries, qm, nil -} - -// AuthMethodCreate will create a new auth method. -func (a *ACL) AuthMethodCreate(method *ACLAuthMethod, q *WriteOptions) (*ACLAuthMethod, *WriteMeta, error) { - if method.Name == "" { - return nil, nil, fmt.Errorf("Must specify a Name in Auth Method Creation") - } - - r := a.c.newRequest("PUT", "/v1/acl/auth-method") - r.setWriteOptions(q) - r.obj = method - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLAuthMethod - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -// AuthMethodUpdate updates an auth method. -func (a *ACL) AuthMethodUpdate(method *ACLAuthMethod, q *WriteOptions) (*ACLAuthMethod, *WriteMeta, error) { - if method.Name == "" { - return nil, nil, fmt.Errorf("Must specify a Name in Auth Method Update") - } - - r := a.c.newRequest("PUT", "/v1/acl/auth-method/"+url.QueryEscape(method.Name)) - r.setWriteOptions(q) - r.obj = method - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLAuthMethod - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -// AuthMethodDelete deletes an auth method given its Name. -func (a *ACL) AuthMethodDelete(methodName string, q *WriteOptions) (*WriteMeta, error) { - if methodName == "" { - return nil, fmt.Errorf("Must specify a Name in Auth Method Delete") - } - - r := a.c.newRequest("DELETE", "/v1/acl/auth-method/"+url.QueryEscape(methodName)) - r.setWriteOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - if err := requireOK(resp); err != nil { - return nil, err - } - closeResponseBody(resp) - - wm := &WriteMeta{RequestTime: rtt} - return wm, nil -} - -// AuthMethodRead retrieves the auth method. Returns nil if not found. -func (a *ACL) AuthMethodRead(methodName string, q *QueryOptions) (*ACLAuthMethod, *QueryMeta, error) { - if methodName == "" { - return nil, nil, fmt.Errorf("Must specify a Name in Auth Method Read") - } - - r := a.c.newRequest("GET", "/v1/acl/auth-method/"+url.QueryEscape(methodName)) - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - found, resp, err := requireNotFoundOrOK(resp) - if err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if !found { - return nil, qm, nil - } - - var out ACLAuthMethod - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, qm, nil -} - -// AuthMethodList retrieves a listing of all auth methods. The listing does not -// include some metadata for the auth method as those should be retrieved by -// subsequent calls to AuthMethodRead. -func (a *ACL) AuthMethodList(q *QueryOptions) ([]*ACLAuthMethodListEntry, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/auth-methods") - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var entries []*ACLAuthMethodListEntry - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, err - } - return entries, qm, nil -} - -// BindingRuleCreate will create a new binding rule. It is not allowed for the -// binding rule parameter's ID field to be set as this will be generated by -// Consul while processing the request. -func (a *ACL) BindingRuleCreate(rule *ACLBindingRule, q *WriteOptions) (*ACLBindingRule, *WriteMeta, error) { - if rule.ID != "" { - return nil, nil, fmt.Errorf("Cannot specify an ID in Binding Rule Creation") - } - - r := a.c.newRequest("PUT", "/v1/acl/binding-rule") - r.setWriteOptions(q) - r.obj = rule - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLBindingRule - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -// BindingRuleUpdate updates a binding rule. The ID field of the role binding -// rule parameter must be set to an existing binding rule ID. -func (a *ACL) BindingRuleUpdate(rule *ACLBindingRule, q *WriteOptions) (*ACLBindingRule, *WriteMeta, error) { - if rule.ID == "" { - return nil, nil, fmt.Errorf("Must specify an ID in Binding Rule Update") - } - - r := a.c.newRequest("PUT", "/v1/acl/binding-rule/"+rule.ID) - r.setWriteOptions(q) - r.obj = rule - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLBindingRule - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -// BindingRuleDelete deletes a binding rule given its ID. -func (a *ACL) BindingRuleDelete(bindingRuleID string, q *WriteOptions) (*WriteMeta, error) { - r := a.c.newRequest("DELETE", "/v1/acl/binding-rule/"+bindingRuleID) - r.setWriteOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - return wm, nil -} - -// BindingRuleRead retrieves the binding rule details. Returns nil if not found. -func (a *ACL) BindingRuleRead(bindingRuleID string, q *QueryOptions) (*ACLBindingRule, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/binding-rule/"+bindingRuleID) - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - found, resp, err := requireNotFoundOrOK(resp) - if err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if !found { - return nil, qm, nil - } - - var out ACLBindingRule - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, qm, nil -} - -// BindingRuleList retrieves a listing of all binding rules. -func (a *ACL) BindingRuleList(methodName string, q *QueryOptions) ([]*ACLBindingRule, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/binding-rules") - if methodName != "" { - r.params.Set("authmethod", methodName) - } - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var entries []*ACLBindingRule - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, err - } - return entries, qm, nil -} - -// Login is used to exchange auth method credentials for a newly-minted Consul Token. -func (a *ACL) Login(auth *ACLLoginParams, q *WriteOptions) (*ACLToken, *WriteMeta, error) { - r := a.c.newRequest("POST", "/v1/acl/login") - r.setWriteOptions(q) - r.obj = auth - - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLToken - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return &out, wm, nil -} - -// Logout is used to destroy a Consul Token created via Login(). -func (a *ACL) Logout(q *WriteOptions) (*WriteMeta, error) { - r := a.c.newRequest("POST", "/v1/acl/logout") - r.setWriteOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - if err := requireOK(resp); err != nil { - return nil, err - } - closeResponseBody(resp) - - wm := &WriteMeta{RequestTime: rtt} - return wm, nil -} - -// OIDCAuthURL requests an authorization URL to start an OIDC login flow. -func (a *ACL) OIDCAuthURL(auth *ACLOIDCAuthURLParams, q *WriteOptions) (string, *WriteMeta, error) { - if auth.AuthMethod == "" { - return "", nil, fmt.Errorf("Must specify an auth method name") - } - - r := a.c.newRequest("POST", "/v1/acl/oidc/auth-url") - r.setWriteOptions(q) - r.obj = auth - - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return "", nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return "", nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - var out aclOIDCAuthURLResponse - if err := decodeBody(resp, &out); err != nil { - return "", nil, err - } - return out.AuthURL, wm, nil -} - -type aclOIDCAuthURLResponse struct { - AuthURL string -} - -type ACLOIDCCallbackParams struct { - AuthMethod string - State string - Code string - ClientNonce string -} - -// OIDCCallback is the callback endpoint to complete an OIDC login. -func (a *ACL) OIDCCallback(auth *ACLOIDCCallbackParams, q *WriteOptions) (*ACLToken, *WriteMeta, error) { - if auth.AuthMethod == "" { - return nil, nil, fmt.Errorf("Must specify an auth method name") - } - - r := a.c.newRequest("POST", "/v1/acl/oidc/callback") - r.setWriteOptions(q) - r.obj = auth - - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLToken - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return &out, wm, nil -} - -// TemplatedPolicyReadByName retrieves the templated policy details (by name). Returns nil if not found. -func (a *ACL) TemplatedPolicyReadByName(templateName string, q *QueryOptions) (*ACLTemplatedPolicyResponse, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/templated-policy/name/"+templateName) - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - found, resp, err := requireNotFoundOrOK(resp) - if err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if !found { - return nil, qm, nil - } - - var out ACLTemplatedPolicyResponse - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, qm, nil -} - -// TemplatedPolicyList retrieves a listing of all templated policies. -func (a *ACL) TemplatedPolicyList(q *QueryOptions) (map[string]ACLTemplatedPolicyResponse, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/acl/templated-policies") - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var entries map[string]ACLTemplatedPolicyResponse - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, err - } - return entries, qm, nil -} - -// TemplatedPolicyPreview is used to preview the policy rendered by the templated policy. -func (a *ACL) TemplatedPolicyPreview(tp *ACLTemplatedPolicy, q *WriteOptions) (*ACLPolicy, *WriteMeta, error) { - r := a.c.newRequest("POST", "/v1/acl/templated-policy/preview/"+tp.TemplateName) - r.setWriteOptions(q) - r.obj = tp.TemplateVariables - - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - wm := &WriteMeta{RequestTime: rtt} - var out ACLPolicy - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return &out, wm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/agent.go b/vendor/github.com/hashicorp/consul/api/agent.go deleted file mode 100644 index 24e2c50d6499c..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/agent.go +++ /dev/null @@ -1,1446 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "bufio" - "context" - "errors" - "fmt" - "io" - "net/http" -) - -// ServiceKind is the kind of service being registered. -type ServiceKind string - -const ( - // ServiceKindTypical is a typical, classic Consul service. This is - // represented by the absence of a value. This was chosen for ease of - // backwards compatibility: existing services in the catalog would - // default to the typical service. - ServiceKindTypical ServiceKind = "" - - // ServiceKindConnectProxy is a proxy for the Connect feature. This - // service proxies another service within Consul and speaks the connect - // protocol. - ServiceKindConnectProxy ServiceKind = "connect-proxy" - - // ServiceKindMeshGateway is a Mesh Gateway for the Connect feature. This - // service will proxy connections based off the SNI header set by other - // connect proxies - ServiceKindMeshGateway ServiceKind = "mesh-gateway" - - // ServiceKindTerminatingGateway is a Terminating Gateway for the Connect - // feature. This service will proxy connections to services outside the mesh. - ServiceKindTerminatingGateway ServiceKind = "terminating-gateway" - - // ServiceKindIngressGateway is an Ingress Gateway for the Connect feature. - // This service will ingress connections based of configuration defined in - // the ingress-gateway config entry. - ServiceKindIngressGateway ServiceKind = "ingress-gateway" - - // ServiceKindAPIGateway is an API Gateway for the Connect feature. - // This service will ingress connections based of configuration defined in - // the api-gateway config entry. - ServiceKindAPIGateway ServiceKind = "api-gateway" -) - -// UpstreamDestType is the type of upstream discovery mechanism. -type UpstreamDestType string - -const ( - // UpstreamDestTypeService discovers instances via healthy service lookup. - UpstreamDestTypeService UpstreamDestType = "service" - - // UpstreamDestTypePreparedQuery discovers instances via prepared query - // execution. - UpstreamDestTypePreparedQuery UpstreamDestType = "prepared_query" -) - -// AgentCheck represents a check known to the agent -type AgentCheck struct { - Node string - CheckID string - Name string - Status string - Notes string - Output string - ServiceID string - ServiceName string - Type string - ExposedPort int - Definition HealthCheckDefinition - Namespace string `json:",omitempty"` - Partition string `json:",omitempty"` -} - -// AgentWeights represent optional weights for a service -type AgentWeights struct { - Passing int - Warning int -} - -// AgentService represents a service known to the agent -type AgentService struct { - Kind ServiceKind `json:",omitempty"` - ID string - Service string - Tags []string - Meta map[string]string - Port int - Address string - SocketPath string `json:",omitempty"` - TaggedAddresses map[string]ServiceAddress `json:",omitempty"` - Weights AgentWeights - EnableTagOverride bool - CreateIndex uint64 `json:",omitempty" bexpr:"-"` - ModifyIndex uint64 `json:",omitempty" bexpr:"-"` - ContentHash string `json:",omitempty" bexpr:"-"` - Proxy *AgentServiceConnectProxyConfig `json:",omitempty"` - Connect *AgentServiceConnect `json:",omitempty"` - PeerName string `json:",omitempty"` - // NOTE: If we ever set the ContentHash outside of singular service lookup then we may need - // to include the Namespace in the hash. When we do, then we are in for lots of fun with tests. - // For now though, ignoring it works well enough. - Namespace string `json:",omitempty" bexpr:"-" hash:"ignore"` - Partition string `json:",omitempty" bexpr:"-" hash:"ignore"` - // Datacenter is only ever returned and is ignored if presented. - Datacenter string `json:",omitempty" bexpr:"-" hash:"ignore"` - Locality *Locality `json:",omitempty" bexpr:"-" hash:"ignore"` -} - -// AgentServiceChecksInfo returns information about a Service and its checks -type AgentServiceChecksInfo struct { - AggregatedStatus string - Service *AgentService - Checks HealthChecks -} - -// AgentServiceConnect represents the Connect configuration of a service. -type AgentServiceConnect struct { - Native bool `json:",omitempty"` - SidecarService *AgentServiceRegistration `json:",omitempty" bexpr:"-"` -} - -// AgentServiceConnectProxyConfig is the proxy configuration in a connect-proxy -// ServiceDefinition or response. -type AgentServiceConnectProxyConfig struct { - EnvoyExtensions []EnvoyExtension `json:",omitempty"` - DestinationServiceName string `json:",omitempty"` - DestinationServiceID string `json:",omitempty"` - LocalServiceAddress string `json:",omitempty"` - LocalServicePort int `json:",omitempty"` - LocalServiceSocketPath string `json:",omitempty"` - Mode ProxyMode `json:",omitempty"` - TransparentProxy *TransparentProxyConfig `json:",omitempty"` - Config map[string]interface{} `json:",omitempty" bexpr:"-"` - Upstreams []Upstream `json:",omitempty"` - MeshGateway MeshGatewayConfig `json:",omitempty"` - Expose ExposeConfig `json:",omitempty"` - AccessLogs *AccessLogsConfig `json:",omitempty"` -} - -const ( - // MemberTagKeyACLMode is the key used to indicate what ACL mode the agent is - // operating in. The values of this key will be one of the MemberACLMode constants - // with the key not being present indicating ACLModeUnknown. - MemberTagKeyACLMode = "acls" - - // MemberTagRole is the key used to indicate that the member is a server or not. - MemberTagKeyRole = "role" - - // MemberTagValueRoleServer is the value of the MemberTagKeyRole used to indicate - // that the member represents a Consul server. - MemberTagValueRoleServer = "consul" - - // MemberTagValueRoleClient is the value of the MemberTagKeyRole used to indicate - // that the member represents a Consul client. - MemberTagValueRoleClient = "node" - - // MemberTagKeyDatacenter is the key used to indicate which datacenter this member is in. - MemberTagKeyDatacenter = "dc" - - // MemberTagKeySegment is the key name of the tag used to indicate which network - // segment this member is in. - // Network Segments are a Consul Enterprise feature. - MemberTagKeySegment = "segment" - - // MemberTagKeyPartition is the key name of the tag used to indicate which partition - // this member is in. - // Partitions are a Consul Enterprise feature. - MemberTagKeyPartition = "ap" - - // MemberTagKeyBootstrap is the key name of the tag used to indicate whether this - // agent was started with the "bootstrap" configuration enabled - MemberTagKeyBootstrap = "bootstrap" - // MemberTagValueBootstrap is the value of the MemberTagKeyBootstrap key when the - // agent was started with the "bootstrap" configuration enabled. - MemberTagValueBootstrap = "1" - - // MemberTagKeyBootstrapExpect is the key name of the tag used to indicate whether - // this agent was started with the "bootstrap_expect" configuration set to a non-zero - // value. The value of this key will be the string for of that configuration value. - MemberTagKeyBootstrapExpect = "expect" - - // MemberTagKeyUseTLS is the key name of the tag used to indicate whther this agent - // was configured to use TLS. - MemberTagKeyUseTLS = "use_tls" - // MemberTagValueUseTLS is the value of the MemberTagKeyUseTLS when the agent was - // configured to use TLS. Any other value indicates that it was not setup in - // that manner. - MemberTagValueUseTLS = "1" - - // MemberTagKeyReadReplica is the key used to indicate that the member is a read - // replica server (will remain a Raft non-voter). - // Read Replicas are a Consul Enterprise feature. - MemberTagKeyReadReplica = "read_replica" - // MemberTagValueReadReplica is the value of the MemberTagKeyReadReplica key when - // the member is in fact a read-replica. Any other value indicates that it is not. - // Read Replicas are a Consul Enterprise feature. - MemberTagValueReadReplica = "1" -) - -type MemberACLMode string - -const ( - // ACLModeDisables indicates that ACLs are disabled for this agent - ACLModeDisabled MemberACLMode = "0" - // ACLModeEnabled indicates that ACLs are enabled and operating in new ACL - // mode (v1.4.0+ ACLs) - ACLModeEnabled MemberACLMode = "1" - // ACLModeLegacy has been deprecated, and will be treated as ACLModeUnknown. - ACLModeLegacy MemberACLMode = "2" // DEPRECATED - // ACLModeUnkown is used to indicate that the AgentMember.Tags didn't advertise - // an ACL mode at all. This is the case for Consul versions before v1.4.0 and - // should be treated the same as ACLModeLegacy. - ACLModeUnknown MemberACLMode = "3" -) - -// AgentMember represents a cluster member known to the agent -type AgentMember struct { - Name string - Addr string - Port uint16 - Tags map[string]string - // Status of the Member which corresponds to github.com/hashicorp/serf/serf.MemberStatus - // Value is one of: - // - // AgentMemberNone = 0 - // AgentMemberAlive = 1 - // AgentMemberLeaving = 2 - // AgentMemberLeft = 3 - // AgentMemberFailed = 4 - Status int - ProtocolMin uint8 - ProtocolMax uint8 - ProtocolCur uint8 - DelegateMin uint8 - DelegateMax uint8 - DelegateCur uint8 -} - -// ACLMode returns the ACL mode this agent is operating in. -func (m *AgentMember) ACLMode() MemberACLMode { - mode := m.Tags[MemberTagKeyACLMode] - - // the key may not have existed but then an - // empty string will be returned and we will - // handle that in the default case of the switch - switch MemberACLMode(mode) { - case ACLModeDisabled: - return ACLModeDisabled - case ACLModeEnabled: - return ACLModeEnabled - default: - return ACLModeUnknown - } -} - -// IsConsulServer returns true when this member is a Consul server. -func (m *AgentMember) IsConsulServer() bool { - return m.Tags[MemberTagKeyRole] == MemberTagValueRoleServer -} - -// AllSegments is used to select for all segments in MembersOpts. -const AllSegments = "_all" - -// MembersOpts is used for querying member information. -type MembersOpts struct { - // WAN is whether to show members from the WAN. - WAN bool - - // Segment is the LAN segment to show members for. Setting this to the - // AllSegments value above will show members in all segments. - Segment string - - Filter string -} - -// AgentServiceRegistration is used to register a new service -type AgentServiceRegistration struct { - Kind ServiceKind `json:",omitempty"` - ID string `json:",omitempty"` - Name string `json:",omitempty"` - Tags []string `json:",omitempty"` - Port int `json:",omitempty"` - Address string `json:",omitempty"` - SocketPath string `json:",omitempty"` - TaggedAddresses map[string]ServiceAddress `json:",omitempty"` - EnableTagOverride bool `json:",omitempty"` - Meta map[string]string `json:",omitempty"` - Weights *AgentWeights `json:",omitempty"` - Check *AgentServiceCheck - Checks AgentServiceChecks - Proxy *AgentServiceConnectProxyConfig `json:",omitempty"` - Connect *AgentServiceConnect `json:",omitempty"` - Namespace string `json:",omitempty" bexpr:"-" hash:"ignore"` - Partition string `json:",omitempty" bexpr:"-" hash:"ignore"` - Locality *Locality `json:",omitempty" bexpr:"-" hash:"ignore"` -} - -// ServiceRegisterOpts is used to pass extra options to the service register. -type ServiceRegisterOpts struct { - // Missing healthchecks will be deleted from the agent. - // Using this parameter allows to idempotently register a service and its checks without - // having to manually deregister checks. - ReplaceExistingChecks bool - - // Token is used to provide a per-request ACL token - // which overrides the agent's default token. - Token string - - // ctx is an optional context pass through to the underlying HTTP - // request layer. Use WithContext() to set the context. - ctx context.Context -} - -// WithContext sets the context to be used for the request on a new ServiceRegisterOpts, -// and returns the opts. -func (o ServiceRegisterOpts) WithContext(ctx context.Context) ServiceRegisterOpts { - o.ctx = ctx - return o -} - -// AgentCheckRegistration is used to register a new check -type AgentCheckRegistration struct { - ID string `json:",omitempty"` - Name string `json:",omitempty"` - Notes string `json:",omitempty"` - ServiceID string `json:",omitempty"` - AgentServiceCheck - Namespace string `json:",omitempty"` - Partition string `json:",omitempty"` -} - -// AgentServiceCheck is used to define a node or service level check -type AgentServiceCheck struct { - CheckID string `json:",omitempty"` - Name string `json:",omitempty"` - Args []string `json:"ScriptArgs,omitempty"` - DockerContainerID string `json:",omitempty"` - Shell string `json:",omitempty"` // Only supported for Docker. - Interval string `json:",omitempty"` - Timeout string `json:",omitempty"` - TTL string `json:",omitempty"` - HTTP string `json:",omitempty"` - Header map[string][]string `json:",omitempty"` - Method string `json:",omitempty"` - Body string `json:",omitempty"` - TCP string `json:",omitempty"` - TCPUseTLS bool `json:",omitempty"` - UDP string `json:",omitempty"` - Status string `json:",omitempty"` - Notes string `json:",omitempty"` - TLSServerName string `json:",omitempty"` - TLSSkipVerify bool `json:",omitempty"` - GRPC string `json:",omitempty"` - GRPCUseTLS bool `json:",omitempty"` - H2PING string `json:",omitempty"` - H2PingUseTLS bool `json:",omitempty"` - AliasNode string `json:",omitempty"` - AliasService string `json:",omitempty"` - SuccessBeforePassing int `json:",omitempty"` - FailuresBeforeWarning int `json:",omitempty"` - FailuresBeforeCritical int `json:",omitempty"` - - // In Consul 0.7 and later, checks that are associated with a service - // may also contain this optional DeregisterCriticalServiceAfter field, - // which is a timeout in the same Go time format as Interval and TTL. If - // a check is in the critical state for more than this configured value, - // then its associated service (and all of its associated checks) will - // automatically be deregistered. - DeregisterCriticalServiceAfter string `json:",omitempty"` -} -type AgentServiceChecks []*AgentServiceCheck - -// AgentToken is used when updating ACL tokens for an agent. -type AgentToken struct { - Token string -} - -// Metrics info is used to store different types of metric values from the agent. -type MetricsInfo struct { - Timestamp string - Gauges []GaugeValue - Points []PointValue - Counters []SampledValue - Samples []SampledValue -} - -// GaugeValue stores one value that is updated as time goes on, such as -// the amount of memory allocated. -type GaugeValue struct { - Name string - Value float32 - Labels map[string]string -} - -// PointValue holds a series of points for a metric. -type PointValue struct { - Name string - Points []float32 -} - -// SampledValue stores info about a metric that is incremented over time, -// such as the number of requests to an HTTP endpoint. -type SampledValue struct { - Name string - Count int - Sum float64 - Min float64 - Max float64 - Mean float64 - Stddev float64 - Labels map[string]string -} - -// AgentAuthorizeParams are the request parameters for authorizing a request. -type AgentAuthorizeParams struct { - Target string - ClientCertURI string - ClientCertSerial string -} - -// AgentAuthorize is the response structure for Connect authorization. -type AgentAuthorize struct { - Authorized bool - Reason string -} - -// ConnectProxyConfig is the response structure for agent-local proxy -// configuration. -type ConnectProxyConfig struct { - ProxyServiceID string - TargetServiceID string - TargetServiceName string - ContentHash string - Config map[string]interface{} `bexpr:"-"` - Upstreams []Upstream -} - -// Upstream is the response structure for a proxy upstream configuration. -type Upstream struct { - DestinationType UpstreamDestType `json:",omitempty"` - DestinationPartition string `json:",omitempty"` - DestinationNamespace string `json:",omitempty"` - DestinationPeer string `json:",omitempty"` - DestinationName string - Datacenter string `json:",omitempty"` - LocalBindAddress string `json:",omitempty"` - LocalBindPort int `json:",omitempty"` - LocalBindSocketPath string `json:",omitempty"` - LocalBindSocketMode string `json:",omitempty"` - Config map[string]interface{} `json:",omitempty" bexpr:"-"` - MeshGateway MeshGatewayConfig `json:",omitempty"` - CentrallyConfigured bool `json:",omitempty" bexpr:"-"` -} - -// Agent can be used to query the Agent endpoints -type Agent struct { - c *Client - - // cache the node name - nodeName string -} - -// Agent returns a handle to the agent endpoints -func (c *Client) Agent() *Agent { - return &Agent{c: c} -} - -// Self is used to query the agent we are speaking to for -// information about itself -func (a *Agent) Self() (map[string]map[string]interface{}, error) { - r := a.c.newRequest("GET", "/v1/agent/self") - _, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - var out map[string]map[string]interface{} - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - return out, nil -} - -// Host is used to retrieve information about the host the -// agent is running on such as CPU, memory, and disk. Requires -// a operator:read ACL token. -func (a *Agent) Host() (map[string]interface{}, error) { - r := a.c.newRequest("GET", "/v1/agent/host") - _, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - var out map[string]interface{} - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - return out, nil -} - -// Version is used to retrieve information about the running Consul version and build. -func (a *Agent) Version() (map[string]interface{}, error) { - r := a.c.newRequest("GET", "/v1/agent/version") - _, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - var out map[string]interface{} - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - return out, nil -} - -// Metrics is used to query the agent we are speaking to for -// its current internal metric data -func (a *Agent) Metrics() (*MetricsInfo, error) { - r := a.c.newRequest("GET", "/v1/agent/metrics") - _, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - var out *MetricsInfo - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - return out, nil -} - -// MetricsStream returns an io.ReadCloser which will emit a stream of metrics -// until the context is cancelled. The metrics are json encoded. -// The caller is responsible for closing the returned io.ReadCloser. -func (a *Agent) MetricsStream(ctx context.Context) (io.ReadCloser, error) { - r := a.c.newRequest("GET", "/v1/agent/metrics/stream") - r.ctx = ctx - _, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - if err := requireOK(resp); err != nil { - return nil, err - } - return resp.Body, nil -} - -// Reload triggers a configuration reload for the agent we are connected to. -func (a *Agent) Reload() error { - r := a.c.newRequest("PUT", "/v1/agent/reload") - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// NodeName is used to get the node name of the agent -func (a *Agent) NodeName() (string, error) { - if a.nodeName != "" { - return a.nodeName, nil - } - info, err := a.Self() - if err != nil { - return "", err - } - name := info["Config"]["NodeName"].(string) - a.nodeName = name - return name, nil -} - -// Checks returns the locally registered checks -func (a *Agent) Checks() (map[string]*AgentCheck, error) { - return a.ChecksWithFilter("") -} - -// ChecksWithFilter returns a subset of the locally registered checks that match -// the given filter expression -func (a *Agent) ChecksWithFilter(filter string) (map[string]*AgentCheck, error) { - return a.ChecksWithFilterOpts(filter, nil) -} - -// ChecksWithFilterOpts returns a subset of the locally registered checks that match -// the given filter expression and QueryOptions. -func (a *Agent) ChecksWithFilterOpts(filter string, q *QueryOptions) (map[string]*AgentCheck, error) { - r := a.c.newRequest("GET", "/v1/agent/checks") - r.setQueryOptions(q) - r.filterQuery(filter) - _, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - var out map[string]*AgentCheck - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - return out, nil -} - -// Services returns the locally registered services -func (a *Agent) Services() (map[string]*AgentService, error) { - return a.ServicesWithFilter("") -} - -// ServicesWithFilter returns a subset of the locally registered services that match -// the given filter expression -func (a *Agent) ServicesWithFilter(filter string) (map[string]*AgentService, error) { - return a.ServicesWithFilterOpts(filter, nil) -} - -// ServicesWithFilterOpts returns a subset of the locally registered services that match -// the given filter expression and QueryOptions. -func (a *Agent) ServicesWithFilterOpts(filter string, q *QueryOptions) (map[string]*AgentService, error) { - r := a.c.newRequest("GET", "/v1/agent/services") - r.setQueryOptions(q) - r.filterQuery(filter) - _, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - var out map[string]*AgentService - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - - return out, nil -} - -// AgentHealthServiceByID returns for a given serviceID: the aggregated health status, the service definition or an error if any -// - If the service is not found, will return status (critical, nil, nil) -// - If the service is found, will return (critical|passing|warning), AgentServiceChecksInfo, nil) -// - In all other cases, will return an error -func (a *Agent) AgentHealthServiceByID(serviceID string) (string, *AgentServiceChecksInfo, error) { - return a.AgentHealthServiceByIDOpts(serviceID, nil) -} - -func (a *Agent) AgentHealthServiceByIDOpts(serviceID string, q *QueryOptions) (string, *AgentServiceChecksInfo, error) { - path := fmt.Sprintf("/v1/agent/health/service/id/%v", serviceID) - r := a.c.newRequest("GET", path) - r.setQueryOptions(q) - r.params.Add("format", "json") - r.header.Set("Accept", "application/json") - // not a lot of value in wrapping the doRequest call in a requireHttpCodes call - // we manipulate the resp body and the require calls "swallow" the content on err - _, resp, err := a.c.doRequest(r) - if err != nil { - return "", nil, err - } - defer closeResponseBody(resp) - // Service not Found - if resp.StatusCode == http.StatusNotFound { - return HealthCritical, nil, nil - } - var out *AgentServiceChecksInfo - if err := decodeBody(resp, &out); err != nil { - return HealthCritical, out, err - } - switch resp.StatusCode { - case http.StatusOK: - return HealthPassing, out, nil - case http.StatusTooManyRequests: - return HealthWarning, out, nil - case http.StatusServiceUnavailable: - return HealthCritical, out, nil - } - return HealthCritical, out, fmt.Errorf("Unexpected Error Code %v for %s", resp.StatusCode, path) -} - -// AgentHealthServiceByName returns for a given service name: the aggregated health status for all services -// having the specified name. -// - If no service is not found, will return status (critical, [], nil) -// - If the service is found, will return (critical|passing|warning), []api.AgentServiceChecksInfo, nil) -// - In all other cases, will return an error -func (a *Agent) AgentHealthServiceByName(service string) (string, []AgentServiceChecksInfo, error) { - return a.AgentHealthServiceByNameOpts(service, nil) -} - -func (a *Agent) AgentHealthServiceByNameOpts(service string, q *QueryOptions) (string, []AgentServiceChecksInfo, error) { - path := fmt.Sprintf("/v1/agent/health/service/name/%v", service) - r := a.c.newRequest("GET", path) - r.setQueryOptions(q) - r.params.Add("format", "json") - r.header.Set("Accept", "application/json") - // not a lot of value in wrapping the doRequest call in a requireHttpCodes call - // we manipulate the resp body and the require calls "swallow" the content on err - _, resp, err := a.c.doRequest(r) - if err != nil { - return "", nil, err - } - defer closeResponseBody(resp) - // Service not Found - if resp.StatusCode == http.StatusNotFound { - return HealthCritical, nil, nil - } - var out []AgentServiceChecksInfo - if err := decodeBody(resp, &out); err != nil { - return HealthCritical, out, err - } - switch resp.StatusCode { - case http.StatusOK: - return HealthPassing, out, nil - case http.StatusTooManyRequests: - return HealthWarning, out, nil - case http.StatusServiceUnavailable: - return HealthCritical, out, nil - } - return HealthCritical, out, fmt.Errorf("Unexpected Error Code %v for %s", resp.StatusCode, path) -} - -// Service returns a locally registered service instance and allows for -// hash-based blocking. -// -// Note that this uses an unconventional blocking mechanism since it's -// agent-local state. That means there is no persistent raft index so we block -// based on object hash instead. -func (a *Agent) Service(serviceID string, q *QueryOptions) (*AgentService, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/agent/service/"+serviceID) - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out *AgentService - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return out, qm, nil -} - -// Members returns the known gossip members. The WAN -// flag can be used to query a server for WAN members. -func (a *Agent) Members(wan bool) ([]*AgentMember, error) { - r := a.c.newRequest("GET", "/v1/agent/members") - if wan { - r.params.Set("wan", "1") - } - _, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - var out []*AgentMember - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - return out, nil -} - -// MembersOpts returns the known gossip members and can be passed -// additional options for WAN/segment filtering. -func (a *Agent) MembersOpts(opts MembersOpts) ([]*AgentMember, error) { - r := a.c.newRequest("GET", "/v1/agent/members") - r.params.Set("segment", opts.Segment) - if opts.WAN { - r.params.Set("wan", "1") - } - - if opts.Filter != "" { - r.params.Set("filter", opts.Filter) - } - - _, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - var out []*AgentMember - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - return out, nil -} - -// ServiceRegister is used to register a new service with -// the local agent -func (a *Agent) ServiceRegister(service *AgentServiceRegistration) error { - opts := ServiceRegisterOpts{ - ReplaceExistingChecks: false, - } - - return a.serviceRegister(service, opts) -} - -// ServiceRegister is used to register a new service with -// the local agent and can be passed additional options. -func (a *Agent) ServiceRegisterOpts(service *AgentServiceRegistration, opts ServiceRegisterOpts) error { - return a.serviceRegister(service, opts) -} - -func (a *Agent) serviceRegister(service *AgentServiceRegistration, opts ServiceRegisterOpts) error { - r := a.c.newRequest("PUT", "/v1/agent/service/register") - r.obj = service - r.ctx = opts.ctx - if opts.ReplaceExistingChecks { - r.params.Set("replace-existing-checks", "true") - } - if opts.Token != "" { - r.header.Set("X-Consul-Token", opts.Token) - } - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// ServiceDeregister is used to deregister a service with -// the local agent -func (a *Agent) ServiceDeregister(serviceID string) error { - r := a.c.newRequest("PUT", "/v1/agent/service/deregister/"+serviceID) - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// ServiceDeregisterOpts is used to deregister a service with -// the local agent with QueryOptions. -func (a *Agent) ServiceDeregisterOpts(serviceID string, q *QueryOptions) error { - r := a.c.newRequest("PUT", "/v1/agent/service/deregister/"+serviceID) - r.setQueryOptions(q) - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// PassTTL is used to set a TTL check to the passing state. -// -// DEPRECATION NOTICE: This interface is deprecated in favor of UpdateTTL(). -// The client interface will be removed in 0.8 or changed to use -// UpdateTTL()'s endpoint and the server endpoints will be removed in 0.9. -func (a *Agent) PassTTL(checkID, note string) error { - return a.updateTTL(checkID, note, "pass") -} - -// WarnTTL is used to set a TTL check to the warning state. -// -// DEPRECATION NOTICE: This interface is deprecated in favor of UpdateTTL(). -// The client interface will be removed in 0.8 or changed to use -// UpdateTTL()'s endpoint and the server endpoints will be removed in 0.9. -func (a *Agent) WarnTTL(checkID, note string) error { - return a.updateTTL(checkID, note, "warn") -} - -// FailTTL is used to set a TTL check to the failing state. -// -// DEPRECATION NOTICE: This interface is deprecated in favor of UpdateTTL(). -// The client interface will be removed in 0.8 or changed to use -// UpdateTTL()'s endpoint and the server endpoints will be removed in 0.9. -func (a *Agent) FailTTL(checkID, note string) error { - return a.updateTTL(checkID, note, "fail") -} - -// updateTTL is used to update the TTL of a check. This is the internal -// method that uses the old API that's present in Consul versions prior to -// 0.6.4. Since Consul didn't have an analogous "update" API before it seemed -// ok to break this (former) UpdateTTL in favor of the new UpdateTTL below, -// but keep the old Pass/Warn/Fail methods using the old API under the hood. -// -// DEPRECATION NOTICE: This interface is deprecated in favor of UpdateTTL(). -// The client interface will be removed in 0.8 and the server endpoints will -// be removed in 0.9. -func (a *Agent) updateTTL(checkID, note, status string) error { - switch status { - case "pass": - case "warn": - case "fail": - default: - return fmt.Errorf("Invalid status: %s", status) - } - endpoint := fmt.Sprintf("/v1/agent/check/%s/%s", status, checkID) - r := a.c.newRequest("PUT", endpoint) - r.params.Set("note", note) - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// checkUpdate is the payload for a PUT for a check update. -type checkUpdate struct { - // Status is one of the api.Health* states: HealthPassing - // ("passing"), HealthWarning ("warning"), or HealthCritical - // ("critical"). - Status string - - // Output is the information to post to the UI for operators as the - // output of the process that decided to hit the TTL check. This is - // different from the note field that's associated with the check - // itself. - Output string -} - -// UpdateTTL is used to update the TTL of a check. This uses the newer API -// that was introduced in Consul 0.6.4 and later. We translate the old status -// strings for compatibility (though a newer version of Consul will still be -// required to use this API). -func (a *Agent) UpdateTTL(checkID, output, status string) error { - return a.UpdateTTLOpts(checkID, output, status, nil) -} - -func (a *Agent) UpdateTTLOpts(checkID, output, status string, q *QueryOptions) error { - switch status { - case "pass", HealthPassing: - status = HealthPassing - case "warn", HealthWarning: - status = HealthWarning - case "fail", HealthCritical: - status = HealthCritical - default: - return fmt.Errorf("Invalid status: %s", status) - } - - endpoint := fmt.Sprintf("/v1/agent/check/update/%s", checkID) - r := a.c.newRequest("PUT", endpoint) - r.setQueryOptions(q) - r.obj = &checkUpdate{ - Status: status, - Output: output, - } - - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// CheckRegister is used to register a new check with -// the local agent -func (a *Agent) CheckRegister(check *AgentCheckRegistration) error { - return a.CheckRegisterOpts(check, nil) -} - -// CheckRegisterOpts is used to register a new check with -// the local agent using query options -func (a *Agent) CheckRegisterOpts(check *AgentCheckRegistration, q *QueryOptions) error { - r := a.c.newRequest("PUT", "/v1/agent/check/register") - r.setQueryOptions(q) - r.obj = check - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// CheckDeregister is used to deregister a check with -// the local agent -func (a *Agent) CheckDeregister(checkID string) error { - return a.CheckDeregisterOpts(checkID, nil) -} - -// CheckDeregisterOpts is used to deregister a check with -// the local agent using query options -func (a *Agent) CheckDeregisterOpts(checkID string, q *QueryOptions) error { - r := a.c.newRequest("PUT", "/v1/agent/check/deregister/"+checkID) - r.setQueryOptions(q) - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// Join is used to instruct the agent to attempt a join to -// another cluster member -func (a *Agent) Join(addr string, wan bool) error { - r := a.c.newRequest("PUT", "/v1/agent/join/"+addr) - if wan { - r.params.Set("wan", "1") - } - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// Leave is used to have the agent gracefully leave the cluster and shutdown -func (a *Agent) Leave() error { - r := a.c.newRequest("PUT", "/v1/agent/leave") - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -type ForceLeaveOpts struct { - // Prune indicates if we should remove a failed agent from the list of - // members in addition to ejecting it. - Prune bool - - // WAN indicates that the request should exclusively target the WAN pool. - WAN bool -} - -// ForceLeave is used to have the agent eject a failed node -func (a *Agent) ForceLeave(node string) error { - return a.ForceLeaveOpts(node, ForceLeaveOpts{}) -} - -// ForceLeavePrune is used to have an a failed agent removed -// from the list of members -func (a *Agent) ForceLeavePrune(node string) error { - return a.ForceLeaveOpts(node, ForceLeaveOpts{Prune: true}) -} - -// ForceLeaveOpts is used to have the agent eject a failed node or remove it -// completely from the list of members. -// -// DEPRECATED - Use ForceLeaveOptions instead. -func (a *Agent) ForceLeaveOpts(node string, opts ForceLeaveOpts) error { - return a.ForceLeaveOptions(node, opts, nil) -} - -// ForceLeaveOptions is used to have the agent eject a failed node or remove it -// completely from the list of members. Allows usage of QueryOptions on-top of ForceLeaveOpts -func (a *Agent) ForceLeaveOptions(node string, opts ForceLeaveOpts, q *QueryOptions) error { - r := a.c.newRequest("PUT", "/v1/agent/force-leave/"+node) - r.setQueryOptions(q) - if opts.Prune { - r.params.Set("prune", "1") - } - if opts.WAN { - r.params.Set("wan", "1") - } - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// ConnectAuthorize is used to authorize an incoming connection -// to a natively integrated Connect service. -func (a *Agent) ConnectAuthorize(auth *AgentAuthorizeParams) (*AgentAuthorize, error) { - r := a.c.newRequest("POST", "/v1/agent/connect/authorize") - r.obj = auth - _, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - var out AgentAuthorize - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - return &out, nil -} - -// ConnectCARoots returns the list of roots. -func (a *Agent) ConnectCARoots(q *QueryOptions) (*CARootList, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/agent/connect/ca/roots") - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out CARootList - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return &out, qm, nil -} - -// ConnectCALeaf gets the leaf certificate for the given service ID. -func (a *Agent) ConnectCALeaf(serviceID string, q *QueryOptions) (*LeafCert, *QueryMeta, error) { - r := a.c.newRequest("GET", "/v1/agent/connect/ca/leaf/"+serviceID) - r.setQueryOptions(q) - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out LeafCert - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return &out, qm, nil -} - -// EnableServiceMaintenance toggles service maintenance mode on -// for the given service ID. -func (a *Agent) EnableServiceMaintenance(serviceID, reason string) error { - return a.EnableServiceMaintenanceOpts(serviceID, reason, nil) -} - -func (a *Agent) EnableServiceMaintenanceOpts(serviceID, reason string, q *QueryOptions) error { - r := a.c.newRequest("PUT", "/v1/agent/service/maintenance/"+serviceID) - r.setQueryOptions(q) - r.params.Set("enable", "true") - r.params.Set("reason", reason) - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// DisableServiceMaintenance toggles service maintenance mode off -// for the given service ID. -func (a *Agent) DisableServiceMaintenance(serviceID string) error { - return a.DisableServiceMaintenanceOpts(serviceID, nil) -} - -func (a *Agent) DisableServiceMaintenanceOpts(serviceID string, q *QueryOptions) error { - r := a.c.newRequest("PUT", "/v1/agent/service/maintenance/"+serviceID) - r.setQueryOptions(q) - r.params.Set("enable", "false") - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// EnableNodeMaintenance toggles node maintenance mode on for the -// agent we are connected to. -func (a *Agent) EnableNodeMaintenance(reason string) error { - r := a.c.newRequest("PUT", "/v1/agent/maintenance") - r.params.Set("enable", "true") - r.params.Set("reason", reason) - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// DisableNodeMaintenance toggles node maintenance mode off for the -// agent we are connected to. -func (a *Agent) DisableNodeMaintenance() error { - r := a.c.newRequest("PUT", "/v1/agent/maintenance") - r.params.Set("enable", "false") - _, resp, err := a.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// Monitor returns a channel which will receive streaming logs from the agent -// Providing a non-nil stopCh can be used to close the connection and stop the -// log stream. An empty string will be sent down the given channel when there's -// nothing left to stream, after which the caller should close the stopCh. -func (a *Agent) Monitor(loglevel string, stopCh <-chan struct{}, q *QueryOptions) (chan string, error) { - return a.monitor(loglevel, false, stopCh, q) -} - -// MonitorJSON is like Monitor except it returns logs in JSON format. -func (a *Agent) MonitorJSON(loglevel string, stopCh <-chan struct{}, q *QueryOptions) (chan string, error) { - return a.monitor(loglevel, true, stopCh, q) -} - -func (a *Agent) monitor(loglevel string, logJSON bool, stopCh <-chan struct{}, q *QueryOptions) (chan string, error) { - r := a.c.newRequest("GET", "/v1/agent/monitor") - r.setQueryOptions(q) - if loglevel != "" { - r.params.Add("loglevel", loglevel) - } - if logJSON { - r.params.Set("logjson", "true") - } - _, resp, err := a.c.doRequest(r) - if err != nil { - return nil, err - } - if err := requireOK(resp); err != nil { - return nil, err - } - logCh := make(chan string, 64) - go func() { - defer closeResponseBody(resp) - scanner := bufio.NewScanner(resp.Body) - for { - select { - case <-stopCh: - close(logCh) - return - default: - } - if scanner.Scan() { - // An empty string signals to the caller that - // the scan is done, so make sure we only emit - // that when the scanner says it's done, not if - // we happen to ingest an empty line. - if text := scanner.Text(); text != "" { - logCh <- text - } else { - logCh <- " " - } - } else { - logCh <- "" - } - } - }() - return logCh, nil -} - -// UpdateACLToken updates the agent's "acl_token". See updateToken for more -// details. Deprecated in Consul 1.4. -// -// DEPRECATED (ACL-Legacy-Compat) - Prefer UpdateDefaultACLToken for v1.4.3 and above -func (a *Agent) UpdateACLToken(token string, q *WriteOptions) (*WriteMeta, error) { - return nil, fmt.Errorf("Legacy ACL Tokens were deprecated in Consul 1.4") -} - -// UpdateACLAgentToken updates the agent's "acl_agent_token". See updateToken -// for more details. Deprecated in Consul 1.4. -// -// DEPRECATED (ACL-Legacy-Compat) - Prefer UpdateAgentACLToken for v1.4.3 and above -func (a *Agent) UpdateACLAgentToken(token string, q *WriteOptions) (*WriteMeta, error) { - return nil, fmt.Errorf("Legacy ACL Tokens were deprecated in Consul 1.4") -} - -// UpdateACLAgentMasterToken updates the agent's "acl_agent_master_token". See -// updateToken for more details. Deprecated in Consul 1.4. -// -// DEPRECATED (ACL-Legacy-Compat) - Prefer UpdateAgentMasterACLToken for v1.4.3 and above -func (a *Agent) UpdateACLAgentMasterToken(token string, q *WriteOptions) (*WriteMeta, error) { - return nil, fmt.Errorf("Legacy ACL Tokens were deprecated in Consul 1.4") -} - -// UpdateACLReplicationToken updates the agent's "acl_replication_token". See -// updateToken for more details. Deprecated in Consul 1.4. -// -// DEPRECATED (ACL-Legacy-Compat) - Prefer UpdateReplicationACLToken for v1.4.3 and above -func (a *Agent) UpdateACLReplicationToken(token string, q *WriteOptions) (*WriteMeta, error) { - return nil, fmt.Errorf("Legacy ACL Tokens were deprecated in Consul 1.4") -} - -// UpdateDefaultACLToken updates the agent's "default" token. See updateToken -// for more details -func (a *Agent) UpdateDefaultACLToken(token string, q *WriteOptions) (*WriteMeta, error) { - return a.updateTokenFallback(token, q, "default", "acl_token") -} - -// UpdateAgentACLToken updates the agent's "agent" token. See updateToken -// for more details -func (a *Agent) UpdateAgentACLToken(token string, q *WriteOptions) (*WriteMeta, error) { - return a.updateTokenFallback(token, q, "agent", "acl_agent_token") -} - -// UpdateAgentRecoveryACLToken updates the agent's "agent_recovery" token. See updateToken -// for more details. -func (a *Agent) UpdateAgentRecoveryACLToken(token string, q *WriteOptions) (*WriteMeta, error) { - return a.updateTokenFallback(token, q, "agent_recovery", "agent_master", "acl_agent_master_token") -} - -// UpdateAgentMasterACLToken updates the agent's "agent_master" token. See updateToken -// for more details. -// -// DEPRECATED - Prefer UpdateAgentRecoveryACLToken for v1.11 and above. -func (a *Agent) UpdateAgentMasterACLToken(token string, q *WriteOptions) (*WriteMeta, error) { - return a.updateTokenFallback(token, q, "agent_master", "acl_agent_master_token") -} - -// UpdateReplicationACLToken updates the agent's "replication" token. See updateToken -// for more details -func (a *Agent) UpdateReplicationACLToken(token string, q *WriteOptions) (*WriteMeta, error) { - return a.updateTokenFallback(token, q, "replication", "acl_replication_token") -} - -// UpdateConfigFileRegistrationToken updates the agent's "replication" token. See updateToken -// for more details -func (a *Agent) UpdateConfigFileRegistrationToken(token string, q *WriteOptions) (*WriteMeta, error) { - return a.updateToken("config_file_service_registration", token, q) -} - -func (a *Agent) UpdateDNSToken(token string, q *WriteOptions) (*WriteMeta, error) { - return a.updateToken("dns", token, q) -} - -// updateToken can be used to update one of an agent's ACL tokens after the agent has -// started. The tokens are may not be persisted, so will need to be updated again if -// the agent is restarted unless the agent is configured to persist them. -func (a *Agent) updateToken(target, token string, q *WriteOptions) (*WriteMeta, error) { - meta, _, err := a.updateTokenOnce(target, token, q) - return meta, err -} - -func (a *Agent) updateTokenFallback(token string, q *WriteOptions, targets ...string) (*WriteMeta, error) { - if len(targets) == 0 { - panic("targets must not be empty") - } - - var ( - meta *WriteMeta - err error - ) - for _, target := range targets { - var status int - meta, status, err = a.updateTokenOnce(target, token, q) - if err == nil && status != http.StatusNotFound { - return meta, err - } - } - return meta, err -} - -func (a *Agent) updateTokenOnce(target, token string, q *WriteOptions) (*WriteMeta, int, error) { - r := a.c.newRequest("PUT", fmt.Sprintf("/v1/agent/token/%s", target)) - r.setWriteOptions(q) - r.obj = &AgentToken{Token: token} - - rtt, resp, err := a.c.doRequest(r) - if err != nil { - return nil, 500, err - } - defer closeResponseBody(resp) - wm := &WriteMeta{RequestTime: rtt} - if err := requireOK(resp); err != nil { - var statusE StatusError - if errors.As(err, &statusE) { - return wm, statusE.Code, statusE - } - return nil, 0, err - } - return wm, resp.StatusCode, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/api.go b/vendor/github.com/hashicorp/consul/api/api.go deleted file mode 100644 index d4d853d5d4b1b..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/api.go +++ /dev/null @@ -1,1314 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "bytes" - "context" - "crypto/tls" - "encoding/json" - "fmt" - "io" - "math" - "net" - "net/http" - "net/url" - "os" - "strconv" - "strings" - "sync" - "time" - - "github.com/hashicorp/go-cleanhttp" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-rootcerts" -) - -const ( - // HTTPAddrEnvName defines an environment variable name which sets - // the HTTP address if there is no -http-addr specified. - HTTPAddrEnvName = "CONSUL_HTTP_ADDR" - - // HTTPTokenEnvName defines an environment variable name which sets - // the HTTP token. - HTTPTokenEnvName = "CONSUL_HTTP_TOKEN" - - // HTTPTokenFileEnvName defines an environment variable name which sets - // the HTTP token file. - HTTPTokenFileEnvName = "CONSUL_HTTP_TOKEN_FILE" - - // HTTPAuthEnvName defines an environment variable name which sets - // the HTTP authentication header. - HTTPAuthEnvName = "CONSUL_HTTP_AUTH" - - // HTTPSSLEnvName defines an environment variable name which sets - // whether or not to use HTTPS. - HTTPSSLEnvName = "CONSUL_HTTP_SSL" - - // HTTPCAFile defines an environment variable name which sets the - // CA file to use for talking to Consul over TLS. - HTTPCAFile = "CONSUL_CACERT" - - // HTTPCAPath defines an environment variable name which sets the - // path to a directory of CA certs to use for talking to Consul over TLS. - HTTPCAPath = "CONSUL_CAPATH" - - // HTTPClientCert defines an environment variable name which sets the - // client cert file to use for talking to Consul over TLS. - HTTPClientCert = "CONSUL_CLIENT_CERT" - - // HTTPClientKey defines an environment variable name which sets the - // client key file to use for talking to Consul over TLS. - HTTPClientKey = "CONSUL_CLIENT_KEY" - - // HTTPTLSServerName defines an environment variable name which sets the - // server name to use as the SNI host when connecting via TLS - HTTPTLSServerName = "CONSUL_TLS_SERVER_NAME" - - // HTTPSSLVerifyEnvName defines an environment variable name which sets - // whether or not to disable certificate checking. - HTTPSSLVerifyEnvName = "CONSUL_HTTP_SSL_VERIFY" - - // GRPCAddrEnvName defines an environment variable name which sets the gRPC - // address for consul connect envoy. Note this isn't actually used by the api - // client in this package but is defined here for consistency with all the - // other ENV names we use. - GRPCAddrEnvName = "CONSUL_GRPC_ADDR" - - // GRPCCAFileEnvName defines an environment variable name which sets the - // CA file to use for talking to Consul gRPC over TLS. - GRPCCAFileEnvName = "CONSUL_GRPC_CACERT" - - // GRPCCAPathEnvName defines an environment variable name which sets the - // path to a directory of CA certs to use for talking to Consul gRPC over TLS. - GRPCCAPathEnvName = "CONSUL_GRPC_CAPATH" - - // HTTPNamespaceEnvVar defines an environment variable name which sets - // the HTTP Namespace to be used by default. This can still be overridden. - HTTPNamespaceEnvName = "CONSUL_NAMESPACE" - - // HTTPPartitionEnvName defines an environment variable name which sets - // the HTTP Partition to be used by default. This can still be overridden. - HTTPPartitionEnvName = "CONSUL_PARTITION" - - // QueryBackendStreaming Query backend of type streaming - QueryBackendStreaming = "streaming" - - // QueryBackendBlockingQuery Query backend of type blocking query - QueryBackendBlockingQuery = "blocking-query" -) - -type StatusError struct { - Code int - Body string -} - -func (e StatusError) Error() string { - return fmt.Sprintf("Unexpected response code: %d (%s)", e.Code, e.Body) -} - -// QueryOptions are used to parameterize a query -type QueryOptions struct { - // Namespace overrides the `default` namespace - // Note: Namespaces are available only in Consul Enterprise - Namespace string - - // Partition overrides the `default` partition - // Note: Partitions are available only in Consul Enterprise - Partition string - - // SamenessGroup is used find the SamenessGroup in the given - // Partition and will find the failover order for the Service - // from the SamenessGroup Members, with the given Partition being - // the first member. - // Note: SamenessGroups are available only in Consul Enterprise - SamenessGroup string - - // Providing a datacenter overwrites the DC provided - // by the Config - Datacenter string - - // Providing a peer name in the query option - Peer string - - // AllowStale allows any Consul server (non-leader) to service - // a read. This allows for lower latency and higher throughput - AllowStale bool - - // RequireConsistent forces the read to be fully consistent. - // This is more expensive but prevents ever performing a stale - // read. - RequireConsistent bool - - // UseCache requests that the agent cache results locally. See - // https://www.consul.io/api/features/caching.html for more details on the - // semantics. - UseCache bool - - // MaxAge limits how old a cached value will be returned if UseCache is true. - // If there is a cached response that is older than the MaxAge, it is treated - // as a cache miss and a new fetch invoked. If the fetch fails, the error is - // returned. Clients that wish to allow for stale results on error can set - // StaleIfError to a longer duration to change this behavior. It is ignored - // if the endpoint supports background refresh caching. See - // https://www.consul.io/api/features/caching.html for more details. - MaxAge time.Duration - - // StaleIfError specifies how stale the client will accept a cached response - // if the servers are unavailable to fetch a fresh one. Only makes sense when - // UseCache is true and MaxAge is set to a lower, non-zero value. It is - // ignored if the endpoint supports background refresh caching. See - // https://www.consul.io/api/features/caching.html for more details. - StaleIfError time.Duration - - // WaitIndex is used to enable a blocking query. Waits - // until the timeout or the next index is reached - WaitIndex uint64 - - // WaitHash is used by some endpoints instead of WaitIndex to perform blocking - // on state based on a hash of the response rather than a monotonic index. - // This is required when the state being blocked on is not stored in Raft, for - // example agent-local proxy configuration. - WaitHash string - - // WaitTime is used to bound the duration of a wait. - // Defaults to that of the Config, but can be overridden. - WaitTime time.Duration - - // Token is used to provide a per-request ACL token - // which overrides the agent's default token. - Token string - - // Near is used to provide a node name that will sort the results - // in ascending order based on the estimated round trip time from - // that node. Setting this to "_agent" will use the agent's node - // for the sort. - Near string - - // NodeMeta is used to filter results by nodes with the given - // metadata key/value pairs. Currently, only one key/value pair can - // be provided for filtering. - NodeMeta map[string]string - - // RelayFactor is used in keyring operations to cause responses to be - // relayed back to the sender through N other random nodes. Must be - // a value from 0 to 5 (inclusive). - RelayFactor uint8 - - // LocalOnly is used in keyring list operation to force the keyring - // query to only hit local servers (no WAN traffic). - LocalOnly bool - - // Connect filters prepared query execution to only include Connect-capable - // services. This currently affects prepared query execution. - Connect bool - - // ctx is an optional context pass through to the underlying HTTP - // request layer. Use Context() and WithContext() to manage this. - ctx context.Context - - // Filter requests filtering data prior to it being returned. The string - // is a go-bexpr compatible expression. - Filter string - - // MergeCentralConfig returns a service definition merged with the - // proxy-defaults/global and service-defaults/:service config entries. - // This can be used to ensure a full service definition is returned in the response - // especially when the service might not be written into the catalog that way. - MergeCentralConfig bool - - // Global is used to request information from all datacenters. Currently only - // used for operator usage requests. - Global bool -} - -func (o *QueryOptions) Context() context.Context { - if o != nil && o.ctx != nil { - return o.ctx - } - return context.Background() -} - -func (o *QueryOptions) WithContext(ctx context.Context) *QueryOptions { - o2 := new(QueryOptions) - if o != nil { - *o2 = *o - } - o2.ctx = ctx - return o2 -} - -// WriteOptions are used to parameterize a write -type WriteOptions struct { - // Namespace overrides the `default` namespace - // Note: Namespaces are available only in Consul Enterprise - Namespace string - - // Partition overrides the `default` partition - // Note: Partitions are available only in Consul Enterprise - Partition string - - // Providing a datacenter overwrites the DC provided - // by the Config - Datacenter string - - // Token is used to provide a per-request ACL token - // which overrides the agent's default token. - Token string - - // RelayFactor is used in keyring operations to cause responses to be - // relayed back to the sender through N other random nodes. Must be - // a value from 0 to 5 (inclusive). - RelayFactor uint8 - - // ctx is an optional context pass through to the underlying HTTP - // request layer. Use Context() and WithContext() to manage this. - ctx context.Context -} - -func (o *WriteOptions) Context() context.Context { - if o != nil && o.ctx != nil { - return o.ctx - } - return context.Background() -} - -func (o *WriteOptions) WithContext(ctx context.Context) *WriteOptions { - o2 := new(WriteOptions) - if o != nil { - *o2 = *o - } - o2.ctx = ctx - return o2 -} - -// QueryMeta is used to return meta data about a query -type QueryMeta struct { - // LastIndex. This can be used as a WaitIndex to perform - // a blocking query - LastIndex uint64 - - // LastContentHash. This can be used as a WaitHash to perform a blocking query - // for endpoints that support hash-based blocking. Endpoints that do not - // support it will return an empty hash. - LastContentHash string - - // Time of last contact from the leader for the - // server servicing the request - LastContact time.Duration - - // Is there a known leader - KnownLeader bool - - // How long did the request take - RequestTime time.Duration - - // Is address translation enabled for HTTP responses on this agent - AddressTranslationEnabled bool - - // CacheHit is true if the result was served from agent-local cache. - CacheHit bool - - // CacheAge is set if request was ?cached and indicates how stale the cached - // response is. - CacheAge time.Duration - - // QueryBackend represent which backend served the request. - QueryBackend string - - // DefaultACLPolicy is used to control the ACL interaction when there is no - // defined policy. This can be "allow" which means ACLs are used to - // deny-list, or "deny" which means ACLs are allow-lists. - DefaultACLPolicy string - - // ResultsFilteredByACLs is true when some of the query's results were - // filtered out by enforcing ACLs. It may be false because nothing was - // removed, or because the endpoint does not yet support this flag. - ResultsFilteredByACLs bool -} - -// WriteMeta is used to return meta data about a write -type WriteMeta struct { - // How long did the request take - RequestTime time.Duration -} - -// HttpBasicAuth is used to authenticate http client with HTTP Basic Authentication -type HttpBasicAuth struct { - // Username to use for HTTP Basic Authentication - Username string - - // Password to use for HTTP Basic Authentication - Password string -} - -// Config is used to configure the creation of a client -type Config struct { - // Address is the address of the Consul server - Address string - - // Scheme is the URI scheme for the Consul server - Scheme string - - // Prefix for URIs for when consul is behind an API gateway (reverse - // proxy). The API gateway must strip off the PathPrefix before - // passing the request onto consul. - PathPrefix string - - // Datacenter to use. If not provided, the default agent datacenter is used. - Datacenter string - - // Transport is the Transport to use for the http client. - Transport *http.Transport - - // HttpClient is the client to use. Default will be - // used if not provided. - HttpClient *http.Client - - // HttpAuth is the auth info to use for http access. - HttpAuth *HttpBasicAuth - - // WaitTime limits how long a Watch will block. If not provided, - // the agent default values will be used. - WaitTime time.Duration - - // Token is used to provide a per-request ACL token - // which overrides the agent's default token. - Token string - - // TokenFile is a file containing the current token to use for this client. - // If provided it is read once at startup and never again. - TokenFile string - - // Namespace is the name of the namespace to send along for the request - // when no other Namespace is present in the QueryOptions - Namespace string - - // Partition is the name of the partition to send along for the request - // when no other Partition is present in the QueryOptions - Partition string - - TLSConfig TLSConfig -} - -// TLSConfig is used to generate a TLSClientConfig that's useful for talking to -// Consul using TLS. -type TLSConfig struct { - // Address is the optional address of the Consul server. The port, if any - // will be removed from here and this will be set to the ServerName of the - // resulting config. - Address string - - // CAFile is the optional path to the CA certificate used for Consul - // communication, defaults to the system bundle if not specified. - CAFile string - - // CAPath is the optional path to a directory of CA certificates to use for - // Consul communication, defaults to the system bundle if not specified. - CAPath string - - // CAPem is the optional PEM-encoded CA certificate used for Consul - // communication, defaults to the system bundle if not specified. - CAPem []byte - - // CertFile is the optional path to the certificate for Consul - // communication. If this is set then you need to also set KeyFile. - CertFile string - - // CertPEM is the optional PEM-encoded certificate for Consul - // communication. If this is set then you need to also set KeyPEM. - CertPEM []byte - - // KeyFile is the optional path to the private key for Consul communication. - // If this is set then you need to also set CertFile. - KeyFile string - - // KeyPEM is the optional PEM-encoded private key for Consul communication. - // If this is set then you need to also set CertPEM. - KeyPEM []byte - - // InsecureSkipVerify if set to true will disable TLS host verification. - InsecureSkipVerify bool -} - -// DefaultConfig returns a default configuration for the client. By default this -// will pool and reuse idle connections to Consul. If you have a long-lived -// client object, this is the desired behavior and should make the most efficient -// use of the connections to Consul. If you don't reuse a client object, which -// is not recommended, then you may notice idle connections building up over -// time. To avoid this, use the DefaultNonPooledConfig() instead. -func DefaultConfig() *Config { - return defaultConfig(nil, cleanhttp.DefaultPooledTransport) -} - -// DefaultConfigWithLogger returns a default configuration for the client. It -// is exactly the same as DefaultConfig, but allows for a pre-configured logger -// object to be passed through. -func DefaultConfigWithLogger(logger hclog.Logger) *Config { - return defaultConfig(logger, cleanhttp.DefaultPooledTransport) -} - -// DefaultNonPooledConfig returns a default configuration for the client which -// does not pool connections. This isn't a recommended configuration because it -// will reconnect to Consul on every request, but this is useful to avoid the -// accumulation of idle connections if you make many client objects during the -// lifetime of your application. -func DefaultNonPooledConfig() *Config { - return defaultConfig(nil, cleanhttp.DefaultTransport) -} - -// defaultConfig returns the default configuration for the client, using the -// given function to make the transport. -func defaultConfig(logger hclog.Logger, transportFn func() *http.Transport) *Config { - if logger == nil { - logger = hclog.New(&hclog.LoggerOptions{ - Name: "consul-api", - }) - } - - config := &Config{ - Address: "127.0.0.1:8500", - Scheme: "http", - Transport: transportFn(), - } - - if addr := os.Getenv(HTTPAddrEnvName); addr != "" { - config.Address = addr - } - - if tokenFile := os.Getenv(HTTPTokenFileEnvName); tokenFile != "" { - config.TokenFile = tokenFile - } - - if token := os.Getenv(HTTPTokenEnvName); token != "" { - config.Token = token - } - - if auth := os.Getenv(HTTPAuthEnvName); auth != "" { - var username, password string - if strings.Contains(auth, ":") { - split := strings.SplitN(auth, ":", 2) - username = split[0] - password = split[1] - } else { - username = auth - } - - config.HttpAuth = &HttpBasicAuth{ - Username: username, - Password: password, - } - } - - if ssl := os.Getenv(HTTPSSLEnvName); ssl != "" { - enabled, err := strconv.ParseBool(ssl) - if err != nil { - logger.Warn(fmt.Sprintf("could not parse %s", HTTPSSLEnvName), "error", err) - } - - if enabled { - config.Scheme = "https" - } - } - - if v := os.Getenv(HTTPTLSServerName); v != "" { - config.TLSConfig.Address = v - } - if v := os.Getenv(HTTPCAFile); v != "" { - config.TLSConfig.CAFile = v - } - if v := os.Getenv(HTTPCAPath); v != "" { - config.TLSConfig.CAPath = v - } - if v := os.Getenv(HTTPClientCert); v != "" { - config.TLSConfig.CertFile = v - } - if v := os.Getenv(HTTPClientKey); v != "" { - config.TLSConfig.KeyFile = v - } - if v := os.Getenv(HTTPSSLVerifyEnvName); v != "" { - doVerify, err := strconv.ParseBool(v) - if err != nil { - logger.Warn(fmt.Sprintf("could not parse %s", HTTPSSLVerifyEnvName), "error", err) - } - if !doVerify { - config.TLSConfig.InsecureSkipVerify = true - } - } - - if v := os.Getenv(HTTPNamespaceEnvName); v != "" { - config.Namespace = v - } - - if v := os.Getenv(HTTPPartitionEnvName); v != "" { - config.Partition = v - } - - return config -} - -// TLSConfig is used to generate a TLSClientConfig that's useful for talking to -// Consul using TLS. -func SetupTLSConfig(tlsConfig *TLSConfig) (*tls.Config, error) { - tlsClientConfig := &tls.Config{ - InsecureSkipVerify: tlsConfig.InsecureSkipVerify, - } - - if tlsConfig.Address != "" { - server := tlsConfig.Address - hasPort := strings.LastIndex(server, ":") > strings.LastIndex(server, "]") - if hasPort { - var err error - server, _, err = net.SplitHostPort(server) - if err != nil { - return nil, err - } - } - tlsClientConfig.ServerName = server - } - - if len(tlsConfig.CertPEM) != 0 && len(tlsConfig.KeyPEM) != 0 { - tlsCert, err := tls.X509KeyPair(tlsConfig.CertPEM, tlsConfig.KeyPEM) - if err != nil { - return nil, err - } - tlsClientConfig.Certificates = []tls.Certificate{tlsCert} - } else if len(tlsConfig.CertPEM) != 0 || len(tlsConfig.KeyPEM) != 0 { - return nil, fmt.Errorf("both client cert and client key must be provided") - } - - if tlsConfig.CertFile != "" && tlsConfig.KeyFile != "" { - tlsCert, err := tls.LoadX509KeyPair(tlsConfig.CertFile, tlsConfig.KeyFile) - if err != nil { - return nil, err - } - tlsClientConfig.Certificates = []tls.Certificate{tlsCert} - } else if tlsConfig.CertFile != "" || tlsConfig.KeyFile != "" { - return nil, fmt.Errorf("both client cert and client key must be provided") - } - - if tlsConfig.CAFile != "" || tlsConfig.CAPath != "" || len(tlsConfig.CAPem) != 0 { - rootConfig := &rootcerts.Config{ - CAFile: tlsConfig.CAFile, - CAPath: tlsConfig.CAPath, - CACertificate: tlsConfig.CAPem, - } - if err := rootcerts.ConfigureTLS(tlsClientConfig, rootConfig); err != nil { - return nil, err - } - } - - return tlsClientConfig, nil -} - -func (c *Config) GenerateEnv() []string { - env := make([]string, 0, 10) - - env = append(env, - fmt.Sprintf("%s=%s", HTTPAddrEnvName, c.Address), - fmt.Sprintf("%s=%s", HTTPTokenEnvName, c.Token), - fmt.Sprintf("%s=%s", HTTPTokenFileEnvName, c.TokenFile), - fmt.Sprintf("%s=%t", HTTPSSLEnvName, c.Scheme == "https"), - fmt.Sprintf("%s=%s", HTTPCAFile, c.TLSConfig.CAFile), - fmt.Sprintf("%s=%s", HTTPCAPath, c.TLSConfig.CAPath), - fmt.Sprintf("%s=%s", HTTPClientCert, c.TLSConfig.CertFile), - fmt.Sprintf("%s=%s", HTTPClientKey, c.TLSConfig.KeyFile), - fmt.Sprintf("%s=%s", HTTPTLSServerName, c.TLSConfig.Address), - fmt.Sprintf("%s=%t", HTTPSSLVerifyEnvName, !c.TLSConfig.InsecureSkipVerify)) - - if c.HttpAuth != nil { - env = append(env, fmt.Sprintf("%s=%s:%s", HTTPAuthEnvName, c.HttpAuth.Username, c.HttpAuth.Password)) - } else { - env = append(env, fmt.Sprintf("%s=", HTTPAuthEnvName)) - } - - return env -} - -// Client provides a client to the Consul API -type Client struct { - modifyLock sync.RWMutex - headers http.Header - - config Config -} - -// Headers gets the current set of headers used for requests. This returns a -// copy; to modify it call AddHeader or SetHeaders. -func (c *Client) Headers() http.Header { - c.modifyLock.RLock() - defer c.modifyLock.RUnlock() - - if c.headers == nil { - return nil - } - - ret := make(http.Header) - for k, v := range c.headers { - for _, val := range v { - ret[k] = append(ret[k], val) - } - } - - return ret -} - -// AddHeader allows a single header key/value pair to be added -// in a race-safe fashion. -func (c *Client) AddHeader(key, value string) { - c.modifyLock.Lock() - defer c.modifyLock.Unlock() - c.headers.Add(key, value) -} - -// SetHeaders clears all previous headers and uses only the given -// ones going forward. -func (c *Client) SetHeaders(headers http.Header) { - c.modifyLock.Lock() - defer c.modifyLock.Unlock() - c.headers = headers -} - -// NewClient returns a new client -func NewClient(config *Config) (*Client, error) { - // bootstrap the config - defConfig := DefaultConfig() - - if config.Address == "" { - config.Address = defConfig.Address - } - - if config.Scheme == "" { - config.Scheme = defConfig.Scheme - } - - if config.Transport == nil { - config.Transport = defConfig.Transport - } - - if config.TLSConfig.Address == "" { - config.TLSConfig.Address = defConfig.TLSConfig.Address - } - - if config.TLSConfig.CAFile == "" { - config.TLSConfig.CAFile = defConfig.TLSConfig.CAFile - } - - if config.TLSConfig.CAPath == "" { - config.TLSConfig.CAPath = defConfig.TLSConfig.CAPath - } - - if config.TLSConfig.CertFile == "" { - config.TLSConfig.CertFile = defConfig.TLSConfig.CertFile - } - - if config.TLSConfig.KeyFile == "" { - config.TLSConfig.KeyFile = defConfig.TLSConfig.KeyFile - } - - if !config.TLSConfig.InsecureSkipVerify { - config.TLSConfig.InsecureSkipVerify = defConfig.TLSConfig.InsecureSkipVerify - } - - if config.HttpClient == nil { - var err error - config.HttpClient, err = NewHttpClient(config.Transport, config.TLSConfig) - if err != nil { - return nil, err - } - } - - if config.Namespace == "" { - config.Namespace = defConfig.Namespace - } - - if config.Partition == "" { - config.Partition = defConfig.Partition - } - - parts := strings.SplitN(config.Address, "://", 2) - if len(parts) == 2 { - switch parts[0] { - case "http": - // Never revert to http if TLS was explicitly requested. - case "https": - config.Scheme = "https" - case "unix": - trans := cleanhttp.DefaultTransport() - trans.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) { - return net.Dial("unix", parts[1]) - } - httpClient, err := NewHttpClient(trans, config.TLSConfig) - if err != nil { - return nil, err - } - config.HttpClient = httpClient - default: - return nil, fmt.Errorf("Unknown protocol scheme: %s", parts[0]) - } - config.Address = parts[1] - - // separate out a reverse proxy prefix, if it is present. - // NOTE: Rewriting this code to use url.Parse() instead of - // strings.SplitN() breaks existing test cases. - switch parts[0] { - case "http", "https": - parts := strings.SplitN(parts[1], "/", 2) - if len(parts) == 2 { - config.Address = parts[0] - config.PathPrefix = "/" + parts[1] - } - } - } - - // If the TokenFile is set, always use that, even if a Token is configured. - // This is because when TokenFile is set it is read into the Token field. - // We want any derived clients to have to re-read the token file. - // The precedence of ACL token should be: - // 1. -token-file cli option - // 2. -token cli option - // 3. CONSUL_HTTP_TOKEN_FILE environment variable - // 4. CONSUL_HTTP_TOKEN environment variable - if config.TokenFile != "" && config.TokenFile != defConfig.TokenFile { - data, err := os.ReadFile(config.TokenFile) - if err != nil { - return nil, fmt.Errorf("Error loading token file %s : %s", config.TokenFile, err) - } - - if token := strings.TrimSpace(string(data)); token != "" { - config.Token = token - } - } else if config.Token != "" && defConfig.Token != config.Token { - // Fall through - } else if defConfig.TokenFile != "" { - data, err := os.ReadFile(defConfig.TokenFile) - if err != nil { - return nil, fmt.Errorf("Error loading token file %s : %s", defConfig.TokenFile, err) - } - - if token := strings.TrimSpace(string(data)); token != "" { - config.Token = token - config.TokenFile = defConfig.TokenFile - } - } else { - config.Token = defConfig.Token - } - return &Client{config: *config, headers: make(http.Header)}, nil -} - -// NewHttpClient returns an http client configured with the given Transport and TLS -// config. -func NewHttpClient(transport *http.Transport, tlsConf TLSConfig) (*http.Client, error) { - client := &http.Client{ - Transport: transport, - } - - // TODO (slackpad) - Once we get some run time on the HTTP/2 support we - // should turn it on by default if TLS is enabled. We would basically - // just need to call http2.ConfigureTransport(transport) here. We also - // don't want to introduce another external dependency on - // golang.org/x/net/http2 at this time. For a complete recipe for how - // to enable HTTP/2 support on a transport suitable for the API client - // library see agent/http_test.go:TestHTTPServer_H2. - - if transport.TLSClientConfig == nil { - tlsClientConfig, err := SetupTLSConfig(&tlsConf) - - if err != nil { - return nil, err - } - - transport.TLSClientConfig = tlsClientConfig - } - - return client, nil -} - -// request is used to help build up a request -type request struct { - config *Config - method string - url *url.URL - params url.Values - body io.Reader - header http.Header - obj interface{} - ctx context.Context -} - -// setQueryOptions is used to annotate the request with -// additional query options -func (r *request) setQueryOptions(q *QueryOptions) { - if q == nil { - return - } - if q.Namespace != "" { - // For backwards-compatibility with existing tests, - // use the short-hand query param name "ns" - // rather than the alternative long-hand "namespace" - r.params.Set("ns", q.Namespace) - } - if q.Partition != "" { - // For backwards-compatibility with existing tests, - // use the long-hand query param name "partition" - // rather than the alternative short-hand "ap" - r.params.Set("partition", q.Partition) - } - if q.SamenessGroup != "" { - // For backwards-compatibility with existing tests, - // use the long-hand query param name "sameness-group" - // rather than the alternative short-hand "sg" - r.params.Set("sameness-group", q.SamenessGroup) - } - if q.Datacenter != "" { - // For backwards-compatibility with existing tests, - // use the short-hand query param name "dc" - // rather than the alternative long-hand "datacenter" - r.params.Set("dc", q.Datacenter) - } - if q.Peer != "" { - r.params.Set("peer", q.Peer) - } - if q.AllowStale { - r.params.Set("stale", "") - } - if q.RequireConsistent { - r.params.Set("consistent", "") - } - if q.WaitIndex != 0 { - r.params.Set("index", strconv.FormatUint(q.WaitIndex, 10)) - } - if q.WaitTime != 0 { - r.params.Set("wait", durToMsec(q.WaitTime)) - } - if q.WaitHash != "" { - r.params.Set("hash", q.WaitHash) - } - if q.Token != "" { - r.header.Set("X-Consul-Token", q.Token) - } - if q.Near != "" { - r.params.Set("near", q.Near) - } - if q.Filter != "" { - r.params.Set("filter", q.Filter) - } - if len(q.NodeMeta) > 0 { - for key, value := range q.NodeMeta { - r.params.Add("node-meta", key+":"+value) - } - } - if q.RelayFactor != 0 { - r.params.Set("relay-factor", strconv.Itoa(int(q.RelayFactor))) - } - if q.LocalOnly { - r.params.Set("local-only", fmt.Sprintf("%t", q.LocalOnly)) - } - if q.Connect { - r.params.Set("connect", "true") - } - if q.UseCache && !q.RequireConsistent { - r.params.Set("cached", "") - - cc := []string{} - if q.MaxAge > 0 { - cc = append(cc, fmt.Sprintf("max-age=%.0f", q.MaxAge.Seconds())) - } - if q.StaleIfError > 0 { - cc = append(cc, fmt.Sprintf("stale-if-error=%.0f", q.StaleIfError.Seconds())) - } - if len(cc) > 0 { - r.header.Set("Cache-Control", strings.Join(cc, ", ")) - } - } - if q.MergeCentralConfig { - r.params.Set("merge-central-config", "") - } - if q.Global { - r.params.Set("global", "") - } - - r.ctx = q.ctx -} - -// durToMsec converts a duration to a millisecond specified string. If the -// user selected a positive value that rounds to 0 ms, then we will use 1 ms -// so they get a short delay, otherwise Consul will translate the 0 ms into -// a huge default delay. -func durToMsec(dur time.Duration) string { - ms := dur / time.Millisecond - if dur > 0 && ms == 0 { - ms = 1 - } - return fmt.Sprintf("%dms", ms) -} - -// serverError is a string we look for to detect 500 errors. -const serverError = "Unexpected response code: 500" - -// IsRetryableError returns true for 500 errors from the Consul servers, and -// network connection errors. These are usually retryable at a later time. -// This applies to reads but NOT to writes. This may return true for errors -// on writes that may have still gone through, so do not use this to retry -// any write operations. -func IsRetryableError(err error) bool { - if err == nil { - return false - } - - if _, ok := err.(net.Error); ok { - return true - } - - // TODO (slackpad) - Make a real error type here instead of using - // a string check. - return strings.Contains(err.Error(), serverError) -} - -// setWriteOptions is used to annotate the request with -// additional write options -func (r *request) setWriteOptions(q *WriteOptions) { - if q == nil { - return - } - // For backwards-compatibility, continue to use the shorthand "ns" - // rather than "namespace" - if q.Namespace != "" { - r.params.Set("ns", q.Namespace) - } - if q.Partition != "" { - r.params.Set("partition", q.Partition) - } - // For backwards-compatibility, continue to use the shorthand "dc" - // rather than "datacenter" - if q.Datacenter != "" { - r.params.Set("dc", q.Datacenter) - } - if q.Token != "" { - r.header.Set("X-Consul-Token", q.Token) - } - if q.RelayFactor != 0 { - r.params.Set("relay-factor", strconv.Itoa(int(q.RelayFactor))) - } - r.ctx = q.ctx -} - -// toHTTP converts the request to an HTTP request -func (r *request) toHTTP() (*http.Request, error) { - // Encode the query parameters - r.url.RawQuery = r.params.Encode() - - // Check if we should encode the body - if r.body == nil && r.obj != nil { - b, err := encodeBody(r.obj) - if err != nil { - return nil, err - } - r.body = b - } - - // Create the HTTP request - req, err := http.NewRequest(r.method, r.url.RequestURI(), r.body) - if err != nil { - return nil, err - } - - // validate that socket communications that do not use the host, detect - // slashes in the host name and replace it with local host. - // this is required since go started validating req.host in 1.20.6 and 1.19.11. - // prior to that they would strip out the slashes for you. They removed that - // behavior and added more strict validation as part of a CVE. - // This issue is being tracked by the Go team: - // https://github.com/golang/go/issues/61431 - // If there is a resolution in this issue, we will remove this code. - // In the time being, this is the accepted workaround. - if strings.HasPrefix(r.url.Host, "/") { - r.url.Host = "localhost" - } - - req.URL.Host = r.url.Host - req.URL.Scheme = r.url.Scheme - req.Host = r.url.Host - req.Header = r.header - - // Content-Type must always be set when a body is present - // See https://github.com/hashicorp/consul/issues/10011 - if req.Body != nil && req.Header.Get("Content-Type") == "" { - req.Header.Set("Content-Type", "application/json") - } - - // Setup auth - if r.config.HttpAuth != nil { - req.SetBasicAuth(r.config.HttpAuth.Username, r.config.HttpAuth.Password) - } - if r.ctx != nil { - return req.WithContext(r.ctx), nil - } - - return req, nil -} - -// newRequest is used to create a new request -func (c *Client) newRequest(method, path string) *request { - r := &request{ - config: &c.config, - method: method, - url: &url.URL{ - Scheme: c.config.Scheme, - Host: c.config.Address, - Path: c.config.PathPrefix + path, - }, - params: make(map[string][]string), - header: c.Headers(), - } - - if c.config.Datacenter != "" { - r.params.Set("dc", c.config.Datacenter) - } - if c.config.Namespace != "" { - r.params.Set("ns", c.config.Namespace) - } - if c.config.Partition != "" { - r.params.Set("partition", c.config.Partition) - } - if c.config.WaitTime != 0 { - r.params.Set("wait", durToMsec(r.config.WaitTime)) - } - if c.config.Token != "" { - r.header.Set("X-Consul-Token", r.config.Token) - } - return r -} - -// doRequest runs a request with our client -func (c *Client) doRequest(r *request) (time.Duration, *http.Response, error) { - req, err := r.toHTTP() - if err != nil { - return 0, nil, err - } - start := time.Now() - resp, err := c.config.HttpClient.Do(req) - diff := time.Since(start) - return diff, resp, err -} - -// Query is used to do a GET request against an endpoint -// and deserialize the response into an interface using -// standard Consul conventions. -func (c *Client) query(endpoint string, out interface{}, q *QueryOptions) (*QueryMeta, error) { - r := c.newRequest("GET", endpoint) - r.setQueryOptions(q) - rtt, resp, err := c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if err := decodeBody(resp, out); err != nil { - return nil, err - } - return qm, nil -} - -// write is used to do a PUT request against an endpoint -// and serialize/deserialized using the standard Consul conventions. -func (c *Client) write(endpoint string, in, out interface{}, q *WriteOptions) (*WriteMeta, error) { - r := c.newRequest("PUT", endpoint) - r.setWriteOptions(q) - r.obj = in - rtt, resp, err := c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - if out != nil { - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - } else if _, err := io.ReadAll(resp.Body); err != nil { - return nil, err - } - return wm, nil -} - -// delete is used to do a DELETE request against an endpoint -func (c *Client) delete(endpoint string, q *QueryOptions) (*WriteMeta, error) { - r := c.newRequest("DELETE", endpoint) - r.setQueryOptions(q) - rtt, resp, err := c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err = requireHttpCodes(resp, 204, 200); err != nil { - return nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - return wm, nil -} - -// parseQueryMeta is used to help parse query meta-data -// -// TODO(rb): bug? the error from this function is never handled -func parseQueryMeta(resp *http.Response, q *QueryMeta) error { - header := resp.Header - - // Parse the X-Consul-Index (if it's set - hash based blocking queries don't - // set this) - if indexStr := header.Get("X-Consul-Index"); indexStr != "" { - index, err := strconv.ParseUint(indexStr, 10, 64) - if err != nil { - return fmt.Errorf("Failed to parse X-Consul-Index: %v", err) - } - q.LastIndex = index - } - q.LastContentHash = header.Get("X-Consul-ContentHash") - - // Parse the X-Consul-LastContact - last, err := strconv.ParseUint(header.Get("X-Consul-LastContact"), 10, 64) - if err != nil { - return fmt.Errorf("Failed to parse X-Consul-LastContact: %v", err) - } - if last > math.MaxInt64 { - return fmt.Errorf("X-Consul-LastContact Header value is out of range: %d", last) - } - q.LastContact = time.Duration(last) * time.Millisecond - - // Parse the X-Consul-KnownLeader - switch header.Get("X-Consul-KnownLeader") { - case "true": - q.KnownLeader = true - default: - q.KnownLeader = false - } - - // Parse X-Consul-Translate-Addresses - switch header.Get("X-Consul-Translate-Addresses") { - case "true": - q.AddressTranslationEnabled = true - default: - q.AddressTranslationEnabled = false - } - - // Parse X-Consul-Default-ACL-Policy - switch v := header.Get("X-Consul-Default-ACL-Policy"); v { - case "allow", "deny": - q.DefaultACLPolicy = v - } - - // Parse the X-Consul-Results-Filtered-By-ACLs - switch header.Get("X-Consul-Results-Filtered-By-ACLs") { - case "true": - q.ResultsFilteredByACLs = true - default: - q.ResultsFilteredByACLs = false - } - - // Parse Cache info - if cacheStr := header.Get("X-Cache"); cacheStr != "" { - q.CacheHit = strings.EqualFold(cacheStr, "HIT") - } - if ageStr := header.Get("Age"); ageStr != "" { - age, err := strconv.ParseUint(ageStr, 10, 64) - if err != nil { - return fmt.Errorf("Failed to parse Age Header: %v", err) - } - if age > math.MaxInt64 { - return fmt.Errorf("Age Header value is out of range: %d", last) - } - q.CacheAge = time.Duration(age) * time.Second - } - - switch v := header.Get("X-Consul-Query-Backend"); v { - case QueryBackendStreaming, QueryBackendBlockingQuery: - q.QueryBackend = v - } - return nil -} - -// decodeBody is used to JSON decode a body -func decodeBody(resp *http.Response, out interface{}) error { - dec := json.NewDecoder(resp.Body) - return dec.Decode(out) -} - -// encodeBody is used to encode a request body -func encodeBody(obj interface{}) (io.Reader, error) { - buf := bytes.NewBuffer(nil) - enc := json.NewEncoder(buf) - if err := enc.Encode(obj); err != nil { - return nil, err - } - return buf, nil -} - -// requireOK is used to wrap doRequest and check for a 200 -func requireOK(resp *http.Response) error { - return requireHttpCodes(resp, 200) -} - -// requireHttpCodes checks for the "allowable" http codes for a response -func requireHttpCodes(resp *http.Response, httpCodes ...int) error { - // if there is an http code that we require, return w no error - for _, httpCode := range httpCodes { - if resp.StatusCode == httpCode { - return nil - } - } - - // if we reached here, then none of the http codes in resp matched any that we expected - // so err out - return generateUnexpectedResponseCodeError(resp) -} - -// closeResponseBody reads resp.Body until EOF, and then closes it. The read -// is necessary to ensure that the http.Client's underlying RoundTripper is able -// to re-use the TCP connection. See godoc on net/http.Client.Do. -func closeResponseBody(resp *http.Response) error { - _, _ = io.Copy(io.Discard, resp.Body) - return resp.Body.Close() -} - -func (req *request) filterQuery(filter string) { - if filter == "" { - return - } - - req.params.Set("filter", filter) -} - -// generateUnexpectedResponseCodeError consumes the rest of the body, closes -// the body stream and generates an error indicating the status code was -// unexpected. -func generateUnexpectedResponseCodeError(resp *http.Response) error { - var buf bytes.Buffer - io.Copy(&buf, resp.Body) - closeResponseBody(resp) - - trimmed := strings.TrimSpace(string(buf.Bytes())) - return StatusError{Code: resp.StatusCode, Body: trimmed} -} - -func requireNotFoundOrOK(resp *http.Response) (bool, *http.Response, error) { - switch resp.StatusCode { - case 200: - return true, resp, nil - case 404: - return false, resp, nil - default: - return false, nil, generateUnexpectedResponseCodeError(resp) - } -} diff --git a/vendor/github.com/hashicorp/consul/api/catalog.go b/vendor/github.com/hashicorp/consul/api/catalog.go deleted file mode 100644 index 0040ca6e7a855..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/catalog.go +++ /dev/null @@ -1,377 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "net" - "strconv" -) - -type Weights struct { - Passing int - Warning int -} - -type Node struct { - ID string - Node string - Address string - Datacenter string - TaggedAddresses map[string]string - Meta map[string]string - CreateIndex uint64 - ModifyIndex uint64 - Partition string `json:",omitempty"` - PeerName string `json:",omitempty"` - Locality *Locality `json:",omitempty"` -} - -type ServiceAddress struct { - Address string - Port int -} - -type CatalogService struct { - ID string - Node string - Address string - Datacenter string - TaggedAddresses map[string]string - NodeMeta map[string]string - ServiceID string - ServiceName string - ServiceAddress string - ServiceTaggedAddresses map[string]ServiceAddress - ServiceTags []string - ServiceMeta map[string]string - ServicePort int - ServiceWeights Weights - ServiceEnableTagOverride bool - ServiceProxy *AgentServiceConnectProxyConfig - ServiceLocality *Locality `json:",omitempty"` - CreateIndex uint64 - Checks HealthChecks - ModifyIndex uint64 - Namespace string `json:",omitempty"` - Partition string `json:",omitempty"` -} - -type CatalogNode struct { - Node *Node - Services map[string]*AgentService -} - -type CatalogNodeServiceList struct { - Node *Node - Services []*AgentService -} - -type CatalogRegistration struct { - ID string - Node string - Address string - TaggedAddresses map[string]string - NodeMeta map[string]string - Datacenter string - Service *AgentService - Check *AgentCheck - Checks HealthChecks - SkipNodeUpdate bool - Partition string `json:",omitempty"` - Locality *Locality `json:",omitempty"` -} - -type CatalogDeregistration struct { - Node string - Address string `json:",omitempty"` // Obsolete. - Datacenter string - ServiceID string - CheckID string - Namespace string `json:",omitempty"` - Partition string `json:",omitempty"` -} - -type CompoundServiceName struct { - Name string - - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` - // Partitions are a Consul Enterprise feature. - Partition string `json:",omitempty"` -} - -// GatewayService associates a gateway with a linked service. -// It also contains service-specific gateway configuration like ingress listener port and protocol. -type GatewayService struct { - Gateway CompoundServiceName - Service CompoundServiceName - GatewayKind ServiceKind - Port int `json:",omitempty"` - Protocol string `json:",omitempty"` - Hosts []string `json:",omitempty"` - CAFile string `json:",omitempty"` - CertFile string `json:",omitempty"` - KeyFile string `json:",omitempty"` - SNI string `json:",omitempty"` - FromWildcard bool `json:",omitempty"` -} - -// Catalog can be used to query the Catalog endpoints -type Catalog struct { - c *Client -} - -// Catalog returns a handle to the catalog endpoints -func (c *Client) Catalog() *Catalog { - return &Catalog{c} -} - -func (c *Catalog) Register(reg *CatalogRegistration, q *WriteOptions) (*WriteMeta, error) { - r := c.c.newRequest("PUT", "/v1/catalog/register") - r.setWriteOptions(q) - r.obj = reg - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{} - wm.RequestTime = rtt - - return wm, nil -} - -func (c *Catalog) Deregister(dereg *CatalogDeregistration, q *WriteOptions) (*WriteMeta, error) { - r := c.c.newRequest("PUT", "/v1/catalog/deregister") - r.setWriteOptions(q) - r.obj = dereg - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{} - wm.RequestTime = rtt - - return wm, nil -} - -// Datacenters is used to query for all the known datacenters -func (c *Catalog) Datacenters() ([]string, error) { - r := c.c.newRequest("GET", "/v1/catalog/datacenters") - _, resp, err := c.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - var out []string - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - return out, nil -} - -// Nodes is used to query all the known nodes -func (c *Catalog) Nodes(q *QueryOptions) ([]*Node, *QueryMeta, error) { - r := c.c.newRequest("GET", "/v1/catalog/nodes") - r.setQueryOptions(q) - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out []*Node - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// Services is used to query for all known services -func (c *Catalog) Services(q *QueryOptions) (map[string][]string, *QueryMeta, error) { - r := c.c.newRequest("GET", "/v1/catalog/services") - r.setQueryOptions(q) - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out map[string][]string - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// Service is used to query catalog entries for a given service -func (c *Catalog) Service(service, tag string, q *QueryOptions) ([]*CatalogService, *QueryMeta, error) { - var tags []string - if tag != "" { - tags = []string{tag} - } - return c.service(service, tags, q, false) -} - -// Supports multiple tags for filtering -func (c *Catalog) ServiceMultipleTags(service string, tags []string, q *QueryOptions) ([]*CatalogService, *QueryMeta, error) { - return c.service(service, tags, q, false) -} - -// Connect is used to query catalog entries for a given Connect-enabled service -func (c *Catalog) Connect(service, tag string, q *QueryOptions) ([]*CatalogService, *QueryMeta, error) { - var tags []string - if tag != "" { - tags = []string{tag} - } - return c.service(service, tags, q, true) -} - -// Supports multiple tags for filtering -func (c *Catalog) ConnectMultipleTags(service string, tags []string, q *QueryOptions) ([]*CatalogService, *QueryMeta, error) { - return c.service(service, tags, q, true) -} - -func (c *Catalog) service(service string, tags []string, q *QueryOptions, connect bool) ([]*CatalogService, *QueryMeta, error) { - path := "/v1/catalog/service/" + service - if connect { - path = "/v1/catalog/connect/" + service - } - r := c.c.newRequest("GET", path) - r.setQueryOptions(q) - if len(tags) > 0 { - for _, tag := range tags { - r.params.Add("tag", tag) - } - } - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out []*CatalogService - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// Node is used to query for service information about a single node -func (c *Catalog) Node(node string, q *QueryOptions) (*CatalogNode, *QueryMeta, error) { - r := c.c.newRequest("GET", "/v1/catalog/node/"+node) - r.setQueryOptions(q) - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out *CatalogNode - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// NodeServiceList is used to query for service information about a single node. It differs from -// the Node function only in its return type which will contain a list of services as opposed to -// a map of service ids to services. This different structure allows for using the wildcard specifier -// '*' for the Namespace in the QueryOptions. -func (c *Catalog) NodeServiceList(node string, q *QueryOptions) (*CatalogNodeServiceList, *QueryMeta, error) { - r := c.c.newRequest("GET", "/v1/catalog/node-services/"+node) - r.setQueryOptions(q) - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out *CatalogNodeServiceList - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// GatewayServices is used to query the services associated with an ingress gateway or terminating gateway. -func (c *Catalog) GatewayServices(gateway string, q *QueryOptions) ([]*GatewayService, *QueryMeta, error) { - r := c.c.newRequest("GET", "/v1/catalog/gateway-services/"+gateway) - r.setQueryOptions(q) - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out []*GatewayService - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} - -func ParseServiceAddr(addrPort string) (ServiceAddress, error) { - port := 0 - host, portStr, err := net.SplitHostPort(addrPort) - if err == nil { - port, err = strconv.Atoi(portStr) - } - return ServiceAddress{Address: host, Port: port}, err -} diff --git a/vendor/github.com/hashicorp/consul/api/config_entry.go b/vendor/github.com/hashicorp/consul/api/config_entry.go deleted file mode 100644 index 8c3a080f70bda..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/config_entry.go +++ /dev/null @@ -1,691 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "strconv" - "strings" - "time" - - "github.com/mitchellh/mapstructure" -) - -const ( - ServiceDefaults string = "service-defaults" - ProxyDefaults string = "proxy-defaults" - ServiceRouter string = "service-router" - ServiceSplitter string = "service-splitter" - ServiceResolver string = "service-resolver" - IngressGateway string = "ingress-gateway" - TerminatingGateway string = "terminating-gateway" - ServiceIntentions string = "service-intentions" - MeshConfig string = "mesh" - ExportedServices string = "exported-services" - SamenessGroup string = "sameness-group" - RateLimitIPConfig string = "control-plane-request-limit" - - ProxyConfigGlobal string = "global" - MeshConfigMesh string = "mesh" - APIGateway string = "api-gateway" - TCPRoute string = "tcp-route" - FileSystemCertificate string = "file-system-certificate" - InlineCertificate string = "inline-certificate" - HTTPRoute string = "http-route" - JWTProvider string = "jwt-provider" -) - -const ( - BuiltinAWSLambdaExtension string = "builtin/aws/lambda" - BuiltinExtAuthzExtension string = "builtin/ext-authz" - BuiltinLuaExtension string = "builtin/lua" - BuiltinOTELAccessLoggingExtension string = "builtin/otel-access-logging" - BuiltinPropertyOverrideExtension string = "builtin/property-override" - BuiltinWasmExtension string = "builtin/wasm" - // BuiltinValidateExtension should not be exposed directly or accepted as a valid configured - // extension type, as it is only used indirectly via troubleshooting tools. It is included here - // for common reference alongside other builtin extensions. - BuiltinValidateExtension string = "builtin/proxy/validate" -) - -type ConfigEntry interface { - GetKind() string - GetName() string - GetPartition() string - GetNamespace() string - GetMeta() map[string]string - GetCreateIndex() uint64 - GetModifyIndex() uint64 -} - -type MeshGatewayMode string - -const ( - // MeshGatewayModeDefault represents no specific mode and should - // be used to indicate that a different layer of the configuration - // chain should take precedence - MeshGatewayModeDefault MeshGatewayMode = "" - - // MeshGatewayModeNone represents that the Upstream Connect connections - // should be direct and not flow through a mesh gateway. - MeshGatewayModeNone MeshGatewayMode = "none" - - // MeshGatewayModeLocal represents that the Upstream Connect connections - // should be made to a mesh gateway in the local datacenter. - MeshGatewayModeLocal MeshGatewayMode = "local" - - // MeshGatewayModeRemote represents that the Upstream Connect connections - // should be made to a mesh gateway in a remote datacenter. - MeshGatewayModeRemote MeshGatewayMode = "remote" -) - -// MeshGatewayConfig controls how Mesh Gateways are used for upstream Connect -// services -type MeshGatewayConfig struct { - // Mode is the mode that should be used for the upstream connection. - Mode MeshGatewayMode `json:",omitempty"` -} - -type ProxyMode string - -const ( - // ProxyModeDefault represents no specific mode and should - // be used to indicate that a different layer of the configuration - // chain should take precedence - ProxyModeDefault ProxyMode = "" - - // ProxyModeTransparent represents that inbound and outbound application - // traffic is being captured and redirected through the proxy. - ProxyModeTransparent ProxyMode = "transparent" - - // ProxyModeDirect represents that the proxy's listeners must be dialed directly - // by the local application and other proxies. - ProxyModeDirect ProxyMode = "direct" -) - -type TransparentProxyConfig struct { - // The port of the listener where outbound application traffic is being redirected to. - OutboundListenerPort int `json:",omitempty" alias:"outbound_listener_port"` - - // DialedDirectly indicates whether transparent proxies can dial this proxy instance directly. - // The discovery chain is not considered when dialing a service instance directly. - // This setting is useful when addressing stateful services, such as a database cluster with a leader node. - DialedDirectly bool `json:",omitempty" alias:"dialed_directly"` -} - -type MutualTLSMode string - -const ( - // MutualTLSModeDefault represents no specific mode and should - // be used to indicate that a different layer of the configuration - // chain should take precedence. - MutualTLSModeDefault MutualTLSMode = "" - - // MutualTLSModeStrict requires mTLS for incoming traffic. - MutualTLSModeStrict MutualTLSMode = "strict" - - // MutualTLSModePermissive allows incoming non-mTLS traffic. - MutualTLSModePermissive MutualTLSMode = "permissive" -) - -// ExposeConfig describes HTTP paths to expose through Envoy outside of Connect. -// Users can expose individual paths and/or all HTTP/GRPC paths for checks. -type ExposeConfig struct { - // Checks defines whether paths associated with Consul checks will be exposed. - // This flag triggers exposing all HTTP and GRPC check paths registered for the service. - Checks bool `json:",omitempty"` - - // Paths is the list of paths exposed through the proxy. - Paths []ExposePath `json:",omitempty"` -} - -// EnvoyExtension has configuration for an extension that patches Envoy resources. -type EnvoyExtension struct { - Name string - Required bool - Arguments map[string]interface{} `bexpr:"-"` - ConsulVersion string - EnvoyVersion string -} - -type ExposePath struct { - // ListenerPort defines the port of the proxy's listener for exposed paths. - ListenerPort int `json:",omitempty" alias:"listener_port"` - - // Path is the path to expose through the proxy, ie. "/metrics." - Path string `json:",omitempty"` - - // LocalPathPort is the port that the service is listening on for the given path. - LocalPathPort int `json:",omitempty" alias:"local_path_port"` - - // Protocol describes the upstream's service protocol. - // Valid values are "http" and "http2", defaults to "http" - Protocol string `json:",omitempty"` - - // ParsedFromCheck is set if this path was parsed from a registered check - ParsedFromCheck bool -} - -type LogSinkType string - -const ( - DefaultLogSinkType LogSinkType = "" - FileLogSinkType LogSinkType = "file" - StdErrLogSinkType LogSinkType = "stderr" - StdOutLogSinkType LogSinkType = "stdout" -) - -// AccessLogsConfig contains the associated default settings for all Envoy instances within the datacenter or partition -type AccessLogsConfig struct { - // Enabled turns off all access logging - Enabled bool `json:",omitempty" alias:"enabled"` - - // DisableListenerLogs turns off just listener logs for connections rejected by Envoy because they don't - // have a matching listener filter. - DisableListenerLogs bool `json:",omitempty" alias:"disable_listener_logs"` - - // Type selects the output for logs: "file", "stderr". "stdout" - Type LogSinkType `json:",omitempty" alias:"type"` - - // Path is the output file to write logs - Path string `json:",omitempty" alias:"path"` - - // The presence of one format string or the other implies the access log string encoding. - // Defining Both is invalid. - JSONFormat string `json:",omitempty" alias:"json_format"` - TextFormat string `json:",omitempty" alias:"text_format"` -} - -type UpstreamConfiguration struct { - // Overrides is a slice of per-service configuration. The name field is - // required. - Overrides []*UpstreamConfig `json:",omitempty"` - - // Defaults contains default configuration for all upstreams of a given - // service. The name field must be empty. - Defaults *UpstreamConfig `json:",omitempty"` -} - -type UpstreamConfig struct { - // Name is only accepted within service-defaults.upstreamConfig.overrides . - Name string `json:",omitempty"` - - // Partition is only accepted within service-defaults.upstreamConfig.overrides . - Partition string `json:",omitempty"` - - // Namespace is only accepted within service-defaults.upstreamConfig.overrides . - Namespace string `json:",omitempty"` - - // Peer is only accepted within service-defaults.upstreamConfig.overrides . - Peer string `json:",omitempty"` - - // EnvoyListenerJSON is a complete override ("escape hatch") for the upstream's - // listener. - // - // Note: This escape hatch is NOT compatible with the discovery chain and - // will be ignored if a discovery chain is active. - EnvoyListenerJSON string `json:",omitempty" alias:"envoy_listener_json"` - - // EnvoyClusterJSON is a complete override ("escape hatch") for the upstream's - // cluster. The Connect client TLS certificate and context will be injected - // overriding any TLS settings present. - // - // Note: This escape hatch is NOT compatible with the discovery chain and - // will be ignored if a discovery chain is active. - EnvoyClusterJSON string `json:",omitempty" alias:"envoy_cluster_json"` - - // Protocol describes the upstream's service protocol. Valid values are "tcp", - // "http" and "grpc". Anything else is treated as tcp. The enables protocol - // aware features like per-request metrics and connection pooling, tracing, - // routing etc. - Protocol string `json:",omitempty"` - - // ConnectTimeoutMs is the number of milliseconds to timeout making a new - // connection to this upstream. Defaults to 5000 (5 seconds) if not set. - ConnectTimeoutMs int `json:",omitempty" alias:"connect_timeout_ms"` - - // Limits are the set of limits that are applied to the proxy for a specific upstream of a - // service instance. - Limits *UpstreamLimits `json:",omitempty"` - - // PassiveHealthCheck configuration determines how upstream proxy instances will - // be monitored for removal from the load balancing pool. - PassiveHealthCheck *PassiveHealthCheck `json:",omitempty" alias:"passive_health_check"` - - // MeshGatewayConfig controls how Mesh Gateways are configured and used - MeshGateway MeshGatewayConfig `json:",omitempty" alias:"mesh_gateway" ` - - // BalanceOutboundConnections indicates that the proxy should attempt to evenly distribute - // outbound connections across worker threads. Only used by envoy proxies. - BalanceOutboundConnections string `json:",omitempty" alias:"balance_outbound_connections"` -} - -// DestinationConfig represents a virtual service, i.e. one that is external to Consul -type DestinationConfig struct { - // Addresses of the endpoint; hostname or IP - Addresses []string `json:",omitempty"` - - // Port allowed within this endpoint - Port int `json:",omitempty"` -} - -type PassiveHealthCheck struct { - // Interval between health check analysis sweeps. Each sweep may remove - // hosts or return hosts to the pool. - Interval time.Duration `json:",omitempty"` - - // MaxFailures is the count of consecutive failures that results in a host - // being removed from the pool. - MaxFailures uint32 `alias:"max_failures"` - - // EnforcingConsecutive5xx is the % chance that a host will be actually ejected - // when an outlier status is detected through consecutive 5xx. - // This setting can be used to disable ejection or to ramp it up slowly. - EnforcingConsecutive5xx *uint32 `json:",omitempty" alias:"enforcing_consecutive_5xx"` - - // The maximum % of an upstream cluster that can be ejected due to outlier detection. - // Defaults to 10% but will eject at least one host regardless of the value. - MaxEjectionPercent *uint32 `json:",omitempty" alias:"max_ejection_percent"` - - // The base time that a host is ejected for. The real time is equal to the base time - // multiplied by the number of times the host has been ejected and is capped by - // max_ejection_time (Default 300s). Defaults to 30000ms or 30s. - BaseEjectionTime *time.Duration `json:",omitempty" alias:"base_ejection_time"` -} - -// UpstreamLimits describes the limits that are associated with a specific -// upstream of a service instance. -type UpstreamLimits struct { - // MaxConnections is the maximum number of connections the local proxy can - // make to the upstream service. - MaxConnections *int `alias:"max_connections"` - - // MaxPendingRequests is the maximum number of requests that will be queued - // waiting for an available connection. This is mostly applicable to HTTP/1.1 - // clusters since all HTTP/2 requests are streamed over a single - // connection. - MaxPendingRequests *int `alias:"max_pending_requests"` - - // MaxConcurrentRequests is the maximum number of in-flight requests that will be allowed - // to the upstream cluster at a point in time. This is mostly applicable to HTTP/2 - // clusters since all HTTP/1.1 requests are limited by MaxConnections. - MaxConcurrentRequests *int `alias:"max_concurrent_requests"` -} - -// RateLimits is rate limiting configuration that is applied to -// inbound traffic for a service. -// Rate limiting is a Consul enterprise feature. -type RateLimits struct { - InstanceLevel InstanceLevelRateLimits `alias:"instance_level"` -} - -// InstanceLevelRateLimits represents rate limit configuration -// that are applied per service instance. -type InstanceLevelRateLimits struct { - // RequestsPerSecond is the average number of requests per second that can be - // made without being throttled. This field is required if RequestsMaxBurst - // is set. The allowed number of requests may exceed RequestsPerSecond up to - // the value specified in RequestsMaxBurst. - // - // Internally, this is the refill rate of the token bucket used for rate limiting. - RequestsPerSecond int `alias:"requests_per_second"` - - // RequestsMaxBurst is the maximum number of requests that can be sent - // in a burst. Should be equal to or greater than RequestsPerSecond. - // If unset, defaults to RequestsPerSecond. - // - // Internally, this is the maximum size of the token bucket used for rate limiting. - RequestsMaxBurst int `alias:"requests_max_burst"` - - // Routes is a list of rate limits applied to specific routes. - // For a given request, the first matching route will be applied, if any - // Overrides any top-level configuration. - Routes []InstanceLevelRouteRateLimits -} - -// InstanceLevelRouteRateLimits represents rate limit configuration -// applied to a route matching one of PathExact/PathPrefix/PathRegex. -type InstanceLevelRouteRateLimits struct { - PathExact string `alias:"path_exact"` - PathPrefix string `alias:"path_prefix"` - PathRegex string `alias:"path_regex"` - - RequestsPerSecond int `alias:"requests_per_second"` - RequestsMaxBurst int `alias:"requests_max_burst"` -} - -type ServiceConfigEntry struct { - Kind string - Name string - Partition string `json:",omitempty"` - Namespace string `json:",omitempty"` - Protocol string `json:",omitempty"` - Mode ProxyMode `json:",omitempty"` - TransparentProxy *TransparentProxyConfig `json:",omitempty" alias:"transparent_proxy"` - MutualTLSMode MutualTLSMode `json:",omitempty" alias:"mutual_tls_mode"` - MeshGateway MeshGatewayConfig `json:",omitempty" alias:"mesh_gateway"` - Expose ExposeConfig `json:",omitempty"` - ExternalSNI string `json:",omitempty" alias:"external_sni"` - UpstreamConfig *UpstreamConfiguration `json:",omitempty" alias:"upstream_config"` - Destination *DestinationConfig `json:",omitempty"` - MaxInboundConnections int `json:",omitempty" alias:"max_inbound_connections"` - LocalConnectTimeoutMs int `json:",omitempty" alias:"local_connect_timeout_ms"` - LocalRequestTimeoutMs int `json:",omitempty" alias:"local_request_timeout_ms"` - BalanceInboundConnections string `json:",omitempty" alias:"balance_inbound_connections"` - RateLimits *RateLimits `json:",omitempty" alias:"rate_limits"` - EnvoyExtensions []EnvoyExtension `json:",omitempty" alias:"envoy_extensions"` - Meta map[string]string `json:",omitempty"` - CreateIndex uint64 - ModifyIndex uint64 -} - -func (s *ServiceConfigEntry) GetKind() string { return s.Kind } -func (s *ServiceConfigEntry) GetName() string { return s.Name } -func (s *ServiceConfigEntry) GetPartition() string { return s.Partition } -func (s *ServiceConfigEntry) GetNamespace() string { return s.Namespace } -func (s *ServiceConfigEntry) GetMeta() map[string]string { return s.Meta } -func (s *ServiceConfigEntry) GetCreateIndex() uint64 { return s.CreateIndex } -func (s *ServiceConfigEntry) GetModifyIndex() uint64 { return s.ModifyIndex } - -type ProxyConfigEntry struct { - Kind string - Name string - Partition string `json:",omitempty"` - Namespace string `json:",omitempty"` - Mode ProxyMode `json:",omitempty"` - TransparentProxy *TransparentProxyConfig `json:",omitempty" alias:"transparent_proxy"` - MutualTLSMode MutualTLSMode `json:",omitempty" alias:"mutual_tls_mode"` - Config map[string]interface{} `json:",omitempty"` - MeshGateway MeshGatewayConfig `json:",omitempty" alias:"mesh_gateway"` - Expose ExposeConfig `json:",omitempty"` - AccessLogs *AccessLogsConfig `json:",omitempty" alias:"access_logs"` - EnvoyExtensions []EnvoyExtension `json:",omitempty" alias:"envoy_extensions"` - FailoverPolicy *ServiceResolverFailoverPolicy `json:",omitempty" alias:"failover_policy"` - PrioritizeByLocality *ServiceResolverPrioritizeByLocality `json:",omitempty" alias:"prioritize_by_locality"` - - Meta map[string]string `json:",omitempty"` - CreateIndex uint64 - ModifyIndex uint64 -} - -func (p *ProxyConfigEntry) GetKind() string { return p.Kind } -func (p *ProxyConfigEntry) GetName() string { return ProxyConfigGlobal } -func (p *ProxyConfigEntry) GetPartition() string { return p.Partition } -func (p *ProxyConfigEntry) GetNamespace() string { return p.Namespace } -func (p *ProxyConfigEntry) GetMeta() map[string]string { return p.Meta } -func (p *ProxyConfigEntry) GetCreateIndex() uint64 { return p.CreateIndex } -func (p *ProxyConfigEntry) GetModifyIndex() uint64 { return p.ModifyIndex } - -func makeConfigEntry(kind, name string) (ConfigEntry, error) { - switch kind { - case ServiceDefaults: - return &ServiceConfigEntry{Kind: kind, Name: name}, nil - case ProxyDefaults: - return &ProxyConfigEntry{Kind: kind, Name: name}, nil - case ServiceRouter: - return &ServiceRouterConfigEntry{Kind: kind, Name: name}, nil - case ServiceSplitter: - return &ServiceSplitterConfigEntry{Kind: kind, Name: name}, nil - case ServiceResolver: - return &ServiceResolverConfigEntry{Kind: kind, Name: name}, nil - case IngressGateway: - return &IngressGatewayConfigEntry{Kind: kind, Name: name}, nil - case TerminatingGateway: - return &TerminatingGatewayConfigEntry{Kind: kind, Name: name}, nil - case ServiceIntentions: - return &ServiceIntentionsConfigEntry{Kind: kind, Name: name}, nil - case MeshConfig: - return &MeshConfigEntry{}, nil - case ExportedServices: - return &ExportedServicesConfigEntry{Name: name}, nil - case SamenessGroup: - return &SamenessGroupConfigEntry{Kind: kind, Name: name}, nil - case APIGateway: - return &APIGatewayConfigEntry{Kind: kind, Name: name}, nil - case TCPRoute: - return &TCPRouteConfigEntry{Kind: kind, Name: name}, nil - case FileSystemCertificate: - return &FileSystemCertificateConfigEntry{Kind: kind, Name: name}, nil - case InlineCertificate: - return &InlineCertificateConfigEntry{Kind: kind, Name: name}, nil - case HTTPRoute: - return &HTTPRouteConfigEntry{Kind: kind, Name: name}, nil - case RateLimitIPConfig: - return &RateLimitIPConfigEntry{Kind: kind, Name: name}, nil - case JWTProvider: - return &JWTProviderConfigEntry{Kind: kind, Name: name}, nil - default: - return nil, fmt.Errorf("invalid config entry kind: %s", kind) - } -} - -func MakeConfigEntry(kind, name string) (ConfigEntry, error) { - return makeConfigEntry(kind, name) -} - -// DecodeConfigEntry will decode the result of using json.Unmarshal of a config -// entry into a map[string]interface{}. -// -// Important caveats: -// -// - This will NOT work if the map[string]interface{} was produced using HCL -// decoding as that requires more extensive parsing to work around the issues -// with map[string][]interface{} that arise. -// -// - This will only decode fields using their camel case json field -// representations. -func DecodeConfigEntry(raw map[string]interface{}) (ConfigEntry, error) { - var entry ConfigEntry - - kindVal, ok := raw["Kind"] - if !ok { - kindVal, ok = raw["kind"] - } - if !ok { - return nil, fmt.Errorf("Payload does not contain a kind/Kind key at the top level") - } - - if kindStr, ok := kindVal.(string); ok { - newEntry, err := makeConfigEntry(kindStr, "") - if err != nil { - return nil, err - } - entry = newEntry - } else { - return nil, fmt.Errorf("Kind value in payload is not a string") - } - - decodeConf := &mapstructure.DecoderConfig{ - DecodeHook: mapstructure.ComposeDecodeHookFunc( - mapstructure.StringToTimeDurationHookFunc(), - mapstructure.StringToTimeHookFunc(time.RFC3339), - ), - Result: &entry, - WeaklyTypedInput: true, - } - - decoder, err := mapstructure.NewDecoder(decodeConf) - if err != nil { - return nil, err - } - - return entry, decoder.Decode(raw) -} - -func DecodeConfigEntryFromJSON(data []byte) (ConfigEntry, error) { - var raw map[string]interface{} - if err := json.Unmarshal(data, &raw); err != nil { - return nil, err - } - - return DecodeConfigEntry(raw) -} - -func decodeConfigEntrySlice(raw []map[string]interface{}) ([]ConfigEntry, error) { - var entries []ConfigEntry - for _, rawEntry := range raw { - entry, err := DecodeConfigEntry(rawEntry) - if err != nil { - return nil, err - } - entries = append(entries, entry) - } - return entries, nil -} - -// ConfigEntries can be used to query the Config endpoints -type ConfigEntries struct { - c *Client -} - -// Config returns a handle to the Config endpoints -func (c *Client) ConfigEntries() *ConfigEntries { - return &ConfigEntries{c} -} - -func (conf *ConfigEntries) Get(kind string, name string, q *QueryOptions) (ConfigEntry, *QueryMeta, error) { - if kind == "" || name == "" { - return nil, nil, fmt.Errorf("Both kind and name parameters must not be empty") - } - - entry, err := makeConfigEntry(kind, name) - if err != nil { - return nil, nil, err - } - - r := conf.c.newRequest("GET", fmt.Sprintf("/v1/config/%s/%s", kind, name)) - r.setQueryOptions(q) - rtt, resp, err := conf.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if err := decodeBody(resp, entry); err != nil { - return nil, nil, err - } - - return entry, qm, nil -} - -func (conf *ConfigEntries) List(kind string, q *QueryOptions) ([]ConfigEntry, *QueryMeta, error) { - if kind == "" { - return nil, nil, fmt.Errorf("The kind parameter must not be empty") - } - - r := conf.c.newRequest("GET", fmt.Sprintf("/v1/config/%s", kind)) - r.setQueryOptions(q) - rtt, resp, err := conf.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var raw []map[string]interface{} - if err := decodeBody(resp, &raw); err != nil { - return nil, nil, err - } - - entries, err := decodeConfigEntrySlice(raw) - if err != nil { - return nil, nil, err - } - - return entries, qm, nil -} - -func (conf *ConfigEntries) Set(entry ConfigEntry, w *WriteOptions) (bool, *WriteMeta, error) { - return conf.set(entry, nil, w) -} - -func (conf *ConfigEntries) CAS(entry ConfigEntry, index uint64, w *WriteOptions) (bool, *WriteMeta, error) { - return conf.set(entry, map[string]string{"cas": strconv.FormatUint(index, 10)}, w) -} - -func (conf *ConfigEntries) set(entry ConfigEntry, params map[string]string, w *WriteOptions) (bool, *WriteMeta, error) { - r := conf.c.newRequest("PUT", "/v1/config") - r.setWriteOptions(w) - for param, value := range params { - r.params.Set(param, value) - } - r.obj = entry - rtt, resp, err := conf.c.doRequest(r) - if err != nil { - return false, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return false, nil, err - } - - var buf bytes.Buffer - if _, err := io.Copy(&buf, resp.Body); err != nil { - return false, nil, fmt.Errorf("Failed to read response: %v", err) - } - res := strings.Contains(buf.String(), "true") - - wm := &WriteMeta{RequestTime: rtt} - return res, wm, nil -} - -func (conf *ConfigEntries) Delete(kind string, name string, w *WriteOptions) (*WriteMeta, error) { - _, wm, err := conf.delete(kind, name, nil, w) - return wm, err -} - -// DeleteCAS performs a Check-And-Set deletion of the given config entry, and -// returns true if it was successful. If the provided index no longer matches -// the entry's ModifyIndex (i.e. it was modified by another process) then the -// operation will fail and return false. -func (conf *ConfigEntries) DeleteCAS(kind, name string, index uint64, w *WriteOptions) (bool, *WriteMeta, error) { - return conf.delete(kind, name, map[string]string{"cas": strconv.FormatUint(index, 10)}, w) -} - -func (conf *ConfigEntries) delete(kind, name string, params map[string]string, w *WriteOptions) (bool, *WriteMeta, error) { - if kind == "" || name == "" { - return false, nil, fmt.Errorf("Both kind and name parameters must not be empty") - } - - r := conf.c.newRequest("DELETE", fmt.Sprintf("/v1/config/%s/%s", kind, name)) - r.setWriteOptions(w) - for param, value := range params { - r.params.Set(param, value) - } - - rtt, resp, err := conf.c.doRequest(r) - if err != nil { - return false, nil, err - } - defer closeResponseBody(resp) - - if err := requireOK(resp); err != nil { - return false, nil, err - } - - var buf bytes.Buffer - if _, err := io.Copy(&buf, resp.Body); err != nil { - return false, nil, fmt.Errorf("Failed to read response: %v", err) - } - - res := strings.Contains(buf.String(), "true") - wm := &WriteMeta{RequestTime: rtt} - return res, wm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_discoverychain.go b/vendor/github.com/hashicorp/consul/api/config_entry_discoverychain.go deleted file mode 100644 index 572d9d2d5e46a..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/config_entry_discoverychain.go +++ /dev/null @@ -1,385 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "encoding/json" - "time" - - "github.com/hashicorp/go-multierror" -) - -type ServiceRouterConfigEntry struct { - Kind string - Name string - Partition string `json:",omitempty"` - Namespace string `json:",omitempty"` - - Routes []ServiceRoute `json:",omitempty"` - - Meta map[string]string `json:",omitempty"` - CreateIndex uint64 - ModifyIndex uint64 -} - -func (e *ServiceRouterConfigEntry) GetKind() string { return e.Kind } -func (e *ServiceRouterConfigEntry) GetName() string { return e.Name } -func (e *ServiceRouterConfigEntry) GetPartition() string { return e.Partition } -func (e *ServiceRouterConfigEntry) GetNamespace() string { return e.Namespace } -func (e *ServiceRouterConfigEntry) GetMeta() map[string]string { return e.Meta } -func (e *ServiceRouterConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex } -func (e *ServiceRouterConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex } - -type ServiceRoute struct { - Match *ServiceRouteMatch `json:",omitempty"` - Destination *ServiceRouteDestination `json:",omitempty"` -} - -type ServiceRouteMatch struct { - HTTP *ServiceRouteHTTPMatch `json:",omitempty"` -} - -type ServiceRouteHTTPMatch struct { - PathExact string `json:",omitempty" alias:"path_exact"` - PathPrefix string `json:",omitempty" alias:"path_prefix"` - PathRegex string `json:",omitempty" alias:"path_regex"` - CaseInsensitive bool `json:",omitempty" alias:"case_insensitive"` - - Header []ServiceRouteHTTPMatchHeader `json:",omitempty"` - QueryParam []ServiceRouteHTTPMatchQueryParam `json:",omitempty" alias:"query_param"` - Methods []string `json:",omitempty"` -} - -type ServiceRouteHTTPMatchHeader struct { - Name string - Present bool `json:",omitempty"` - Exact string `json:",omitempty"` - Prefix string `json:",omitempty"` - Suffix string `json:",omitempty"` - Regex string `json:",omitempty"` - Invert bool `json:",omitempty"` -} - -type ServiceRouteHTTPMatchQueryParam struct { - Name string - Present bool `json:",omitempty"` - Exact string `json:",omitempty"` - Regex string `json:",omitempty"` -} - -type ServiceRouteDestination struct { - Service string `json:",omitempty"` - ServiceSubset string `json:",omitempty" alias:"service_subset"` - Namespace string `json:",omitempty"` - Partition string `json:",omitempty"` - PrefixRewrite string `json:",omitempty" alias:"prefix_rewrite"` - RequestTimeout time.Duration `json:",omitempty" alias:"request_timeout"` - IdleTimeout time.Duration `json:",omitempty" alias:"idle_timeout"` - NumRetries uint32 `json:",omitempty" alias:"num_retries"` - RetryOnConnectFailure bool `json:",omitempty" alias:"retry_on_connect_failure"` - RetryOnStatusCodes []uint32 `json:",omitempty" alias:"retry_on_status_codes"` - RetryOn []string `json:",omitempty" alias:"retry_on"` - RequestHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"request_headers"` - ResponseHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"response_headers"` -} - -func (e *ServiceRouteDestination) MarshalJSON() ([]byte, error) { - type Alias ServiceRouteDestination - exported := &struct { - RequestTimeout string `json:",omitempty"` - IdleTimeout string `json:",omitempty"` - *Alias - }{ - RequestTimeout: e.RequestTimeout.String(), - IdleTimeout: e.IdleTimeout.String(), - Alias: (*Alias)(e), - } - if e.RequestTimeout == 0 { - exported.RequestTimeout = "" - } - if e.IdleTimeout == 0 { - exported.IdleTimeout = "" - } - - return json.Marshal(exported) -} - -func (e *ServiceRouteDestination) UnmarshalJSON(data []byte) error { - type Alias ServiceRouteDestination - aux := &struct { - RequestTimeout string - IdleTimeout string - *Alias - }{ - Alias: (*Alias)(e), - } - if err := json.Unmarshal(data, &aux); err != nil { - return err - } - var err error - if aux.RequestTimeout != "" { - if e.RequestTimeout, err = time.ParseDuration(aux.RequestTimeout); err != nil { - return err - } - } - if aux.IdleTimeout != "" { - if e.IdleTimeout, err = time.ParseDuration(aux.IdleTimeout); err != nil { - return err - } - } - return nil -} - -type ServiceSplitterConfigEntry struct { - Kind string - Name string - Partition string `json:",omitempty"` - Namespace string `json:",omitempty"` - - Splits []ServiceSplit `json:",omitempty"` - - Meta map[string]string `json:",omitempty"` - CreateIndex uint64 - ModifyIndex uint64 -} - -func (e *ServiceSplitterConfigEntry) GetKind() string { return e.Kind } -func (e *ServiceSplitterConfigEntry) GetName() string { return e.Name } -func (e *ServiceSplitterConfigEntry) GetPartition() string { return e.Partition } -func (e *ServiceSplitterConfigEntry) GetNamespace() string { return e.Namespace } -func (e *ServiceSplitterConfigEntry) GetMeta() map[string]string { return e.Meta } -func (e *ServiceSplitterConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex } -func (e *ServiceSplitterConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex } - -type ServiceSplit struct { - Weight float32 - Service string `json:",omitempty"` - ServiceSubset string `json:",omitempty" alias:"service_subset"` - Namespace string `json:",omitempty"` - Partition string `json:",omitempty"` - RequestHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"request_headers"` - ResponseHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"response_headers"` -} - -type ServiceResolverConfigEntry struct { - Kind string - Name string - Partition string `json:",omitempty"` - Namespace string `json:",omitempty"` - - DefaultSubset string `json:",omitempty" alias:"default_subset"` - Subsets map[string]ServiceResolverSubset `json:",omitempty"` - Redirect *ServiceResolverRedirect `json:",omitempty"` - Failover map[string]ServiceResolverFailover `json:",omitempty"` - ConnectTimeout time.Duration `json:",omitempty" alias:"connect_timeout"` - RequestTimeout time.Duration `json:",omitempty" alias:"request_timeout"` - - // PrioritizeByLocality controls whether the locality of services within the - // local partition will be used to prioritize connectivity. - PrioritizeByLocality *ServiceResolverPrioritizeByLocality `json:",omitempty" alias:"prioritize_by_locality"` - - // LoadBalancer determines the load balancing policy and configuration for services - // issuing requests to this upstream service. - LoadBalancer *LoadBalancer `json:",omitempty" alias:"load_balancer"` - - Meta map[string]string `json:",omitempty"` - CreateIndex uint64 - ModifyIndex uint64 -} - -func (e *ServiceResolverConfigEntry) MarshalJSON() ([]byte, error) { - type Alias ServiceResolverConfigEntry - exported := &struct { - ConnectTimeout string `json:",omitempty"` - RequestTimeout string `json:",omitempty"` - *Alias - }{ - ConnectTimeout: e.ConnectTimeout.String(), - RequestTimeout: e.RequestTimeout.String(), - Alias: (*Alias)(e), - } - if e.ConnectTimeout == 0 { - exported.ConnectTimeout = "" - } - if e.RequestTimeout == 0 { - exported.RequestTimeout = "" - } - - return json.Marshal(exported) -} - -func (e *ServiceResolverConfigEntry) UnmarshalJSON(data []byte) error { - type Alias ServiceResolverConfigEntry - aux := &struct { - ConnectTimeout string - RequestTimeout string - *Alias - }{ - Alias: (*Alias)(e), - } - var err error - if err = json.Unmarshal(data, &aux); err != nil { - return err - } - var merr *multierror.Error - if aux.ConnectTimeout != "" { - if e.ConnectTimeout, err = time.ParseDuration(aux.ConnectTimeout); err != nil { - merr = multierror.Append(merr, err) - } - } - if aux.RequestTimeout != "" { - if e.RequestTimeout, err = time.ParseDuration(aux.RequestTimeout); err != nil { - merr = multierror.Append(merr, err) - } - } - return merr.ErrorOrNil() -} - -func (e *ServiceResolverConfigEntry) GetKind() string { return e.Kind } -func (e *ServiceResolverConfigEntry) GetName() string { return e.Name } -func (e *ServiceResolverConfigEntry) GetPartition() string { return e.Partition } -func (e *ServiceResolverConfigEntry) GetNamespace() string { return e.Namespace } -func (e *ServiceResolverConfigEntry) GetMeta() map[string]string { return e.Meta } -func (e *ServiceResolverConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex } -func (e *ServiceResolverConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex } - -type ServiceResolverSubset struct { - Filter string `json:",omitempty"` - OnlyPassing bool `json:",omitempty" alias:"only_passing"` -} - -type ServiceResolverRedirect struct { - Service string `json:",omitempty"` - ServiceSubset string `json:",omitempty" alias:"service_subset"` - Namespace string `json:",omitempty"` - Partition string `json:",omitempty"` - Datacenter string `json:",omitempty"` - Peer string `json:",omitempty"` - SamenessGroup string `json:",omitempty" alias:"sameness_group"` -} - -type ServiceResolverFailover struct { - Service string `json:",omitempty"` - ServiceSubset string `json:",omitempty" alias:"service_subset"` - // Referencing other partitions is not supported. - Namespace string `json:",omitempty"` - Datacenters []string `json:",omitempty"` - Targets []ServiceResolverFailoverTarget `json:",omitempty"` - Policy *ServiceResolverFailoverPolicy `json:",omitempty"` - SamenessGroup string `json:",omitempty" alias:"sameness_group"` -} - -type ServiceResolverFailoverTarget struct { - Service string `json:",omitempty"` - ServiceSubset string `json:",omitempty" alias:"service_subset"` - Partition string `json:",omitempty"` - Namespace string `json:",omitempty"` - Datacenter string `json:",omitempty"` - Peer string `json:",omitempty"` -} - -type ServiceResolverFailoverPolicy struct { - // Mode specifies the type of failover that will be performed. Valid values are - // "sequential", "" (equivalent to "sequential") and "order-by-locality". - Mode string `json:",omitempty"` - Regions []string `json:",omitempty"` -} - -type ServiceResolverPrioritizeByLocality struct { - // Mode specifies the type of prioritization that will be performed - // when selecting nodes in the local partition. - // Valid values are: "" (default "none"), "none", and "failover". - Mode string `json:",omitempty"` -} - -// LoadBalancer determines the load balancing policy and configuration for services -// issuing requests to this upstream service. -type LoadBalancer struct { - // Policy is the load balancing policy used to select a host - Policy string `json:",omitempty"` - - // RingHashConfig contains configuration for the "ring_hash" policy type - RingHashConfig *RingHashConfig `json:",omitempty" alias:"ring_hash_config"` - - // LeastRequestConfig contains configuration for the "least_request" policy type - LeastRequestConfig *LeastRequestConfig `json:",omitempty" alias:"least_request_config"` - - // HashPolicies is a list of hash policies to use for hashing load balancing algorithms. - // Hash policies are evaluated individually and combined such that identical lists - // result in the same hash. - // If no hash policies are present, or none are successfully evaluated, - // then a random backend host will be selected. - HashPolicies []HashPolicy `json:",omitempty" alias:"hash_policies"` -} - -// RingHashConfig contains configuration for the "ring_hash" policy type -type RingHashConfig struct { - // MinimumRingSize determines the minimum number of entries in the hash ring - MinimumRingSize uint64 `json:",omitempty" alias:"minimum_ring_size"` - - // MaximumRingSize determines the maximum number of entries in the hash ring - MaximumRingSize uint64 `json:",omitempty" alias:"maximum_ring_size"` -} - -// LeastRequestConfig contains configuration for the "least_request" policy type -type LeastRequestConfig struct { - // ChoiceCount determines the number of random healthy hosts from which to select the one with the least requests. - ChoiceCount uint32 `json:",omitempty" alias:"choice_count"` -} - -// HashPolicy defines which attributes will be hashed by hash-based LB algorithms -type HashPolicy struct { - // Field is the attribute type to hash on. - // Must be one of "header","cookie", or "query_parameter". - // Cannot be specified along with SourceIP. - Field string `json:",omitempty"` - - // FieldValue is the value to hash. - // ie. header name, cookie name, URL query parameter name - // Cannot be specified along with SourceIP. - FieldValue string `json:",omitempty" alias:"field_value"` - - // CookieConfig contains configuration for the "cookie" hash policy type. - CookieConfig *CookieConfig `json:",omitempty" alias:"cookie_config"` - - // SourceIP determines whether the hash should be of the source IP rather than of a field and field value. - // Cannot be specified along with Field or FieldValue. - SourceIP bool `json:",omitempty" alias:"source_ip"` - - // Terminal will short circuit the computation of the hash when multiple hash policies are present. - // If a hash is computed when a Terminal policy is evaluated, - // then that hash will be used and subsequent hash policies will be ignored. - Terminal bool `json:",omitempty"` -} - -// CookieConfig contains configuration for the "cookie" hash policy type. -// This is specified to have Envoy generate a cookie for a client on its first request. -type CookieConfig struct { - // Generates a session cookie with no expiration. - Session bool `json:",omitempty"` - - // TTL for generated cookies. Cannot be specified for session cookies. - TTL time.Duration `json:",omitempty"` - - // The path to set for the cookie - Path string `json:",omitempty"` -} - -// HTTPHeaderModifiers is a set of rules for HTTP header modification that -// should be performed by proxies as the request passes through them. It can -// operate on either request or response headers depending on the context in -// which it is used. -type HTTPHeaderModifiers struct { - // Add is a set of name -> value pairs that should be appended to the request - // or response (i.e. allowing duplicates if the same header already exists). - Add map[string]string `json:",omitempty"` - - // Set is a set of name -> value pairs that should be added to the request or - // response, overwriting any existing header values of the same name. - Set map[string]string `json:",omitempty"` - - // Remove is the set of header names that should be stripped from the request - // or response. - Remove []string `json:",omitempty"` -} diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_exports.go b/vendor/github.com/hashicorp/consul/api/config_entry_exports.go deleted file mode 100644 index b8e9830e652da..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/config_entry_exports.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "encoding/json" -) - -// ExportedServicesConfigEntry manages the exported services for a single admin partition. -// Admin Partitions are a Consul Enterprise feature. -type ExportedServicesConfigEntry struct { - // Name is the name of the partition the ExportedServicesConfigEntry applies to. - // Partitioning is a Consul Enterprise feature. - Name string `json:",omitempty"` - - // Partition is the partition where the ExportedServicesConfigEntry is stored. - // If the partition does not match the name, the name will overwrite the partition. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // Services is a list of services to be exported and the list of partitions - // to expose them to. - Services []ExportedService `json:",omitempty"` - - Meta map[string]string `json:",omitempty"` - - // CreateIndex is the Raft index this entry was created at. This is a - // read-only field. - CreateIndex uint64 - - // ModifyIndex is used for the Check-And-Set operations and can also be fed - // back into the WaitIndex of the QueryOptions in order to perform blocking - // queries. - ModifyIndex uint64 -} - -// ExportedService manages the exporting of a service in the local partition to -// other partitions. -type ExportedService struct { - // Name is the name of the service to be exported. - Name string - - // Namespace is the namespace to export the service from. - Namespace string `json:",omitempty"` - - // Consumers is a list of downstream consumers of the service to be exported. - Consumers []ServiceConsumer `json:",omitempty"` -} - -// ServiceConsumer represents a downstream consumer of the service to be exported. -// At most one of Partition or Peer must be specified. -type ServiceConsumer struct { - // Partition is the admin partition to export the service to. - Partition string `json:",omitempty"` - - // Peer is the name of the peer to export the service to. - Peer string `json:",omitempty" alias:"peer_name"` - - // SamenessGroup is the name of the sameness group to export the service to. - SamenessGroup string `json:",omitempty" alias:"sameness_group"` -} - -func (e *ExportedServicesConfigEntry) GetKind() string { return ExportedServices } -func (e *ExportedServicesConfigEntry) GetName() string { return e.Name } -func (e *ExportedServicesConfigEntry) GetPartition() string { return e.Name } -func (e *ExportedServicesConfigEntry) GetNamespace() string { return "" } -func (e *ExportedServicesConfigEntry) GetMeta() map[string]string { return e.Meta } -func (e *ExportedServicesConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex } -func (e *ExportedServicesConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex } - -// MarshalJSON adds the Kind field so that the JSON can be decoded back into the -// correct type. -func (e *ExportedServicesConfigEntry) MarshalJSON() ([]byte, error) { - type Alias ExportedServicesConfigEntry - source := &struct { - Kind string - *Alias - }{ - Kind: ExportedServices, - Alias: (*Alias)(e), - } - return json.Marshal(source) -} diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_file_system_certificate.go b/vendor/github.com/hashicorp/consul/api/config_entry_file_system_certificate.go deleted file mode 100644 index 3a0f319acd065..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/config_entry_file_system_certificate.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -type FileSystemCertificateConfigEntry struct { - // Kind of the config entry. This should be set to api.FileSystemCertificate. - Kind string - - Name string - - // Certificate is the path to a client certificate to use for TLS connections. - Certificate string `json:",omitempty" alias:"certificate"` - - // PrivateKey is the path to a private key to use for TLS connections. - PrivateKey string `json:",omitempty" alias:"private_key"` - - Meta map[string]string `json:",omitempty"` - - // CreateIndex is the Raft index this entry was created at. This is a - // read-only field. - CreateIndex uint64 - - // ModifyIndex is used for the Check-And-Set operations and can also be fed - // back into the WaitIndex of the QueryOptions in order to perform blocking - // queries. - ModifyIndex uint64 - - // Partition is the partition the config entry is associated with. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // Namespace is the namespace the config entry is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` -} - -func (a *FileSystemCertificateConfigEntry) GetKind() string { return FileSystemCertificate } -func (a *FileSystemCertificateConfigEntry) GetName() string { return a.Name } -func (a *FileSystemCertificateConfigEntry) GetPartition() string { return a.Partition } -func (a *FileSystemCertificateConfigEntry) GetNamespace() string { return a.Namespace } -func (a *FileSystemCertificateConfigEntry) GetMeta() map[string]string { return a.Meta } -func (a *FileSystemCertificateConfigEntry) GetCreateIndex() uint64 { return a.CreateIndex } -func (a *FileSystemCertificateConfigEntry) GetModifyIndex() uint64 { return a.ModifyIndex } diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_gateways.go b/vendor/github.com/hashicorp/consul/api/config_entry_gateways.go deleted file mode 100644 index ba2bac19efe7c..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/config_entry_gateways.go +++ /dev/null @@ -1,347 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -// IngressGatewayConfigEntry manages the configuration for an ingress service -// with the given name. -type IngressGatewayConfigEntry struct { - // Kind of the config entry. This should be set to api.IngressGateway. - Kind string - - // Name is used to match the config entry with its associated ingress gateway - // service. This should match the name provided in the service definition. - Name string - - // Partition is the partition the IngressGateway is associated with. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // Namespace is the namespace the IngressGateway is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` - - // TLS holds the TLS configuration for this gateway. - TLS GatewayTLSConfig - - // Listeners declares what ports the ingress gateway should listen on, and - // what services to associated to those ports. - Listeners []IngressListener - - Meta map[string]string `json:",omitempty"` - - // Defaults is default configuration for all upstream services - Defaults *IngressServiceConfig `json:",omitempty"` - - // CreateIndex is the Raft index this entry was created at. This is a - // read-only field. - CreateIndex uint64 - - // ModifyIndex is used for the Check-And-Set operations and can also be fed - // back into the WaitIndex of the QueryOptions in order to perform blocking - // queries. - ModifyIndex uint64 -} - -type IngressServiceConfig struct { - MaxConnections *uint32 - MaxPendingRequests *uint32 - MaxConcurrentRequests *uint32 - - // PassiveHealthCheck configuration determines how upstream proxy instances will - // be monitored for removal from the load balancing pool. - PassiveHealthCheck *PassiveHealthCheck `json:",omitempty" alias:"passive_health_check"` -} - -type GatewayTLSConfig struct { - // Indicates that TLS should be enabled for this gateway service. - Enabled bool - - // SDS allows configuring TLS certificate from an SDS service. - SDS *GatewayTLSSDSConfig `json:",omitempty"` - - TLSMinVersion string `json:",omitempty" alias:"tls_min_version"` - TLSMaxVersion string `json:",omitempty" alias:"tls_max_version"` - - // Define a subset of cipher suites to restrict - // Only applicable to connections negotiated via TLS 1.2 or earlier - CipherSuites []string `json:",omitempty" alias:"cipher_suites"` -} - -type GatewayServiceTLSConfig struct { - // SDS allows configuring TLS certificate from an SDS service. - SDS *GatewayTLSSDSConfig `json:",omitempty"` -} - -type GatewayTLSSDSConfig struct { - ClusterName string `json:",omitempty" alias:"cluster_name"` - CertResource string `json:",omitempty" alias:"cert_resource"` -} - -// IngressListener manages the configuration for a listener on a specific port. -type IngressListener struct { - // Port declares the port on which the ingress gateway should listen for traffic. - Port int - - // Protocol declares what type of traffic this listener is expected to - // receive. Depending on the protocol, a listener might support multiplexing - // services over a single port, or additional discovery chain features. The - // current supported values are: (tcp | http | http2 | grpc). - Protocol string - - // Services declares the set of services to which the listener forwards - // traffic. - // - // For "tcp" protocol listeners, only a single service is allowed. - // For "http" listeners, multiple services can be declared. - Services []IngressService - - // TLS allows specifying some TLS configuration per listener. - TLS *GatewayTLSConfig `json:",omitempty"` -} - -// IngressService manages configuration for services that are exposed to -// ingress traffic. -type IngressService struct { - // Name declares the service to which traffic should be forwarded. - // - // This can either be a specific service, or the wildcard specifier, - // "*". If the wildcard specifier is provided, the listener must be of "http" - // protocol and means that the listener will forward traffic to all services. - // - // A name can be specified on multiple listeners, and will be exposed on both - // of the listeners. - Name string - - // Hosts is a list of hostnames which should be associated to this service on - // the defined listener. Only allowed on layer 7 protocols, this will be used - // to route traffic to the service by matching the Host header of the HTTP - // request. - // - // If a host is provided for a service that also has a wildcard specifier - // defined, the host will override the wildcard-specifier-provided - // ".*" domain for that listener. - // - // This cannot be specified when using the wildcard specifier, "*", or when - // using a "tcp" listener. - Hosts []string - - // Namespace is the namespace where the service is located. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` - - // Partition is the partition where the service is located. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // TLS allows specifying some TLS configuration per listener. - TLS *GatewayServiceTLSConfig `json:",omitempty"` - - // Allow HTTP header manipulation to be configured. - RequestHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"request_headers"` - ResponseHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"response_headers"` - - MaxConnections *uint32 `json:",omitempty" alias:"max_connections"` - MaxPendingRequests *uint32 `json:",omitempty" alias:"max_pending_requests"` - MaxConcurrentRequests *uint32 `json:",omitempty" alias:"max_concurrent_requests"` - - // PassiveHealthCheck configuration determines how upstream proxy instances will - // be monitored for removal from the load balancing pool. - PassiveHealthCheck *PassiveHealthCheck `json:",omitempty" alias:"passive_health_check"` -} - -func (i *IngressGatewayConfigEntry) GetKind() string { return i.Kind } -func (i *IngressGatewayConfigEntry) GetName() string { return i.Name } -func (i *IngressGatewayConfigEntry) GetPartition() string { return i.Partition } -func (i *IngressGatewayConfigEntry) GetNamespace() string { return i.Namespace } -func (i *IngressGatewayConfigEntry) GetMeta() map[string]string { return i.Meta } -func (i *IngressGatewayConfigEntry) GetCreateIndex() uint64 { return i.CreateIndex } -func (i *IngressGatewayConfigEntry) GetModifyIndex() uint64 { return i.ModifyIndex } - -// TerminatingGatewayConfigEntry manages the configuration for a terminating gateway -// with the given name. -type TerminatingGatewayConfigEntry struct { - // Kind of the config entry. This should be set to api.TerminatingGateway. - Kind string - - // Name is used to match the config entry with its associated terminating gateway - // service. This should match the name provided in the service definition. - Name string - - // Services is a list of service names represented by the terminating gateway. - Services []LinkedService `json:",omitempty"` - - Meta map[string]string `json:",omitempty"` - - // CreateIndex is the Raft index this entry was created at. This is a - // read-only field. - CreateIndex uint64 - - // ModifyIndex is used for the Check-And-Set operations and can also be fed - // back into the WaitIndex of the QueryOptions in order to perform blocking - // queries. - ModifyIndex uint64 - - // Partition is the partition the config entry is associated with. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // Namespace is the namespace the config entry is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` -} - -// A LinkedService is a service represented by a terminating gateway -type LinkedService struct { - // Referencing other partitions is not supported. - - //DisableAutoHostRewrite disables terminating gateways auto host rewrite feature when set to true. - DisableAutoHostRewrite bool `json:",omitempty"` - - // Namespace is where the service is registered. - Namespace string `json:",omitempty"` - - // Name is the name of the service, as defined in Consul's catalog. - Name string `json:",omitempty"` - - // CAFile is the optional path to a CA certificate to use for TLS connections - // from the gateway to the linked service. - CAFile string `json:",omitempty" alias:"ca_file"` - - // CertFile is the optional path to a client certificate to use for TLS connections - // from the gateway to the linked service. - CertFile string `json:",omitempty" alias:"cert_file"` - - // KeyFile is the optional path to a private key to use for TLS connections - // from the gateway to the linked service. - KeyFile string `json:",omitempty" alias:"key_file"` - - // SNI is the optional name to specify during the TLS handshake with a linked service. - SNI string `json:",omitempty"` -} - -func (g *TerminatingGatewayConfigEntry) GetKind() string { return g.Kind } -func (g *TerminatingGatewayConfigEntry) GetName() string { return g.Name } -func (g *TerminatingGatewayConfigEntry) GetPartition() string { return g.Partition } -func (g *TerminatingGatewayConfigEntry) GetNamespace() string { return g.Namespace } -func (g *TerminatingGatewayConfigEntry) GetMeta() map[string]string { return g.Meta } -func (g *TerminatingGatewayConfigEntry) GetCreateIndex() uint64 { return g.CreateIndex } -func (g *TerminatingGatewayConfigEntry) GetModifyIndex() uint64 { return g.ModifyIndex } - -// APIGatewayConfigEntry manages the configuration for an API gateway -// with the given name. -type APIGatewayConfigEntry struct { - // Kind of the config entry. This should be set to api.APIGateway. - Kind string - - // Name is used to match the config entry with its associated api gateway - // service. This should match the name provided in the service definition. - Name string - - Meta map[string]string `json:",omitempty"` - - // Listeners is the set of listener configuration to which an API Gateway - // might bind. - Listeners []APIGatewayListener - // Status is the asynchronous status which an APIGateway propagates to the user. - Status ConfigEntryStatus - - // CreateIndex is the Raft index this entry was created at. This is a - // read-only field. - CreateIndex uint64 - - // ModifyIndex is used for the Check-And-Set operations and can also be fed - // back into the WaitIndex of the QueryOptions in order to perform blocking - // queries. - ModifyIndex uint64 - - // Partition is the partition the config entry is associated with. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // Namespace is the namespace the config entry is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` -} - -func (g *APIGatewayConfigEntry) GetKind() string { return g.Kind } -func (g *APIGatewayConfigEntry) GetName() string { return g.Name } -func (g *APIGatewayConfigEntry) GetPartition() string { return g.Partition } -func (g *APIGatewayConfigEntry) GetNamespace() string { return g.Namespace } -func (g *APIGatewayConfigEntry) GetMeta() map[string]string { return g.Meta } -func (g *APIGatewayConfigEntry) GetCreateIndex() uint64 { return g.CreateIndex } -func (g *APIGatewayConfigEntry) GetModifyIndex() uint64 { return g.ModifyIndex } - -// APIGatewayListener represents an individual listener for an APIGateway -type APIGatewayListener struct { - // Name is the name of the listener in a given gateway. This must be - // unique within a gateway. - Name string - // Hostname is the host name that a listener should be bound to, if - // unspecified, the listener accepts requests for all hostnames. - Hostname string - // Port is the port at which this listener should bind. - Port int - // Protocol is the protocol that a listener should use, it must - // either be "http" or "tcp" - Protocol string - // TLS is the TLS settings for the listener. - TLS APIGatewayTLSConfiguration - // Override is the policy that overrides all other policy and route specific configuration - Override *APIGatewayPolicy `json:",omitempty"` - // Default is the policy that is the default for the listener and route, routes can override this behavior - Default *APIGatewayPolicy `json:",omitempty"` -} - -// APIGatewayTLSConfiguration specifies the configuration of a listener’s -// TLS settings. -type APIGatewayTLSConfiguration struct { - // Certificates is a set of references to certificates - // that a gateway listener uses for TLS termination. - Certificates []ResourceReference - // MaxVersion is the maximum TLS version that the listener - // should support. - MaxVersion string `json:",omitempty" alias:"tls_max_version"` - // MinVersion is the minimum TLS version that the listener - // should support. - MinVersion string `json:",omitempty" alias:"tls_min_version"` - // Define a subset of cipher suites to restrict - // Only applicable to connections negotiated via TLS 1.2 or earlier - CipherSuites []string `json:",omitempty" alias:"cipher_suites"` -} - -// APIGatewayPolicy holds the policy that configures the gateway listener, this is used in the `Override` and `Default` fields of a listener -type APIGatewayPolicy struct { - // JWT holds the JWT configuration for the Listener - JWT *APIGatewayJWTRequirement `json:",omitempty"` -} - -// APIGatewayJWTRequirement holds the list of JWT providers to be verified against -type APIGatewayJWTRequirement struct { - // Providers is a list of providers to consider when verifying a JWT. - Providers []*APIGatewayJWTProvider `json:",omitempty"` -} - -// APIGatewayJWTProvider holds the provider and claim verification information -type APIGatewayJWTProvider struct { - // Name is the name of the JWT provider. There MUST be a corresponding - // "jwt-provider" config entry with this name. - Name string `json:",omitempty"` - - // VerifyClaims is a list of additional claims to verify in a JWT's payload. - VerifyClaims []*APIGatewayJWTClaimVerification `json:",omitempty" alias:"verify_claims"` -} - -// APIGatewayJWTClaimVerification holds the actual claim information to be verified -type APIGatewayJWTClaimVerification struct { - // Path is the path to the claim in the token JSON. - Path []string `json:",omitempty"` - - // Value is the expected value at the given path: - // - If the type at the path is a list then we verify - // that this value is contained in the list. - // - // - If the type at the path is a string then we verify - // that this value matches. - Value string `json:",omitempty"` -} diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_inline_certificate.go b/vendor/github.com/hashicorp/consul/api/config_entry_inline_certificate.go deleted file mode 100644 index 47a1ead05666a..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/config_entry_inline_certificate.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -// InlineCertificateConfigEntry -- TODO stub -type InlineCertificateConfigEntry struct { - // Kind of the config entry. This should be set to api.InlineCertificate. - Kind string - - // Name is used to match the config entry with its associated tcp-route - // service. This should match the name provided in the service definition. - Name string - - // Certificate is the public certificate component of an x509 key pair encoded in raw PEM format. - Certificate string - // PrivateKey is the private key component of an x509 key pair encoded in raw PEM format. - PrivateKey string `alias:"private_key"` - - Meta map[string]string `json:",omitempty"` - - // CreateIndex is the Raft index this entry was created at. This is a - // read-only field. - CreateIndex uint64 - - // ModifyIndex is used for the Check-And-Set operations and can also be fed - // back into the WaitIndex of the QueryOptions in order to perform blocking - // queries. - ModifyIndex uint64 - - // Partition is the partition the config entry is associated with. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // Namespace is the namespace the config entry is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` -} - -func (a *InlineCertificateConfigEntry) GetKind() string { return InlineCertificate } -func (a *InlineCertificateConfigEntry) GetName() string { return a.Name } -func (a *InlineCertificateConfigEntry) GetPartition() string { return a.Partition } -func (a *InlineCertificateConfigEntry) GetNamespace() string { return a.Namespace } -func (a *InlineCertificateConfigEntry) GetMeta() map[string]string { return a.Meta } -func (a *InlineCertificateConfigEntry) GetCreateIndex() uint64 { return a.CreateIndex } -func (a *InlineCertificateConfigEntry) GetModifyIndex() uint64 { return a.ModifyIndex } diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_intentions.go b/vendor/github.com/hashicorp/consul/api/config_entry_intentions.go deleted file mode 100644 index 3f03b0875b9c2..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/config_entry_intentions.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import "time" - -type ServiceIntentionsConfigEntry struct { - Kind string - Name string - Partition string `json:",omitempty"` - Namespace string `json:",omitempty"` - - Sources []*SourceIntention - JWT *IntentionJWTRequirement `json:",omitempty"` - - Meta map[string]string `json:",omitempty"` - - CreateIndex uint64 - ModifyIndex uint64 -} - -type SourceIntention struct { - Name string - Peer string `json:",omitempty"` - Partition string `json:",omitempty"` - Namespace string `json:",omitempty"` - SamenessGroup string `json:",omitempty" alias:"sameness_group"` - Action IntentionAction `json:",omitempty"` - Permissions []*IntentionPermission `json:",omitempty"` - Precedence int - Type IntentionSourceType - Description string `json:",omitempty"` - - LegacyID string `json:",omitempty" alias:"legacy_id"` - LegacyMeta map[string]string `json:",omitempty" alias:"legacy_meta"` - LegacyCreateTime *time.Time `json:",omitempty" alias:"legacy_create_time"` - LegacyUpdateTime *time.Time `json:",omitempty" alias:"legacy_update_time"` -} - -func (e *ServiceIntentionsConfigEntry) GetKind() string { return e.Kind } -func (e *ServiceIntentionsConfigEntry) GetName() string { return e.Name } -func (e *ServiceIntentionsConfigEntry) GetPartition() string { return e.Partition } -func (e *ServiceIntentionsConfigEntry) GetNamespace() string { return e.Namespace } -func (e *ServiceIntentionsConfigEntry) GetMeta() map[string]string { return e.Meta } -func (e *ServiceIntentionsConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex } -func (e *ServiceIntentionsConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex } - -type IntentionPermission struct { - Action IntentionAction - HTTP *IntentionHTTPPermission `json:",omitempty"` - JWT *IntentionJWTRequirement `json:",omitempty"` -} - -type IntentionHTTPPermission struct { - PathExact string `json:",omitempty" alias:"path_exact"` - PathPrefix string `json:",omitempty" alias:"path_prefix"` - PathRegex string `json:",omitempty" alias:"path_regex"` - - Header []IntentionHTTPHeaderPermission `json:",omitempty"` - - Methods []string `json:",omitempty"` -} - -type IntentionHTTPHeaderPermission struct { - Name string - Present bool `json:",omitempty"` - Exact string `json:",omitempty"` - Prefix string `json:",omitempty"` - Suffix string `json:",omitempty"` - Regex string `json:",omitempty"` - Invert bool `json:",omitempty"` -} - -type IntentionJWTRequirement struct { - // Providers is a list of providers to consider when verifying a JWT. - Providers []*IntentionJWTProvider `json:",omitempty"` -} - -type IntentionJWTProvider struct { - // Name is the name of the JWT provider. There MUST be a corresponding - // "jwt-provider" config entry with this name. - Name string `json:",omitempty"` - - // VerifyClaims is a list of additional claims to verify in a JWT's payload. - VerifyClaims []*IntentionJWTClaimVerification `json:",omitempty" alias:"verify_claims"` -} - -type IntentionJWTClaimVerification struct { - // Path is the path to the claim in the token JSON. - Path []string `json:",omitempty"` - - // Value is the expected value at the given path: - // - If the type at the path is a list then we verify - // that this value is contained in the list. - // - // - If the type at the path is a string then we verify - // that this value matches. - Value string `json:",omitempty"` -} diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_jwt_provider.go b/vendor/github.com/hashicorp/consul/api/config_entry_jwt_provider.go deleted file mode 100644 index 270f0d5641563..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/config_entry_jwt_provider.go +++ /dev/null @@ -1,310 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "time" -) - -const ( - DiscoveryTypeStrictDNS ClusterDiscoveryType = "STRICT_DNS" - DiscoveryTypeStatic ClusterDiscoveryType = "STATIC" - DiscoveryTypeLogicalDNS ClusterDiscoveryType = "LOGICAL_DNS" - DiscoveryTypeEDS ClusterDiscoveryType = "EDS" - DiscoveryTypeOriginalDST ClusterDiscoveryType = "ORIGINAL_DST" -) - -type JWTProviderConfigEntry struct { - // Kind is the kind of configuration entry and must be "jwt-provider". - Kind string `json:",omitempty"` - - // Name is the name of the provider being configured. - Name string `json:",omitempty"` - - // JSONWebKeySet defines a JSON Web Key Set, its location on disk, or the - // means with which to fetch a key set from a remote server. - JSONWebKeySet *JSONWebKeySet `json:",omitempty" alias:"json_web_key_set"` - - // Issuer is the entity that must have issued the JWT. - // This value must match the "iss" claim of the token. - Issuer string `json:",omitempty"` - - // Audiences is the set of audiences the JWT is allowed to access. - // If specified, all JWTs verified with this provider must address - // at least one of these to be considered valid. - Audiences []string `json:",omitempty"` - - // Locations where the JWT will be present in requests. - // Envoy will check all of these locations to extract a JWT. - // If no locations are specified Envoy will default to: - // 1. Authorization header with Bearer schema: - // "Authorization: Bearer " - // 2. access_token query parameter. - Locations []*JWTLocation `json:",omitempty"` - - // Forwarding defines rules for forwarding verified JWTs to the backend. - Forwarding *JWTForwardingConfig `json:",omitempty"` - - // ClockSkewSeconds specifies the maximum allowable time difference - // from clock skew when validating the "exp" (Expiration) and "nbf" - // (Not Before) claims. - // - // Default value is 30 seconds. - ClockSkewSeconds int `json:",omitempty" alias:"clock_skew_seconds"` - - // CacheConfig defines configuration for caching the validation - // result for previously seen JWTs. Caching results can speed up - // verification when individual tokens are expected to be handled - // multiple times. - CacheConfig *JWTCacheConfig `json:",omitempty" alias:"cache_config"` - - Meta map[string]string `json:",omitempty"` - - // CreateIndex is the Raft index this entry was created at. This is a - // read-only field. - CreateIndex uint64 `json:",omitempty"` - - // ModifyIndex is used for the Check-And-Set operations and can also be fed - // back into the WaitIndex of the QueryOptions in order to perform blocking - // queries. - ModifyIndex uint64 `json:",omitempty"` - - // Partition is the partition the JWTProviderConfigEntry applies to. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // Namespace is the namespace the JWTProviderConfigEntry applies to. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` -} - -// JWTLocation is a location where the JWT could be present in requests. -// -// Only one of Header, QueryParam, or Cookie can be specified. -type JWTLocation struct { - // Header defines how to extract a JWT from an HTTP request header. - Header *JWTLocationHeader `json:",omitempty"` - - // QueryParam defines how to extract a JWT from an HTTP request - // query parameter. - QueryParam *JWTLocationQueryParam `json:",omitempty" alias:"query_param"` - - // Cookie defines how to extract a JWT from an HTTP request cookie. - Cookie *JWTLocationCookie `json:",omitempty"` -} - -// JWTLocationHeader defines how to extract a JWT from an HTTP -// request header. -type JWTLocationHeader struct { - // Name is the name of the header containing the token. - Name string `json:",omitempty"` - - // ValuePrefix is an optional prefix that precedes the token in the - // header value. - // For example, "Bearer " is a standard value prefix for a header named - // "Authorization", but the prefix is not part of the token itself: - // "Authorization: Bearer " - ValuePrefix string `json:",omitempty" alias:"value_prefix"` - - // Forward defines whether the header with the JWT should be - // forwarded after the token has been verified. If false, the - // header will not be forwarded to the backend. - // - // Default value is false. - Forward bool `json:",omitempty"` -} - -// JWTLocationQueryParam defines how to extract a JWT from an HTTP request query parameter. -type JWTLocationQueryParam struct { - // Name is the name of the query param containing the token. - Name string `json:",omitempty"` -} - -// JWTLocationCookie defines how to extract a JWT from an HTTP request cookie. -type JWTLocationCookie struct { - // Name is the name of the cookie containing the token. - Name string `json:",omitempty"` -} - -type JWTForwardingConfig struct { - // HeaderName is a header name to use when forwarding a verified - // JWT to the backend. The verified JWT could have been extracted - // from any location (query param, header, or cookie). - // - // The header value will be base64-URL-encoded, and will not be - // padded unless PadForwardPayloadHeader is true. - HeaderName string `json:",omitempty" alias:"header_name"` - - // PadForwardPayloadHeader determines whether padding should be added - // to the base64 encoded token forwarded with ForwardPayloadHeader. - // - // Default value is false. - PadForwardPayloadHeader bool `json:",omitempty" alias:"pad_forward_payload_header"` -} - -// JSONWebKeySet defines a key set, its location on disk, or the -// means with which to fetch a key set from a remote server. -// -// Exactly one of Local or Remote must be specified. -type JSONWebKeySet struct { - // Local specifies a local source for the key set. - Local *LocalJWKS `json:",omitempty"` - - // Remote specifies how to fetch a key set from a remote server. - Remote *RemoteJWKS `json:",omitempty"` -} - -// LocalJWKS specifies a location for a local JWKS. -// -// Only one of String and Filename can be specified. -type LocalJWKS struct { - // JWKS contains a base64 encoded JWKS. - JWKS string `json:",omitempty"` - - // Filename configures a location on disk where the JWKS can be - // found. If specified, the file must be present on the disk of ALL - // proxies with intentions referencing this provider. - Filename string `json:",omitempty"` -} - -// RemoteJWKS specifies how to fetch a JWKS from a remote server. -type RemoteJWKS struct { - // URI is the URI of the server to query for the JWKS. - URI string `json:",omitempty"` - - // RequestTimeoutMs is the number of milliseconds to - // time out when making a request for the JWKS. - RequestTimeoutMs int `json:",omitempty" alias:"request_timeout_ms"` - - // CacheDuration is the duration after which cached keys - // should be expired. - // - // Default value is 5 minutes. - CacheDuration time.Duration `json:",omitempty" alias:"cache_duration"` - - // FetchAsynchronously indicates that the JWKS should be fetched - // when a client request arrives. Client requests will be paused - // until the JWKS is fetched. - // If false, the proxy listener will wait for the JWKS to be - // fetched before being activated. - // - // Default value is false. - FetchAsynchronously bool `json:",omitempty" alias:"fetch_asynchronously"` - - // RetryPolicy defines a retry policy for fetching JWKS. - // - // There is no retry by default. - RetryPolicy *JWKSRetryPolicy `json:",omitempty" alias:"retry_policy"` - - // JWKSCluster defines how the specified Remote JWKS URI is to be fetched. - JWKSCluster *JWKSCluster `json:",omitempty" alias:"jwks_cluster"` -} - -type JWKSCluster struct { - // DiscoveryType refers to the service discovery type to use for resolving the cluster. - // - // This defaults to STRICT_DNS. - // Other options include STATIC, LOGICAL_DNS, EDS or ORIGINAL_DST. - DiscoveryType ClusterDiscoveryType `json:",omitempty" alias:"discovery_type"` - - // TLSCertificates refers to the data containing certificate authority certificates to use - // in verifying a presented peer certificate. - // If not specified and a peer certificate is presented it will not be verified. - // - // Must be either CaCertificateProviderInstance or TrustedCA. - TLSCertificates *JWKSTLSCertificate `json:",omitempty" alias:"tls_certificates"` - - // The timeout for new network connections to hosts in the cluster. - // If not set, a default value of 5s will be used. - ConnectTimeout time.Duration `json:",omitempty" alias:"connect_timeout"` -} - -type ClusterDiscoveryType string - -// JWKSTLSCertificate refers to the data containing certificate authority certificates to use -// in verifying a presented peer certificate. -// If not specified and a peer certificate is presented it will not be verified. -// -// Must be either CaCertificateProviderInstance or TrustedCA. -type JWKSTLSCertificate struct { - // CaCertificateProviderInstance Certificate provider instance for fetching TLS certificates. - CaCertificateProviderInstance *JWKSTLSCertProviderInstance `json:",omitempty" alias:"ca_certificate_provider_instance"` - - // TrustedCA defines TLS certificate data containing certificate authority certificates - // to use in verifying a presented peer certificate. - // - // Exactly one of Filename, EnvironmentVariable, InlineString or InlineBytes must be specified. - TrustedCA *JWKSTLSCertTrustedCA `json:",omitempty" alias:"trusted_ca"` -} - -// JWKSTLSCertTrustedCA defines TLS certificate data containing certificate authority certificates -// to use in verifying a presented peer certificate. -// -// Exactly one of Filename, EnvironmentVariable, InlineString or InlineBytes must be specified. -type JWKSTLSCertTrustedCA struct { - Filename string `json:",omitempty" alias:"filename"` - EnvironmentVariable string `json:",omitempty" alias:"environment_variable"` - InlineString string `json:",omitempty" alias:"inline_string"` - InlineBytes []byte `json:",omitempty" alias:"inline_bytes"` -} - -type JWKSTLSCertProviderInstance struct { - // InstanceName refers to the certificate provider instance name - // - // The default value is "default". - InstanceName string `json:",omitempty" alias:"instance_name"` - - // CertificateName is used to specify certificate instances or types. For example, "ROOTCA" to specify - // a root-certificate (validation context) or "example.com" to specify a certificate for a - // particular domain. - // - // The default value is the empty string. - CertificateName string `json:",omitempty" alias:"certificate_name"` -} - -type JWKSRetryPolicy struct { - // NumRetries is the number of times to retry fetching the JWKS. - // The retry strategy uses jittered exponential backoff with - // a base interval of 1s and max of 10s. - // - // Default value is 0. - NumRetries int `json:",omitempty" alias:"num_retries"` - - // Backoff policy - // - // Defaults to Envoy's backoff policy - RetryPolicyBackOff *RetryPolicyBackOff `json:",omitempty" alias:"retry_policy_back_off"` -} - -type RetryPolicyBackOff struct { - // BaseInterval to be used for the next back off computation - // - // The default value from envoy is 1s - BaseInterval time.Duration `json:",omitempty" alias:"base_interval"` - - // MaxInternal to be used to specify the maximum interval between retries. - // Optional but should be greater or equal to BaseInterval. - // - // Defaults to 10 times BaseInterval - MaxInterval time.Duration `json:",omitempty" alias:"max_interval"` -} - -type JWTCacheConfig struct { - // Size specifies the maximum number of JWT verification - // results to cache. - // - // Defaults to 0, meaning that JWT caching is disabled. - Size int `json:",omitempty"` -} - -func (e *JWTProviderConfigEntry) GetKind() string { - return JWTProvider -} - -func (e *JWTProviderConfigEntry) GetName() string { return e.Name } -func (e *JWTProviderConfigEntry) GetMeta() map[string]string { return e.Meta } -func (e *JWTProviderConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex } -func (e *JWTProviderConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex } -func (e *JWTProviderConfigEntry) GetPartition() string { return e.Partition } -func (e *JWTProviderConfigEntry) GetNamespace() string { return e.Namespace } diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_mesh.go b/vendor/github.com/hashicorp/consul/api/config_entry_mesh.go deleted file mode 100644 index 1a1ebb8b536bc..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/config_entry_mesh.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "encoding/json" -) - -// MeshConfigEntry manages the global configuration for all service mesh -// proxies. -type MeshConfigEntry struct { - // Partition is the partition the MeshConfigEntry applies to. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // Namespace is the namespace the MeshConfigEntry applies to. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` - - // TransparentProxy applies configuration specific to proxies - // in transparent mode. - TransparentProxy TransparentProxyMeshConfig `alias:"transparent_proxy"` - - // AllowEnablingPermissiveMutualTLS must be true in order to allow setting - // MutualTLSMode=permissive in either service-defaults or proxy-defaults. - AllowEnablingPermissiveMutualTLS bool `json:",omitempty" alias:"allow_enabling_permissive_mutual_tls"` - - TLS *MeshTLSConfig `json:",omitempty"` - - HTTP *MeshHTTPConfig `json:",omitempty"` - - Peering *PeeringMeshConfig `json:",omitempty"` - - Meta map[string]string `json:",omitempty"` - - // CreateIndex is the Raft index this entry was created at. This is a - // read-only field. - CreateIndex uint64 - - // ModifyIndex is used for the Check-And-Set operations and can also be fed - // back into the WaitIndex of the QueryOptions in order to perform blocking - // queries. - ModifyIndex uint64 -} - -type TransparentProxyMeshConfig struct { - MeshDestinationsOnly bool `alias:"mesh_destinations_only"` -} - -type MeshTLSConfig struct { - Incoming *MeshDirectionalTLSConfig `json:",omitempty"` - Outgoing *MeshDirectionalTLSConfig `json:",omitempty"` -} - -type MeshDirectionalTLSConfig struct { - TLSMinVersion string `json:",omitempty" alias:"tls_min_version"` - TLSMaxVersion string `json:",omitempty" alias:"tls_max_version"` - CipherSuites []string `json:",omitempty" alias:"cipher_suites"` -} - -type MeshHTTPConfig struct { - SanitizeXForwardedClientCert bool `alias:"sanitize_x_forwarded_client_cert"` -} - -type PeeringMeshConfig struct { - PeerThroughMeshGateways bool `json:",omitempty" alias:"peer_through_mesh_gateways"` -} - -func (e *MeshConfigEntry) GetKind() string { return MeshConfig } -func (e *MeshConfigEntry) GetName() string { return MeshConfigMesh } -func (e *MeshConfigEntry) GetPartition() string { return e.Partition } -func (e *MeshConfigEntry) GetNamespace() string { return e.Namespace } -func (e *MeshConfigEntry) GetMeta() map[string]string { return e.Meta } -func (e *MeshConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex } -func (e *MeshConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex } - -// MarshalJSON adds the Kind field so that the JSON can be decoded back into the -// correct type. -func (e *MeshConfigEntry) MarshalJSON() ([]byte, error) { - type Alias MeshConfigEntry - source := &struct { - Kind string - *Alias - }{ - Kind: MeshConfig, - Alias: (*Alias)(e), - } - return json.Marshal(source) -} diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_rate_limit_ip.go b/vendor/github.com/hashicorp/consul/api/config_entry_rate_limit_ip.go deleted file mode 100644 index 7af2a2658f2e1..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/config_entry_rate_limit_ip.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -type ReadWriteRatesConfig struct { - ReadRate float64 `alias:"read_rate"` - WriteRate float64 `alias:"write_rate"` -} - -type RateLimitIPConfigEntry struct { - // Kind of the config entry. This will be set to structs.RateLimitIPConfig - Kind string - Name string - Mode string // {permissive, enforcing, disabled} - - Meta map[string]string `json:",omitempty"` - // overall limits - ReadRate float64 `alias:"read_rate"` - WriteRate float64 `alias:"write_rate"` - - //limits specific to a type of call - ACL *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryACL OperationCategory = "ACL" - Catalog *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryCatalog OperationCategory = "Catalog" - ConfigEntry *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryConfigEntry OperationCategory = "ConfigEntry" - ConnectCA *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryConnectCA OperationCategory = "ConnectCA" - Coordinate *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryCoordinate OperationCategory = "Coordinate" - DiscoveryChain *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryDiscoveryChain OperationCategory = "DiscoveryChain" - ServerDiscovery *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryServerDiscovery OperationCategory = "ServerDiscovery" - Health *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryHealth OperationCategory = "Health" - Intention *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryIntention OperationCategory = "Intention" - KV *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryKV OperationCategory = "KV" - Tenancy *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryPartition OperationCategory = "Tenancy" - PreparedQuery *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryPreparedQuery OperationCategory = "PreparedQuery" - Session *ReadWriteRatesConfig `json:",omitempty"` // OperationCategorySession OperationCategory = "Session" - Txn *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryTxn OperationCategory = "Txn" - AutoConfig *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryAutoConfig OperationCategory = "AutoConfig" - FederationState *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryFederationState OperationCategory = "FederationState" - Internal *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryInternal OperationCategory = "Internal" - PeerStream *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryPeerStream OperationCategory = "PeerStream" - Peering *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryPeering OperationCategory = "Peering" - DataPlane *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryDataPlane OperationCategory = "DataPlane" - DNS *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryDNS OperationCategory = "DNS" - Subscribe *ReadWriteRatesConfig `json:",omitempty"` // OperationCategorySubscribe OperationCategory = "Subscribe" - Resource *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryResource OperationCategory = "Resource" - - // Partition is the partition the config entry is associated with. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // Namespace is the namespace the config entry is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` - - // CreateIndex is the Raft index this entry was created at. This is a - // read-only field. - CreateIndex uint64 - - // ModifyIndex is used for the Check-And-Set operations and can also be fed - // back into the WaitIndex of the QueryOptions in order to perform blocking - // queries. - ModifyIndex uint64 -} - -func (r *RateLimitIPConfigEntry) GetKind() string { - return RateLimitIPConfig -} -func (r *RateLimitIPConfigEntry) GetName() string { - if r == nil { - return "" - } - return r.Name -} -func (r *RateLimitIPConfigEntry) GetPartition() string { - return r.Partition -} -func (r *RateLimitIPConfigEntry) GetNamespace() string { - return r.Namespace -} -func (r *RateLimitIPConfigEntry) GetMeta() map[string]string { - if r == nil { - return nil - } - return r.Meta -} -func (r *RateLimitIPConfigEntry) GetCreateIndex() uint64 { - return r.CreateIndex -} -func (r *RateLimitIPConfigEntry) GetModifyIndex() uint64 { - return r.ModifyIndex -} diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_routes.go b/vendor/github.com/hashicorp/consul/api/config_entry_routes.go deleted file mode 100644 index bbaa032d50f66..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/config_entry_routes.go +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import "time" - -// TCPRouteConfigEntry -- TODO stub -type TCPRouteConfigEntry struct { - // Kind of the config entry. This should be set to api.TCPRoute. - Kind string - - // Name is used to match the config entry with its associated tcp-route - // service. This should match the name provided in the service definition. - Name string - - // Parents is a list of gateways that this route should be bound to. - Parents []ResourceReference - // Services is a list of TCP-based services that this should route to. - // Currently, this must specify at maximum one service. - Services []TCPService - - Meta map[string]string `json:",omitempty"` - - // Status is the asynchronous status which a TCPRoute propagates to the user. - Status ConfigEntryStatus - - // CreateIndex is the Raft index this entry was created at. This is a - // read-only field. - CreateIndex uint64 - - // ModifyIndex is used for the Check-And-Set operations and can also be fed - // back into the WaitIndex of the QueryOptions in order to perform blocking - // queries. - ModifyIndex uint64 - - // Partition is the partition the config entry is associated with. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // Namespace is the namespace the config entry is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` -} - -func (a *TCPRouteConfigEntry) GetKind() string { return TCPRoute } -func (a *TCPRouteConfigEntry) GetName() string { return a.Name } -func (a *TCPRouteConfigEntry) GetPartition() string { return a.Partition } -func (a *TCPRouteConfigEntry) GetNamespace() string { return a.Namespace } -func (a *TCPRouteConfigEntry) GetMeta() map[string]string { return a.Meta } -func (a *TCPRouteConfigEntry) GetCreateIndex() uint64 { return a.CreateIndex } -func (a *TCPRouteConfigEntry) GetModifyIndex() uint64 { return a.ModifyIndex } - -// TCPService is a service reference for a TCPRoute -type TCPService struct { - Name string - - // Partition is the partition the config entry is associated with. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // Namespace is the namespace the config entry is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` -} - -// HTTPRouteConfigEntry manages the configuration for a HTTP route -// with the given name. -type HTTPRouteConfigEntry struct { - // Kind of the config entry. This should be set to api.HTTPRoute. - Kind string - - // Name is used to match the config entry with its associated http-route. - Name string - - // Parents is a list of gateways that this route should be bound to - Parents []ResourceReference - // Rules are a list of HTTP-based routing rules that this route should - // use for constructing a routing table. - Rules []HTTPRouteRule - // Hostnames are the hostnames for which this HTTPRoute should respond to requests. - Hostnames []string - - Meta map[string]string `json:",omitempty"` - - // CreateIndex is the Raft index this entry was created at. This is a - // read-only field. - CreateIndex uint64 - - // ModifyIndex is used for the Check-And-Set operations and can also be fed - // back into the WaitIndex of the QueryOptions in order to perform blocking - // queries. - ModifyIndex uint64 - - // Partition is the partition the config entry is associated with. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // Namespace is the namespace the config entry is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` - - // Status is the asynchronous status which an HTTPRoute propagates to the user. - Status ConfigEntryStatus -} - -func (r *HTTPRouteConfigEntry) GetKind() string { return HTTPRoute } -func (r *HTTPRouteConfigEntry) GetName() string { return r.Name } -func (r *HTTPRouteConfigEntry) GetPartition() string { return r.Partition } -func (r *HTTPRouteConfigEntry) GetNamespace() string { return r.Namespace } -func (r *HTTPRouteConfigEntry) GetMeta() map[string]string { return r.Meta } -func (r *HTTPRouteConfigEntry) GetCreateIndex() uint64 { return r.CreateIndex } -func (r *HTTPRouteConfigEntry) GetModifyIndex() uint64 { return r.ModifyIndex } - -// HTTPMatch specifies the criteria that should be -// used in determining whether or not a request should -// be routed to a given set of services. -type HTTPMatch struct { - Headers []HTTPHeaderMatch - Method HTTPMatchMethod - Path HTTPPathMatch - Query []HTTPQueryMatch -} - -// HTTPMatchMethod specifies which type of HTTP verb should -// be used for matching a given request. -type HTTPMatchMethod string - -const ( - HTTPMatchMethodAll HTTPMatchMethod = "" - HTTPMatchMethodConnect HTTPMatchMethod = "CONNECT" - HTTPMatchMethodDelete HTTPMatchMethod = "DELETE" - HTTPMatchMethodGet HTTPMatchMethod = "GET" - HTTPMatchMethodHead HTTPMatchMethod = "HEAD" - HTTPMatchMethodOptions HTTPMatchMethod = "OPTIONS" - HTTPMatchMethodPatch HTTPMatchMethod = "PATCH" - HTTPMatchMethodPost HTTPMatchMethod = "POST" - HTTPMatchMethodPut HTTPMatchMethod = "PUT" - HTTPMatchMethodTrace HTTPMatchMethod = "TRACE" -) - -// HTTPHeaderMatchType specifies how header matching criteria -// should be applied to a request. -type HTTPHeaderMatchType string - -const ( - HTTPHeaderMatchExact HTTPHeaderMatchType = "exact" - HTTPHeaderMatchPrefix HTTPHeaderMatchType = "prefix" - HTTPHeaderMatchPresent HTTPHeaderMatchType = "present" - HTTPHeaderMatchRegularExpression HTTPHeaderMatchType = "regex" - HTTPHeaderMatchSuffix HTTPHeaderMatchType = "suffix" -) - -// HTTPHeaderMatch specifies how a match should be done -// on a request's headers. -type HTTPHeaderMatch struct { - Match HTTPHeaderMatchType - Name string - Value string -} - -// HTTPPathMatchType specifies how path matching criteria -// should be applied to a request. -type HTTPPathMatchType string - -const ( - HTTPPathMatchExact HTTPPathMatchType = "exact" - HTTPPathMatchPrefix HTTPPathMatchType = "prefix" - HTTPPathMatchRegularExpression HTTPPathMatchType = "regex" -) - -// HTTPPathMatch specifies how a match should be done -// on a request's path. -type HTTPPathMatch struct { - Match HTTPPathMatchType - Value string -} - -// HTTPQueryMatchType specifies how querys matching criteria -// should be applied to a request. -type HTTPQueryMatchType string - -const ( - HTTPQueryMatchExact HTTPQueryMatchType = "exact" - HTTPQueryMatchPresent HTTPQueryMatchType = "present" - HTTPQueryMatchRegularExpression HTTPQueryMatchType = "regex" -) - -// HTTPQueryMatch specifies how a match should be done -// on a request's query parameters. -type HTTPQueryMatch struct { - Match HTTPQueryMatchType - Name string - Value string -} - -// HTTPFilters specifies a list of filters used to modify a request -// before it is routed to an upstream. -type HTTPFilters struct { - Headers []HTTPHeaderFilter - URLRewrite *URLRewrite - RetryFilter *RetryFilter - TimeoutFilter *TimeoutFilter - JWT *JWTFilter -} - -// HTTPResponseFilters specifies a list of filters used to modify a -// response returned by an upstream -type HTTPResponseFilters struct { - Headers []HTTPHeaderFilter -} - -// HTTPHeaderFilter specifies how HTTP headers should be modified. -type HTTPHeaderFilter struct { - Add map[string]string - Remove []string - Set map[string]string -} - -type URLRewrite struct { - Path string -} - -type RetryFilter struct { - NumRetries uint32 - RetryOn []string - RetryOnStatusCodes []uint32 - RetryOnConnectFailure bool -} - -type TimeoutFilter struct { - RequestTimeout time.Duration - IdleTimeout time.Duration -} - -// JWTFilter specifies the JWT configuration for a route -type JWTFilter struct { - Providers []*APIGatewayJWTProvider `json:",omitempty"` -} - -// HTTPRouteRule specifies the routing rules used to determine what upstream -// service an HTTP request is routed to. -type HTTPRouteRule struct { - // Filters is a list of HTTP-based filters used to modify a request prior - // to routing it to the upstream service - Filters HTTPFilters - // ResponseFilters is a list of HTTP-based filters used to modify a response - // returned by the upstream service - ResponseFilters HTTPResponseFilters - // Matches specified the matching criteria used in the routing table. If a - // request matches the given HTTPMatch configuration, then traffic is routed - // to services specified in the Services field. - Matches []HTTPMatch - // Services is a list of HTTP-based services to route to if the request matches - // the rules specified in the Matches field. - Services []HTTPService -} - -// HTTPService is a service reference for HTTP-based routing rules -type HTTPService struct { - Name string - // Weight is an arbitrary integer used in calculating how much - // traffic should be sent to the given service. - Weight int - - // Filters is a list of HTTP-based filters used to modify a request prior - // to routing it to the upstream service - Filters HTTPFilters - - // ResponseFilters is a list of HTTP-based filters used to modify the - // response returned from the upstream service - ResponseFilters HTTPResponseFilters - - // Partition is the partition the config entry is associated with. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // Namespace is the namespace the config entry is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` -} diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_sameness_group.go b/vendor/github.com/hashicorp/consul/api/config_entry_sameness_group.go deleted file mode 100644 index 1217efe7d2ccd..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/config_entry_sameness_group.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -type SamenessGroupConfigEntry struct { - Kind string - Name string - Partition string `json:",omitempty"` - DefaultForFailover bool `json:",omitempty" alias:"default_for_failover"` - IncludeLocal bool `json:",omitempty" alias:"include_local"` - Members []SamenessGroupMember - Meta map[string]string `json:",omitempty"` - CreateIndex uint64 - ModifyIndex uint64 -} - -type SamenessGroupMember struct { - Partition string `json:",omitempty"` - Peer string `json:",omitempty"` -} - -func (s *SamenessGroupConfigEntry) GetKind() string { return s.Kind } -func (s *SamenessGroupConfigEntry) GetName() string { return s.Name } -func (s *SamenessGroupConfigEntry) GetPartition() string { return s.Partition } -func (s *SamenessGroupConfigEntry) GetNamespace() string { return "" } -func (s *SamenessGroupConfigEntry) GetCreateIndex() uint64 { return s.CreateIndex } -func (s *SamenessGroupConfigEntry) GetModifyIndex() uint64 { return s.ModifyIndex } -func (s *SamenessGroupConfigEntry) GetMeta() map[string]string { return s.Meta } diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_status.go b/vendor/github.com/hashicorp/consul/api/config_entry_status.go deleted file mode 100644 index 997066f24fe9d..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/config_entry_status.go +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "fmt" - "time" - - "golang.org/x/exp/slices" -) - -// ResourceReference is a reference to a ConfigEntry -// with an optional reference to a subsection of that ConfigEntry -// that can be specified as SectionName -type ResourceReference struct { - // Kind is the kind of ConfigEntry that this resource refers to. - Kind string - // Name is the identifier for the ConfigEntry this resource refers to. - Name string - // SectionName is a generic subresource identifier that specifies - // a subset of the ConfigEntry to which this reference applies. Usage - // of this field should be up to the controller that leverages it. If - // unused, this should be blank. - SectionName string - - // Partition is the partition the config entry is associated with. - // Partitioning is a Consul Enterprise feature. - Partition string `json:",omitempty"` - - // Namespace is the namespace the config entry is associated with. - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` -} - -// ConfigEntryStatus is used for propagating back asynchronously calculated -// messages from control loops to a user -type ConfigEntryStatus struct { - // Conditions is the set of condition objects associated with - // a ConfigEntry status. - Conditions []Condition -} - -// Condition is used for a single message and state associated -// with an object. For example, a ConfigEntry that references -// multiple other resources may have different statuses with -// respect to each of those resources. -type Condition struct { - // Type is a value from a bounded set of types that an object might have - Type string - // Status is a value from a bounded set of statuses that an object might have - Status ConditionStatus - // Reason is a value from a bounded set of reasons for a given status - Reason string - // Message is a message that gives more detailed information about - // why a Condition has a given status and reason - Message string - // Resource is an optional reference to a resource for which this - // condition applies - Resource *ResourceReference - // LastTransitionTime is the time at which this Condition was created - LastTransitionTime *time.Time -} - -type ( - ConditionStatus string -) - -const ( - ConditionStatusTrue ConditionStatus = "True" - ConditionStatusFalse ConditionStatus = "False" - ConditionStatusUnknown ConditionStatus = "Unknown" -) - -// GatewayConditionType is a type of condition associated with a -// Gateway. This type should be used with the GatewayStatus.Conditions -// field. -type GatewayConditionType string - -// GatewayConditionReason defines the set of reasons that explain why a -// particular Gateway condition type has been raised. -type GatewayConditionReason string - -// the following are directly from the k8s spec -const ( - // This condition is true when the controller managing the Gateway is - // syntactically and semantically valid enough to produce some configuration - // in the underlying data plane. This does not indicate whether or not the - // configuration has been propagated to the data plane. - // - // Possible reasons for this condition to be True are: - // - // * "Accepted" - // - // Possible reasons for this condition to be False are: - // - // * InvalidCertificates - // - GatewayConditionAccepted GatewayConditionType = "Accepted" - - // This reason is used with the "Accepted" condition when the condition is - // True. - GatewayReasonAccepted GatewayConditionReason = "Accepted" - - // This reason is used with the "Accepted" condition when the gateway has multiple invalid - // certificates and cannot bind to any routes - GatewayReasonInvalidCertificates GatewayConditionReason = "InvalidCertificates" - - // This reason is used with the "Accepted" condition when the gateway has multiple invalid - // JWT providers and cannot bind to any routes - GatewayReasonInvalidJWTProviders GatewayConditionReason = "InvalidJWTProviders" - - // This condition indicates that the gateway was unable to resolve - // conflicting specification requirements for this Listener. If a - // Listener is conflicted, its network port should not be configured - // on any network elements. - // - // Possible reasons for this condition to be true are: - // - // * "RouteConflict" - // - // Possible reasons for this condition to be False are: - // - // * "NoConflict" - // - // Controllers may raise this condition with other reasons, - // but should prefer to use the reasons listed above to improve - // interoperability. - GatewayConditionConflicted GatewayConditionType = "Conflicted" - // This reason is used with the "Conflicted" condition when the condition - // is False. - GatewayReasonNoConflict GatewayConditionReason = "NoConflict" - // This reason is used with the "Conflicted" condition when the route is - // in a conflicted state, such as when a TCPListener attempts to bind to two routes - GatewayReasonRouteConflict GatewayConditionReason = "RouteConflict" - - // This condition indicates whether the controller was able to - // resolve all the object references for the Gateway. When setting this - // condition to False, a ResourceReference to the misconfigured Listener should - // be provided. - // - // Possible reasons for this condition to be true are: - // - // * "ResolvedRefs" - // - // Possible reasons for this condition to be False are: - // - // * "InvalidCertificateRef" - // * "InvalidRouteKinds" - // * "RefNotPermitted" - // - GatewayConditionResolvedRefs GatewayConditionType = "ResolvedRefs" - - // This reason is used with the "ResolvedRefs" condition when the condition - // is true. - GatewayReasonResolvedRefs GatewayConditionReason = "ResolvedRefs" - - // This reason is used with the "ResolvedRefs" condition when a - // Listener has a TLS configuration with at least one TLS CertificateRef - // that is invalid or does not exist. - // A CertificateRef is considered invalid when it refers to a nonexistent - // or unsupported resource or kind, or when the data within that resource - // is malformed. - // This reason must be used only when the reference is allowed, either by - // referencing an object in the same namespace as the Gateway, or when - // a cross-namespace reference has been explicitly allowed by a ReferenceGrant. - // If the reference is not allowed, the reason RefNotPermitted must be used - // instead. - GatewayListenerReasonInvalidCertificateRef GatewayConditionReason = "InvalidCertificateRef" - - // This reason is used with the "ResolvedRefs" condition when a - // Listener has a JWT configuration with at least one JWTProvider - // that is invalid or does not exist. - // A JWTProvider is considered invalid when it refers to a nonexistent - // or unsupported resource or kind, or when the data within that resource - // is malformed. - GatewayListenerReasonInvalidJWTProviderRef GatewayConditionReason = "InvalidJWTProviderRef" -) - -var validGatewayConditionReasonsMapping = map[GatewayConditionType]map[ConditionStatus][]GatewayConditionReason{ - GatewayConditionAccepted: { - ConditionStatusTrue: { - GatewayReasonAccepted, - }, - ConditionStatusFalse: { - GatewayReasonInvalidCertificates, - GatewayReasonInvalidJWTProviders, - }, - ConditionStatusUnknown: {}, - }, - GatewayConditionConflicted: { - ConditionStatusTrue: { - GatewayReasonRouteConflict, - }, - ConditionStatusFalse: { - GatewayReasonNoConflict, - }, - ConditionStatusUnknown: {}, - }, - GatewayConditionResolvedRefs: { - ConditionStatusTrue: { - GatewayReasonResolvedRefs, - }, - ConditionStatusFalse: { - GatewayListenerReasonInvalidCertificateRef, - GatewayListenerReasonInvalidJWTProviderRef, - }, - ConditionStatusUnknown: {}, - }, -} - -func ValidateGatewayConditionReason(name GatewayConditionType, status ConditionStatus, reason GatewayConditionReason) error { - if err := checkConditionStatus(status); err != nil { - return err - } - - reasons, ok := validGatewayConditionReasonsMapping[name] - if !ok { - return fmt.Errorf("unrecognized GatewayConditionType %q", name) - } - - reasonsForStatus, ok := reasons[status] - if !ok { - return fmt.Errorf("unrecognized ConditionStatus %q", status) - } - - if !slices.Contains(reasonsForStatus, reason) { - return fmt.Errorf("gateway condition reason %q not allowed for gateway condition type %q with status %q", reason, name, status) - } - return nil -} - -// RouteConditionType is a type of condition for a route. -type RouteConditionType string - -// RouteConditionReason is a reason for a route condition. -type RouteConditionReason string - -// The following statuses are taken from the K8's Spec -// With the exception of: "RouteReasonInvalidDiscoveryChain" and "NoUpstreamServicesTargeted" -const ( - // This condition indicates whether the route has been accepted or rejected - // by a Gateway, and why. - // - // Possible reasons for this condition to be true are: - // - // * "Accepted" - // - // Possible reasons for this condition to be False are: - // - // * "InvalidDiscoveryChain" - // * "NoUpstreamServicesTargeted" - // - // - // Controllers may raise this condition with other reasons, - // but should prefer to use the reasons listed above to improve - // interoperability. - RouteConditionAccepted RouteConditionType = "Accepted" - - // This reason is used with the "Accepted" condition when the Route has been - // accepted by the Gateway. - RouteReasonAccepted RouteConditionReason = "Accepted" - - // This reason is used with the "Accepted" condition when the route has an - // invalid discovery chain, this includes conditions like the protocol being invalid - // or the discovery chain failing to compile - RouteReasonInvalidDiscoveryChain RouteConditionReason = "InvalidDiscoveryChain" - - // This reason is used with the "Accepted" condition when the route - RouteReasonNoUpstreamServicesTargeted RouteConditionReason = "NoUpstreamServicesTargeted" -) - -// the following statuses are custom to Consul -const ( - // This condition indicates whether the route was able to successfully bind the - // Listener on the gateway - // Possible reasons for this condition to be true are: - // - // * "Bound" - // - // Possible reasons for this condition to be false are: - // - // * "FailedToBind" - // * "GatewayNotFound" - // - RouteConditionBound RouteConditionType = "Bound" - - // This reason is used with the "Bound" condition when the condition - // is true - RouteReasonBound RouteConditionReason = "Bound" - - // This reason is used with the "Bound" condition when the route failed - // to bind to the gateway - RouteReasonFailedToBind RouteConditionReason = "FailedToBind" - - // This reason is used with the "Bound" condition when the route fails - // to find the gateway - RouteReasonGatewayNotFound RouteConditionReason = "GatewayNotFound" - - // This reason is used with the "Accepted" condition when the route references non-existent - // JWTProviders - RouteReasonJWTProvidersNotFound RouteConditionReason = "JWTProvidersNotFound" -) - -var validRouteConditionReasonsMapping = map[RouteConditionType]map[ConditionStatus][]RouteConditionReason{ - RouteConditionAccepted: { - ConditionStatusTrue: { - RouteReasonAccepted, - }, - ConditionStatusFalse: { - RouteReasonInvalidDiscoveryChain, - RouteReasonNoUpstreamServicesTargeted, - }, - ConditionStatusUnknown: {}, - }, - RouteConditionBound: { - ConditionStatusTrue: { - RouteReasonBound, - }, - ConditionStatusFalse: { - RouteReasonGatewayNotFound, - RouteReasonFailedToBind, - RouteReasonJWTProvidersNotFound, - }, - ConditionStatusUnknown: {}, - }, -} - -func ValidateRouteConditionReason(name RouteConditionType, status ConditionStatus, reason RouteConditionReason) error { - if err := checkConditionStatus(status); err != nil { - return err - } - - reasons, ok := validRouteConditionReasonsMapping[name] - if !ok { - return fmt.Errorf("unrecognized RouteConditionType %s", name) - } - - reasonsForStatus, ok := reasons[status] - if !ok { - return fmt.Errorf("unrecognized ConditionStatus %s", name) - } - - if !slices.Contains(reasonsForStatus, reason) { - return fmt.Errorf("route condition reason %s not allowed for route condition type %s with status %s", reason, name, status) - } - - return nil -} - -func checkConditionStatus(status ConditionStatus) error { - switch status { - case ConditionStatusTrue, ConditionStatusFalse, ConditionStatusUnknown: - return nil - default: - return fmt.Errorf("unrecognized condition status: %q", status) - } -} diff --git a/vendor/github.com/hashicorp/consul/api/connect.go b/vendor/github.com/hashicorp/consul/api/connect.go deleted file mode 100644 index 77be00034d034..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/connect.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -// TelemetryCollectorName is the service name for the Consul Telemetry Collector -const TelemetryCollectorName string = "consul-telemetry-collector" - -// Connect can be used to work with endpoints related to Connect, the -// feature for securely connecting services within Consul. -type Connect struct { - c *Client -} - -// Connect returns a handle to the connect-related endpoints -func (c *Client) Connect() *Connect { - return &Connect{c} -} diff --git a/vendor/github.com/hashicorp/consul/api/connect_ca.go b/vendor/github.com/hashicorp/consul/api/connect_ca.go deleted file mode 100644 index 8a5c9f870e954..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/connect_ca.go +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "fmt" - "time" - - "github.com/mitchellh/mapstructure" -) - -// CAConfig is the structure for the Connect CA configuration. -type CAConfig struct { - // Provider is the CA provider implementation to use. - Provider string - - // Configuration is arbitrary configuration for the provider. This - // should only contain primitive values and containers (such as lists - // and maps). - Config map[string]interface{} - - // State is read-only data that the provider might have persisted for use - // after restart or leadership transition. For example this might include - // UUIDs of resources it has created. Setting this when writing a - // configuration is an error. - State map[string]string - - // ForceWithoutCrossSigning indicates that the CA reconfiguration should go - // ahead even if the current CA is unable to cross sign certificates. This - // risks temporary connection failures during the rollout as new leafs will be - // rejected by proxies that have not yet observed the new root cert but is the - // only option if a CA that doesn't support cross signing needs to be - // reconfigured or mirated away from. - ForceWithoutCrossSigning bool - - CreateIndex uint64 - ModifyIndex uint64 -} - -// CommonCAProviderConfig is the common options available to all CA providers. -type CommonCAProviderConfig struct { - LeafCertTTL time.Duration - RootCertTTL time.Duration - SkipValidate bool - CSRMaxPerSecond float32 - CSRMaxConcurrent int -} - -// ConsulCAProviderConfig is the config for the built-in Consul CA provider. -type ConsulCAProviderConfig struct { - CommonCAProviderConfig `mapstructure:",squash"` - - PrivateKey string - RootCert string - IntermediateCertTTL time.Duration -} - -// ParseConsulCAConfig takes a raw config map and returns a parsed -// ConsulCAProviderConfig. -func ParseConsulCAConfig(raw map[string]interface{}) (*ConsulCAProviderConfig, error) { - var config ConsulCAProviderConfig - decodeConf := &mapstructure.DecoderConfig{ - DecodeHook: mapstructure.StringToTimeDurationHookFunc(), - Result: &config, - WeaklyTypedInput: true, - } - - decoder, err := mapstructure.NewDecoder(decodeConf) - if err != nil { - return nil, err - } - - if err := decoder.Decode(raw); err != nil { - return nil, fmt.Errorf("error decoding config: %s", err) - } - - return &config, nil -} - -// CARootList is the structure for the results of listing roots. -type CARootList struct { - ActiveRootID string - TrustDomain string - Roots []*CARoot -} - -// CARoot represents a root CA certificate that is trusted. -type CARoot struct { - // ID is a globally unique ID (UUID) representing this CA root. - ID string - - // Name is a human-friendly name for this CA root. This value is - // opaque to Consul and is not used for anything internally. - Name string - - // RootCertPEM is the PEM-encoded public certificate. - RootCertPEM string `json:"RootCert"` - - // Active is true if this is the current active CA. This must only - // be true for exactly one CA. For any method that modifies roots in the - // state store, tests should be written to verify that multiple roots - // cannot be active. - Active bool - - CreateIndex uint64 - ModifyIndex uint64 -} - -// LeafCert is a certificate that has been issued by a Connect CA. -type LeafCert struct { - // SerialNumber is the unique serial number for this certificate. - // This is encoded in standard hex separated by :. - SerialNumber string - - // CertPEM and PrivateKeyPEM are the PEM-encoded certificate and private - // key for that cert, respectively. This should not be stored in the - // state store, but is present in the sign API response. - CertPEM string `json:",omitempty"` - PrivateKeyPEM string `json:",omitempty"` - - // Service is the name of the service for which the cert was issued. - // ServiceURI is the cert URI value. - Service string - ServiceURI string - - // ValidAfter and ValidBefore are the validity periods for the - // certificate. - ValidAfter time.Time - ValidBefore time.Time - - CreateIndex uint64 - ModifyIndex uint64 -} - -// CARoots queries the list of available roots. -func (h *Connect) CARoots(q *QueryOptions) (*CARootList, *QueryMeta, error) { - r := h.c.newRequest("GET", "/v1/connect/ca/roots") - r.setQueryOptions(q) - rtt, resp, err := h.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out CARootList - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return &out, qm, nil -} - -// CAGetConfig returns the current CA configuration. -func (h *Connect) CAGetConfig(q *QueryOptions) (*CAConfig, *QueryMeta, error) { - r := h.c.newRequest("GET", "/v1/connect/ca/configuration") - r.setQueryOptions(q) - rtt, resp, err := h.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out CAConfig - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return &out, qm, nil -} - -// CASetConfig sets the current CA configuration. -func (h *Connect) CASetConfig(conf *CAConfig, q *WriteOptions) (*WriteMeta, error) { - r := h.c.newRequest("PUT", "/v1/connect/ca/configuration") - r.setWriteOptions(q) - r.obj = conf - rtt, resp, err := h.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{} - wm.RequestTime = rtt - return wm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/connect_intention.go b/vendor/github.com/hashicorp/consul/api/connect_intention.go deleted file mode 100644 index e91c03e8b71ad..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/connect_intention.go +++ /dev/null @@ -1,461 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "bytes" - "fmt" - "io" - "time" -) - -// Intention defines an intention for the Connect Service Graph. This defines -// the allowed or denied behavior of a connection between two services using -// Connect. -type Intention struct { - // ID is the UUID-based ID for the intention, always generated by Consul. - ID string `json:",omitempty"` - - // Description is a human-friendly description of this intention. - // It is opaque to Consul and is only stored and transferred in API - // requests. - Description string `json:",omitempty"` - - // SourceNS, SourceName are the namespace and name, respectively, of - // the source service. Either of these may be the wildcard "*", but only - // the full value can be a wildcard. Partial wildcards are not allowed. - // The source may also be a non-Consul service, as specified by SourceType. - // - // DestinationNS, DestinationName is the same, but for the destination - // service. The same rules apply. The destination is always a Consul - // service. - SourceNS, SourceName string - DestinationNS, DestinationName string - - // SourcePartition and DestinationPartition cannot be wildcards "*" and - // are not compatible with legacy intentions. - SourcePartition string `json:",omitempty"` - DestinationPartition string `json:",omitempty"` - - // SourcePeer cannot be a wildcard "*" and is not compatible with legacy - // intentions. Cannot be used with SourcePartition, as both represent the - // same level of tenancy (partition is local to cluster, peer is remote). - SourcePeer string `json:",omitempty"` - - // SourceSamenessGroup cannot be wildcards "*" and - // is not compatible with legacy intentions. - SourceSamenessGroup string `json:",omitempty"` - - // SourceType is the type of the value for the source. - SourceType IntentionSourceType - - // Action is whether this is an allowlist or denylist intention. - Action IntentionAction `json:",omitempty"` - - // Permissions is the list of additional L7 attributes that extend the - // intention definition. - // - // NOTE: This field is not editable unless editing the underlying - // service-intentions config entry directly. - Permissions []*IntentionPermission `json:",omitempty"` - - // DefaultAddr is not used. - // Deprecated: DefaultAddr is not used and may be removed in a future version. - DefaultAddr string `json:",omitempty"` - // DefaultPort is not used. - // Deprecated: DefaultPort is not used and may be removed in a future version. - DefaultPort int `json:",omitempty"` - - // Meta is arbitrary metadata associated with the intention. This is - // opaque to Consul but is served in API responses. - Meta map[string]string `json:",omitempty"` - - // Precedence is the order that the intention will be applied, with - // larger numbers being applied first. This is a read-only field, on - // any intention update it is updated. - Precedence int - - // CreatedAt and UpdatedAt keep track of when this record was created - // or modified. - CreatedAt, UpdatedAt time.Time - - // Hash of the contents of the intention - // - // This is needed mainly for replication purposes. When replicating from - // one DC to another keeping the content Hash will allow us to detect - // content changes more efficiently than checking every single field - Hash []byte `json:",omitempty"` - - CreateIndex uint64 - ModifyIndex uint64 -} - -// String returns human-friendly output describing ths intention. -func (i *Intention) String() string { - var detail string - switch n := len(i.Permissions); n { - case 0: - detail = string(i.Action) - case 1: - detail = "1 permission" - default: - detail = fmt.Sprintf("%d permissions", len(i.Permissions)) - } - - return fmt.Sprintf("%s => %s (%s)", - i.SourceString(), - i.DestinationString(), - detail) -} - -// SourceString returns the namespace/name format for the source, or -// just "name" if the namespace is the default namespace. -func (i *Intention) SourceString() string { - return i.partString(i.SourceNS, i.SourceName) -} - -// DestinationString returns the namespace/name format for the source, or -// just "name" if the namespace is the default namespace. -func (i *Intention) DestinationString() string { - return i.partString(i.DestinationNS, i.DestinationName) -} - -func (i *Intention) partString(ns, n string) string { - // For now we omit the default namespace from the output. In the future - // we might want to look at this and show this in a multi-namespace world. - if ns != "" && ns != IntentionDefaultNamespace { - n = ns + "/" + n - } - - return n -} - -// IntentionDefaultNamespace is the default namespace value. -const IntentionDefaultNamespace = "default" - -// IntentionAction is the action that the intention represents. This -// can be "allow" or "deny" to allowlist or denylist intentions. -type IntentionAction string - -const ( - IntentionActionAllow IntentionAction = "allow" - IntentionActionDeny IntentionAction = "deny" -) - -// IntentionSourceType is the type of the source within an intention. -type IntentionSourceType string - -const ( - // IntentionSourceConsul is a service within the Consul catalog. - IntentionSourceConsul IntentionSourceType = "consul" -) - -// IntentionMatch are the arguments for the intention match API. -type IntentionMatch struct { - By IntentionMatchType - Names []string -} - -// IntentionMatchType is the target for a match request. For example, -// matching by source will look for all intentions that match the given -// source value. -type IntentionMatchType string - -const ( - IntentionMatchSource IntentionMatchType = "source" - IntentionMatchDestination IntentionMatchType = "destination" -) - -// IntentionCheck are the arguments for the intention check API. For -// more documentation see the IntentionCheck function. -type IntentionCheck struct { - // Source and Destination are the source and destination values to - // check. The destination is always a Consul service, but the source - // may be other values as defined by the SourceType. - Source, Destination string - - // SourceType is the type of the value for the source. - SourceType IntentionSourceType -} - -// Intentions returns the list of intentions. -func (h *Connect) Intentions(q *QueryOptions) ([]*Intention, *QueryMeta, error) { - r := h.c.newRequest("GET", "/v1/connect/intentions") - r.setQueryOptions(q) - rtt, resp, err := h.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out []*Intention - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// IntentionGetExact retrieves a single intention by its unique name instead of -// its ID. -func (h *Connect) IntentionGetExact(source, destination string, q *QueryOptions) (*Intention, *QueryMeta, error) { - r := h.c.newRequest("GET", "/v1/connect/intentions/exact") - r.setQueryOptions(q) - r.params.Set("source", source) - r.params.Set("destination", destination) - rtt, resp, err := h.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if resp.StatusCode == 404 { - return nil, qm, nil - } else if resp.StatusCode != 200 { - var buf bytes.Buffer - io.Copy(&buf, resp.Body) - return nil, nil, fmt.Errorf( - "Unexpected response %d: %s", resp.StatusCode, buf.String()) - } - - var out Intention - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return &out, qm, nil -} - -// IntentionGet retrieves a single intention. -// -// Deprecated: use IntentionGetExact instead -func (h *Connect) IntentionGet(id string, q *QueryOptions) (*Intention, *QueryMeta, error) { - r := h.c.newRequest("GET", "/v1/connect/intentions/"+id) - r.setQueryOptions(q) - rtt, resp, err := h.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if resp.StatusCode == 404 { - return nil, qm, nil - } else if resp.StatusCode != 200 { - var buf bytes.Buffer - io.Copy(&buf, resp.Body) - return nil, nil, fmt.Errorf( - "Unexpected response %d: %s", resp.StatusCode, buf.String()) - } - - var out Intention - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return &out, qm, nil -} - -// IntentionDeleteExact deletes a single intention by its unique name instead of its ID. -func (h *Connect) IntentionDeleteExact(source, destination string, q *WriteOptions) (*WriteMeta, error) { - r := h.c.newRequest("DELETE", "/v1/connect/intentions/exact") - r.setWriteOptions(q) - r.params.Set("source", source) - r.params.Set("destination", destination) - - rtt, resp, err := h.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - qm := &WriteMeta{} - qm.RequestTime = rtt - - return qm, nil -} - -// IntentionDelete deletes a single intention. -// -// Deprecated: use IntentionDeleteExact instead -func (h *Connect) IntentionDelete(id string, q *WriteOptions) (*WriteMeta, error) { - r := h.c.newRequest("DELETE", "/v1/connect/intentions/"+id) - r.setWriteOptions(q) - rtt, resp, err := h.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - qm := &WriteMeta{} - qm.RequestTime = rtt - - return qm, nil -} - -// IntentionMatch returns the list of intentions that match a given source -// or destination. The returned intentions are ordered by precedence where -// result[0] is the highest precedence (if that matches, then that rule overrides -// all other rules). -// -// Matching can be done for multiple names at the same time. The resulting -// map is keyed by the given names. Casing is preserved. -func (h *Connect) IntentionMatch(args *IntentionMatch, q *QueryOptions) (map[string][]*Intention, *QueryMeta, error) { - r := h.c.newRequest("GET", "/v1/connect/intentions/match") - r.setQueryOptions(q) - r.params.Set("by", string(args.By)) - for _, name := range args.Names { - r.params.Add("name", name) - } - rtt, resp, err := h.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out map[string][]*Intention - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// IntentionCheck returns whether a given source/destination would be allowed -// or not given the current set of intentions and the configuration of Consul. -func (h *Connect) IntentionCheck(args *IntentionCheck, q *QueryOptions) (bool, *QueryMeta, error) { - r := h.c.newRequest("GET", "/v1/connect/intentions/check") - r.setQueryOptions(q) - r.params.Set("source", args.Source) - r.params.Set("destination", args.Destination) - if args.SourceType != "" { - r.params.Set("source-type", string(args.SourceType)) - } - rtt, resp, err := h.c.doRequest(r) - if err != nil { - return false, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return false, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out struct{ Allowed bool } - if err := decodeBody(resp, &out); err != nil { - return false, nil, err - } - return out.Allowed, qm, nil -} - -// IntentionUpsert will update an existing intention. The Source & Destination parameters -// in the structure must be non-empty. The ID must be empty. -func (c *Connect) IntentionUpsert(ixn *Intention, q *WriteOptions) (*WriteMeta, error) { - r := c.c.newRequest("PUT", "/v1/connect/intentions/exact") - r.setWriteOptions(q) - r.params.Set("source", maybePrefixNamespaceAndPartition(ixn.SourcePartition, ixn.SourceNS, ixn.SourceName)) - r.params.Set("destination", maybePrefixNamespaceAndPartition(ixn.DestinationPartition, ixn.DestinationNS, ixn.DestinationName)) - r.obj = ixn - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{} - wm.RequestTime = rtt - return wm, nil -} - -func maybePrefixNamespaceAndPartition(part, ns, name string) string { - switch { - case part == "" && ns == "": - return name - case part == "" && ns != "": - return ns + "/" + name - case part != "" && ns == "": - return part + "/" + IntentionDefaultNamespace + "/" + name - default: - return part + "/" + ns + "/" + name - } -} - -// IntentionCreate will create a new intention. The ID in the given -// structure must be empty and a generate ID will be returned on -// success. -// -// Deprecated: use IntentionUpsert instead -func (c *Connect) IntentionCreate(ixn *Intention, q *WriteOptions) (string, *WriteMeta, error) { - r := c.c.newRequest("POST", "/v1/connect/intentions") - r.setWriteOptions(q) - r.obj = ixn - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return "", nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return "", nil, err - } - - wm := &WriteMeta{} - wm.RequestTime = rtt - - var out struct{ ID string } - if err := decodeBody(resp, &out); err != nil { - return "", nil, err - } - return out.ID, wm, nil -} - -// IntentionUpdate will update an existing intention. The ID in the given -// structure must be non-empty. -// -// Deprecated: use IntentionUpsert instead -func (c *Connect) IntentionUpdate(ixn *Intention, q *WriteOptions) (*WriteMeta, error) { - r := c.c.newRequest("PUT", "/v1/connect/intentions/"+ixn.ID) - r.setWriteOptions(q) - r.obj = ixn - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{} - wm.RequestTime = rtt - return wm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/coordinate.go b/vendor/github.com/hashicorp/consul/api/coordinate.go deleted file mode 100644 index b0269adaef684..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/coordinate.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "github.com/hashicorp/serf/coordinate" -) - -// CoordinateEntry represents a node and its associated network coordinate. -type CoordinateEntry struct { - Node string - Segment string - Partition string `json:",omitempty"` - Coord *coordinate.Coordinate -} - -// CoordinateDatacenterMap has the coordinates for servers in a given datacenter -// and area. Network coordinates are only compatible within the same area. -type CoordinateDatacenterMap struct { - Datacenter string - AreaID string - Coordinates []CoordinateEntry -} - -// Coordinate can be used to query the coordinate endpoints -type Coordinate struct { - c *Client -} - -// Coordinate returns a handle to the coordinate endpoints -func (c *Client) Coordinate() *Coordinate { - return &Coordinate{c} -} - -// Datacenters is used to return the coordinates of all the servers in the WAN -// pool. -func (c *Coordinate) Datacenters() ([]*CoordinateDatacenterMap, error) { - r := c.c.newRequest("GET", "/v1/coordinate/datacenters") - _, resp, err := c.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - var out []*CoordinateDatacenterMap - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - return out, nil -} - -// Nodes is used to return the coordinates of all the nodes in the LAN pool. -func (c *Coordinate) Nodes(q *QueryOptions) ([]*CoordinateEntry, *QueryMeta, error) { - r := c.c.newRequest("GET", "/v1/coordinate/nodes") - r.setQueryOptions(q) - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out []*CoordinateEntry - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// Update inserts or updates the LAN coordinate of a node. -func (c *Coordinate) Update(coord *CoordinateEntry, q *WriteOptions) (*WriteMeta, error) { - r := c.c.newRequest("PUT", "/v1/coordinate/update") - r.setWriteOptions(q) - r.obj = coord - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{} - wm.RequestTime = rtt - - return wm, nil -} - -// Node is used to return the coordinates of a single node in the LAN pool. -func (c *Coordinate) Node(node string, q *QueryOptions) ([]*CoordinateEntry, *QueryMeta, error) { - r := c.c.newRequest("GET", "/v1/coordinate/node/"+node) - r.setQueryOptions(q) - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out []*CoordinateEntry - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/debug.go b/vendor/github.com/hashicorp/consul/api/debug.go deleted file mode 100644 index e6b5dc52dac2c..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/debug.go +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "context" - "fmt" - "io" - "strconv" -) - -// Debug can be used to query the /debug/pprof endpoints to gather -// profiling information about the target agent.Debug -// -// The agent must have enable_debug set to true for profiling to be enabled -// and for these endpoints to function. -type Debug struct { - c *Client -} - -// Debug returns a handle that exposes the internal debug endpoints. -func (c *Client) Debug() *Debug { - return &Debug{c} -} - -// Heap returns a pprof heap dump -func (d *Debug) Heap() ([]byte, error) { - r := d.c.newRequest("GET", "/debug/pprof/heap") - _, resp, err := d.c.doRequest(r) - if err != nil { - return nil, fmt.Errorf("error making request: %s", err) - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - // We return a raw response because we're just passing through a response - // from the pprof handlers - body, err := io.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("error decoding body: %s", err) - } - - return body, nil -} - -// Profile returns a pprof CPU profile for the specified number of seconds -func (d *Debug) Profile(seconds int) ([]byte, error) { - r := d.c.newRequest("GET", "/debug/pprof/profile") - - // Capture a profile for the specified number of seconds - r.params.Set("seconds", strconv.Itoa(seconds)) - - _, resp, err := d.c.doRequest(r) - if err != nil { - return nil, fmt.Errorf("error making request: %s", err) - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - // We return a raw response because we're just passing through a response - // from the pprof handlers - body, err := io.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("error decoding body: %s", err) - } - - return body, nil -} - -// PProf returns a pprof profile for the specified number of seconds. The caller -// is responsible for closing the returned io.ReadCloser once all bytes are read. -func (d *Debug) PProf(ctx context.Context, name string, seconds int) (io.ReadCloser, error) { - r := d.c.newRequest("GET", "/debug/pprof/"+name) - r.ctx = ctx - - // Capture a profile for the specified number of seconds - r.params.Set("seconds", strconv.Itoa(seconds)) - - _, resp, err := d.c.doRequest(r) - if err != nil { - return nil, fmt.Errorf("error making request: %s", err) - } - if err := requireOK(resp); err != nil { - return nil, err - } - return resp.Body, nil -} - -// Trace returns an execution trace -func (d *Debug) Trace(seconds int) ([]byte, error) { - r := d.c.newRequest("GET", "/debug/pprof/trace") - - // Capture a trace for the specified number of seconds - r.params.Set("seconds", strconv.Itoa(seconds)) - - _, resp, err := d.c.doRequest(r) - if err != nil { - return nil, fmt.Errorf("error making request: %s", err) - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - // We return a raw response because we're just passing through a response - // from the pprof handlers - body, err := io.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("error decoding body: %s", err) - } - - return body, nil -} - -// Goroutine returns a pprof goroutine profile -func (d *Debug) Goroutine() ([]byte, error) { - r := d.c.newRequest("GET", "/debug/pprof/goroutine") - - _, resp, err := d.c.doRequest(r) - if err != nil { - return nil, fmt.Errorf("error making request: %s", err) - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - // We return a raw response because we're just passing through a response - // from the pprof handlers - body, err := io.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("error decoding body: %s", err) - } - - return body, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/discovery_chain.go b/vendor/github.com/hashicorp/consul/api/discovery_chain.go deleted file mode 100644 index 4b6260cf34aaa..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/discovery_chain.go +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "encoding/json" - "fmt" - "time" -) - -// DiscoveryChain can be used to query the discovery-chain endpoints -type DiscoveryChain struct { - c *Client -} - -// DiscoveryChain returns a handle to the discovery-chain endpoints -func (c *Client) DiscoveryChain() *DiscoveryChain { - return &DiscoveryChain{c} -} - -func (d *DiscoveryChain) Get(name string, opts *DiscoveryChainOptions, q *QueryOptions) (*DiscoveryChainResponse, *QueryMeta, error) { - if name == "" { - return nil, nil, fmt.Errorf("Name parameter must not be empty") - } - - method := "GET" - if opts != nil && opts.requiresPOST() { - method = "POST" - } - - r := d.c.newRequest(method, fmt.Sprintf("/v1/discovery-chain/%s", name)) - r.setQueryOptions(q) - - if opts != nil { - if opts.EvaluateInDatacenter != "" { - r.params.Set("compile-dc", opts.EvaluateInDatacenter) - } - } - - if method == "POST" { - r.obj = opts - } - rtt, resp, err := d.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out DiscoveryChainResponse - - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, qm, nil -} - -type DiscoveryChainOptions struct { - EvaluateInDatacenter string `json:"-"` - - // OverrideMeshGateway allows for the mesh gateway setting to be overridden - // for any resolver in the compiled chain. - OverrideMeshGateway MeshGatewayConfig `json:",omitempty"` - - // OverrideProtocol allows for the final protocol for the chain to be - // altered. - // - // - If the chain ordinarily would be TCP and an L7 protocol is passed here - // the chain will not include Routers or Splitters. - // - // - If the chain ordinarily would be L7 and TCP is passed here the chain - // will not include Routers or Splitters. - OverrideProtocol string `json:",omitempty"` - - // OverrideConnectTimeout allows for the ConnectTimeout setting to be - // overridden for any resolver in the compiled chain. - OverrideConnectTimeout time.Duration `json:",omitempty"` -} - -func (o *DiscoveryChainOptions) requiresPOST() bool { - if o == nil { - return false - } - return o.OverrideMeshGateway.Mode != "" || - o.OverrideProtocol != "" || - o.OverrideConnectTimeout != 0 -} - -type DiscoveryChainResponse struct { - Chain *CompiledDiscoveryChain -} - -type CompiledDiscoveryChain struct { - ServiceName string - Namespace string - Datacenter string - - // CustomizationHash is a unique hash of any data that affects the - // compilation of the discovery chain other than config entries or the - // name/namespace/datacenter evaluation criteria. - // - // If set, this value should be used to prefix/suffix any generated load - // balancer data plane objects to avoid sharing customized and - // non-customized versions. - CustomizationHash string - - // Default indicates if this discovery chain is based on no - // service-resolver, service-splitter, or service-router config entries. - Default bool - - // Protocol is the overall protocol shared by everything in the chain. - Protocol string - - // ServiceMeta is the metadata from the underlying service-defaults config - // entry for the service named ServiceName. - ServiceMeta map[string]string - - // StartNode is the first key into the Nodes map that should be followed - // when walking the discovery chain. - StartNode string - - // Nodes contains all nodes available for traversal in the chain keyed by a - // unique name. You can walk this by starting with StartNode. - // - // NOTE: The names should be treated as opaque values and are only - // guaranteed to be consistent within a single compilation. - Nodes map[string]*DiscoveryGraphNode - - // Targets is a list of all targets used in this chain. - // - // NOTE: The names should be treated as opaque values and are only - // guaranteed to be consistent within a single compilation. - Targets map[string]*DiscoveryTarget -} - -const ( - DiscoveryGraphNodeTypeRouter = "router" - DiscoveryGraphNodeTypeSplitter = "splitter" - DiscoveryGraphNodeTypeResolver = "resolver" -) - -// DiscoveryGraphNode is a single node in the compiled discovery chain. -type DiscoveryGraphNode struct { - Type string - Name string // this is NOT necessarily a service - - // fields for Type==router - Routes []*DiscoveryRoute - - // fields for Type==splitter - Splits []*DiscoverySplit - - // fields for Type==resolver - Resolver *DiscoveryResolver - - // shared by Type==resolver || Type==splitter - LoadBalancer *LoadBalancer `json:",omitempty"` -} - -// compiled form of ServiceRoute -type DiscoveryRoute struct { - Definition *ServiceRoute - NextNode string -} - -// compiled form of ServiceSplit -type DiscoverySplit struct { - Weight float32 - NextNode string -} - -// compiled form of ServiceResolverConfigEntry -type DiscoveryResolver struct { - Default bool - ConnectTimeout time.Duration - Target string - Failover *DiscoveryFailover -} - -func (r *DiscoveryResolver) MarshalJSON() ([]byte, error) { - type Alias DiscoveryResolver - exported := &struct { - ConnectTimeout string `json:",omitempty"` - *Alias - }{ - ConnectTimeout: r.ConnectTimeout.String(), - Alias: (*Alias)(r), - } - if r.ConnectTimeout == 0 { - exported.ConnectTimeout = "" - } - - return json.Marshal(exported) -} - -func (r *DiscoveryResolver) UnmarshalJSON(data []byte) error { - type Alias DiscoveryResolver - aux := &struct { - ConnectTimeout string - *Alias - }{ - Alias: (*Alias)(r), - } - if err := json.Unmarshal(data, &aux); err != nil { - return err - } - var err error - if aux.ConnectTimeout != "" { - if r.ConnectTimeout, err = time.ParseDuration(aux.ConnectTimeout); err != nil { - return err - } - } - return nil -} - -// compiled form of ServiceResolverFailover -type DiscoveryFailover struct { - Targets []string - Policy ServiceResolverFailoverPolicy `json:",omitempty"` -} - -// DiscoveryTarget represents all of the inputs necessary to use a resolver -// config entry to execute a catalog query to generate a list of service -// instances during discovery. -type DiscoveryTarget struct { - ID string - - Service string - ServiceSubset string - Namespace string - Datacenter string - - MeshGateway MeshGatewayConfig - Subset ServiceResolverSubset - ConnectTimeout time.Duration - External bool - SNI string - Name string -} - -func (t *DiscoveryTarget) MarshalJSON() ([]byte, error) { - type Alias DiscoveryTarget - exported := &struct { - ConnectTimeout string `json:",omitempty"` - *Alias - }{ - ConnectTimeout: t.ConnectTimeout.String(), - Alias: (*Alias)(t), - } - if t.ConnectTimeout == 0 { - exported.ConnectTimeout = "" - } - - return json.Marshal(exported) -} - -func (t *DiscoveryTarget) UnmarshalJSON(data []byte) error { - type Alias DiscoveryTarget - aux := &struct { - ConnectTimeout string - *Alias - }{ - Alias: (*Alias)(t), - } - if err := json.Unmarshal(data, &aux); err != nil { - return err - } - var err error - if aux.ConnectTimeout != "" { - if t.ConnectTimeout, err = time.ParseDuration(aux.ConnectTimeout); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/hashicorp/consul/api/event.go b/vendor/github.com/hashicorp/consul/api/event.go deleted file mode 100644 index efba89d3b5673..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/event.go +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "bytes" - "strconv" -) - -// Event can be used to query the Event endpoints -type Event struct { - c *Client -} - -// UserEvent represents an event that was fired by the user -type UserEvent struct { - ID string - Name string - Payload []byte - NodeFilter string - ServiceFilter string - TagFilter string - Version int - LTime uint64 -} - -// Event returns a handle to the event endpoints -func (c *Client) Event() *Event { - return &Event{c} -} - -// Fire is used to fire a new user event. Only the Name, Payload and Filters -// are respected. This returns the ID or an associated error. Cross DC requests -// are supported. -func (e *Event) Fire(params *UserEvent, q *WriteOptions) (string, *WriteMeta, error) { - r := e.c.newRequest("PUT", "/v1/event/fire/"+params.Name) - r.setWriteOptions(q) - if params.NodeFilter != "" { - r.params.Set("node", params.NodeFilter) - } - if params.ServiceFilter != "" { - r.params.Set("service", params.ServiceFilter) - } - if params.TagFilter != "" { - r.params.Set("tag", params.TagFilter) - } - if params.Payload != nil { - r.body = bytes.NewReader(params.Payload) - } - r.header.Set("Content-Type", "application/octet-stream") - - rtt, resp, err := e.c.doRequest(r) - if err != nil { - return "", nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return "", nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - var out UserEvent - if err := decodeBody(resp, &out); err != nil { - return "", nil, err - } - return out.ID, wm, nil -} - -// List is used to get the most recent events an agent has received. -// This list can be optionally filtered by the name. This endpoint supports -// quasi-blocking queries. The index is not monotonic, nor does it provide provide -// LastContact or KnownLeader. -func (e *Event) List(name string, q *QueryOptions) ([]*UserEvent, *QueryMeta, error) { - r := e.c.newRequest("GET", "/v1/event/list") - r.setQueryOptions(q) - if name != "" { - r.params.Set("name", name) - } - rtt, resp, err := e.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var entries []*UserEvent - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, err - } - return entries, qm, nil -} - -// IDToIndex is a bit of a hack. This simulates the index generation to -// convert an event ID into a WaitIndex. -func (e *Event) IDToIndex(uuid string) uint64 { - lower := uuid[0:8] + uuid[9:13] + uuid[14:18] - upper := uuid[19:23] + uuid[24:36] - lowVal, err := strconv.ParseUint(lower, 16, 64) - if err != nil { - panic("Failed to convert " + lower) - } - highVal, err := strconv.ParseUint(upper, 16, 64) - if err != nil { - panic("Failed to convert " + upper) - } - return lowVal ^ highVal -} diff --git a/vendor/github.com/hashicorp/consul/api/exported_services.go b/vendor/github.com/hashicorp/consul/api/exported_services.go deleted file mode 100644 index 50483e9c8da65..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/exported_services.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -type ResolvedExportedService struct { - // Service is the name of the service which is exported. - Service string - - // Partition of the service - Partition string `json:",omitempty"` - - // Namespace of the service - Namespace string `json:",omitempty"` - - // Consumers is a list of downstream consumers of the service. - Consumers ResolvedConsumers -} - -type ResolvedConsumers struct { - Peers []string `json:",omitempty"` - Partitions []string `json:",omitempty"` -} - -func (c *Client) ExportedServices(q *QueryOptions) ([]ResolvedExportedService, *QueryMeta, error) { - - r := c.newRequest("GET", "/v1/exported-services") - r.setQueryOptions(q) - rtt, resp, err := c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var expSvcs []ResolvedExportedService - - if err := decodeBody(resp, &expSvcs); err != nil { - return nil, nil, err - } - - return expSvcs, qm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/health.go b/vendor/github.com/hashicorp/consul/api/health.go deleted file mode 100644 index a0230020460de..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/health.go +++ /dev/null @@ -1,398 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "encoding/json" - "fmt" - "strings" - "time" -) - -const ( - // HealthAny is special, and is used as a wild card, - // not as a specific state. - HealthAny = "any" - HealthPassing = "passing" - HealthWarning = "warning" - HealthCritical = "critical" - HealthMaint = "maintenance" -) - -const ( - serviceHealth = "service" - connectHealth = "connect" - ingressHealth = "ingress" -) - -const ( - // NodeMaint is the special key set by a node in maintenance mode. - NodeMaint = "_node_maintenance" - - // ServiceMaintPrefix is the prefix for a service in maintenance mode. - ServiceMaintPrefix = "_service_maintenance:" -) - -// HealthCheck is used to represent a single check -type HealthCheck struct { - Node string - CheckID string - Name string - Status string - Notes string - Output string - ServiceID string - ServiceName string - ServiceTags []string - Type string - Namespace string `json:",omitempty"` - Partition string `json:",omitempty"` - ExposedPort int - PeerName string `json:",omitempty"` - - Definition HealthCheckDefinition - - CreateIndex uint64 - ModifyIndex uint64 -} - -// HealthCheckDefinition is used to store the details about -// a health check's execution. -type HealthCheckDefinition struct { - HTTP string - Header map[string][]string - Method string - Body string - TLSServerName string - TLSSkipVerify bool - TCP string - TCPUseTLS bool - UDP string - GRPC string - OSService string - GRPCUseTLS bool - IntervalDuration time.Duration `json:"-"` - TimeoutDuration time.Duration `json:"-"` - DeregisterCriticalServiceAfterDuration time.Duration `json:"-"` - - // DEPRECATED in Consul 1.4.1. Use the above time.Duration fields instead. - Interval ReadableDuration - Timeout ReadableDuration - DeregisterCriticalServiceAfter ReadableDuration -} - -func (d *HealthCheckDefinition) MarshalJSON() ([]byte, error) { - type Alias HealthCheckDefinition - out := &struct { - Interval string - Timeout string - DeregisterCriticalServiceAfter string - *Alias - }{ - Interval: d.Interval.String(), - Timeout: d.Timeout.String(), - DeregisterCriticalServiceAfter: d.DeregisterCriticalServiceAfter.String(), - Alias: (*Alias)(d), - } - - if d.IntervalDuration != 0 { - out.Interval = d.IntervalDuration.String() - } else if d.Interval != 0 { - out.Interval = d.Interval.String() - } - if d.TimeoutDuration != 0 { - out.Timeout = d.TimeoutDuration.String() - } else if d.Timeout != 0 { - out.Timeout = d.Timeout.String() - } - if d.DeregisterCriticalServiceAfterDuration != 0 { - out.DeregisterCriticalServiceAfter = d.DeregisterCriticalServiceAfterDuration.String() - } else if d.DeregisterCriticalServiceAfter != 0 { - out.DeregisterCriticalServiceAfter = d.DeregisterCriticalServiceAfter.String() - } - - return json.Marshal(out) -} - -func (t *HealthCheckDefinition) UnmarshalJSON(data []byte) (err error) { - type Alias HealthCheckDefinition - aux := &struct { - IntervalDuration interface{} - TimeoutDuration interface{} - DeregisterCriticalServiceAfterDuration interface{} - *Alias - }{ - Alias: (*Alias)(t), - } - if err := json.Unmarshal(data, &aux); err != nil { - return err - } - - // Parse the values into both the time.Duration and old ReadableDuration fields. - - if aux.IntervalDuration == nil { - t.IntervalDuration = time.Duration(t.Interval) - } else { - switch v := aux.IntervalDuration.(type) { - case string: - if t.IntervalDuration, err = time.ParseDuration(v); err != nil { - return err - } - case float64: - t.IntervalDuration = time.Duration(v) - } - t.Interval = ReadableDuration(t.IntervalDuration) - } - - if aux.TimeoutDuration == nil { - t.TimeoutDuration = time.Duration(t.Timeout) - } else { - switch v := aux.TimeoutDuration.(type) { - case string: - if t.TimeoutDuration, err = time.ParseDuration(v); err != nil { - return err - } - case float64: - t.TimeoutDuration = time.Duration(v) - } - t.Timeout = ReadableDuration(t.TimeoutDuration) - } - if aux.DeregisterCriticalServiceAfterDuration == nil { - t.DeregisterCriticalServiceAfterDuration = time.Duration(t.DeregisterCriticalServiceAfter) - } else { - switch v := aux.DeregisterCriticalServiceAfterDuration.(type) { - case string: - if t.DeregisterCriticalServiceAfterDuration, err = time.ParseDuration(v); err != nil { - return err - } - case float64: - t.DeregisterCriticalServiceAfterDuration = time.Duration(v) - } - t.DeregisterCriticalServiceAfter = ReadableDuration(t.DeregisterCriticalServiceAfterDuration) - } - - return nil -} - -// HealthChecks is a collection of HealthCheck structs. -type HealthChecks []*HealthCheck - -// AggregatedStatus returns the "best" status for the list of health checks. -// Because a given entry may have many service and node-level health checks -// attached, this function determines the best representative of the status as -// as single string using the following heuristic: -// -// maintenance > critical > warning > passing -func (c HealthChecks) AggregatedStatus() string { - var passing, warning, critical, maintenance bool - for _, check := range c { - id := check.CheckID - if id == NodeMaint || strings.HasPrefix(id, ServiceMaintPrefix) { - maintenance = true - continue - } - - switch check.Status { - case HealthPassing: - passing = true - case HealthWarning: - warning = true - case HealthCritical: - critical = true - default: - return "" - } - } - - switch { - case maintenance: - return HealthMaint - case critical: - return HealthCritical - case warning: - return HealthWarning - case passing: - return HealthPassing - default: - return HealthPassing - } -} - -// ServiceEntry is used for the health service endpoint -type ServiceEntry struct { - Node *Node - Service *AgentService - Checks HealthChecks -} - -// Health can be used to query the Health endpoints -type Health struct { - c *Client -} - -// Health returns a handle to the health endpoints -func (c *Client) Health() *Health { - return &Health{c} -} - -// Node is used to query for checks belonging to a given node -func (h *Health) Node(node string, q *QueryOptions) (HealthChecks, *QueryMeta, error) { - r := h.c.newRequest("GET", "/v1/health/node/"+node) - r.setQueryOptions(q) - rtt, resp, err := h.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out HealthChecks - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// Checks is used to return the checks associated with a service -func (h *Health) Checks(service string, q *QueryOptions) (HealthChecks, *QueryMeta, error) { - r := h.c.newRequest("GET", "/v1/health/checks/"+service) - r.setQueryOptions(q) - rtt, resp, err := h.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out HealthChecks - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// Service is used to query health information along with service info -// for a given service. It can optionally do server-side filtering on a tag -// or nodes with passing health checks only. -func (h *Health) Service(service, tag string, passingOnly bool, q *QueryOptions) ([]*ServiceEntry, *QueryMeta, error) { - var tags []string - if tag != "" { - tags = []string{tag} - } - return h.service(service, tags, passingOnly, q, serviceHealth) -} - -func (h *Health) ServiceMultipleTags(service string, tags []string, passingOnly bool, q *QueryOptions) ([]*ServiceEntry, *QueryMeta, error) { - return h.service(service, tags, passingOnly, q, serviceHealth) -} - -// Connect is equivalent to Service except that it will only return services -// which are Connect-enabled and will returns the connection address for Connect -// client's to use which may be a proxy in front of the named service. If -// passingOnly is true only instances where both the service and any proxy are -// healthy will be returned. -func (h *Health) Connect(service, tag string, passingOnly bool, q *QueryOptions) ([]*ServiceEntry, *QueryMeta, error) { - var tags []string - if tag != "" { - tags = []string{tag} - } - return h.service(service, tags, passingOnly, q, connectHealth) -} - -func (h *Health) ConnectMultipleTags(service string, tags []string, passingOnly bool, q *QueryOptions) ([]*ServiceEntry, *QueryMeta, error) { - return h.service(service, tags, passingOnly, q, connectHealth) -} - -// Ingress is equivalent to Connect except that it will only return associated -// ingress gateways for the requested service. -func (h *Health) Ingress(service string, passingOnly bool, q *QueryOptions) ([]*ServiceEntry, *QueryMeta, error) { - var tags []string - return h.service(service, tags, passingOnly, q, ingressHealth) -} - -func (h *Health) service(service string, tags []string, passingOnly bool, q *QueryOptions, healthType string) ([]*ServiceEntry, *QueryMeta, error) { - var path string - switch healthType { - case connectHealth: - path = "/v1/health/connect/" + service - case ingressHealth: - path = "/v1/health/ingress/" + service - default: - path = "/v1/health/service/" + service - } - - r := h.c.newRequest("GET", path) - r.setQueryOptions(q) - if len(tags) > 0 { - for _, tag := range tags { - r.params.Add("tag", tag) - } - } - if passingOnly { - r.params.Set(HealthPassing, "1") - } - rtt, resp, err := h.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out []*ServiceEntry - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// State is used to retrieve all the checks in a given state. -// The wildcard "any" state can also be used for all checks. -func (h *Health) State(state string, q *QueryOptions) (HealthChecks, *QueryMeta, error) { - switch state { - case HealthAny: - case HealthWarning: - case HealthCritical: - case HealthPassing: - default: - return nil, nil, fmt.Errorf("Unsupported state: %v", state) - } - r := h.c.newRequest("GET", "/v1/health/state/"+state) - r.setQueryOptions(q) - rtt, resp, err := h.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out HealthChecks - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/internal.go b/vendor/github.com/hashicorp/consul/api/internal.go deleted file mode 100644 index b5f400f4b19be..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/internal.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import "context" - -// Internal can be used to query endpoints that are intended for -// Hashicorp internal-use only. -type Internal struct { - c *Client -} - -// Internal returns a handle to endpoints that are for internal -// Hashicorp usage only. There is not guarantee that these will -// be backwards-compatible or supported, so usage of these is -// not encouraged. -func (c *Client) Internal() *Internal { - return &Internal{c} -} - -type AssignServiceManualVIPsRequest struct { - Service string - ManualVIPs []string -} - -type AssignServiceManualVIPsResponse struct { - ServiceFound bool `json:"Found"` - UnassignedFrom []PeeredServiceName -} - -type PeeredServiceName struct { - ServiceName CompoundServiceName - Peer string -} - -func (i *Internal) AssignServiceVirtualIP( - ctx context.Context, - service string, - manualVIPs []string, - wo *WriteOptions, -) (*AssignServiceManualVIPsResponse, *QueryMeta, error) { - req := i.c.newRequest("PUT", "/v1/internal/service-virtual-ip") - req.setWriteOptions(wo) - req.ctx = ctx - req.obj = AssignServiceManualVIPsRequest{ - Service: service, - ManualVIPs: manualVIPs, - } - rtt, resp, err := i.c.doRequest(req) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{RequestTime: rtt} - parseQueryMeta(resp, qm) - - var out AssignServiceManualVIPsResponse - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return &out, qm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/kv.go b/vendor/github.com/hashicorp/consul/api/kv.go deleted file mode 100644 index b9d330a6fd3b5..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/kv.go +++ /dev/null @@ -1,307 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "bytes" - "fmt" - "io" - "net/http" - "strconv" - "strings" -) - -// KVPair is used to represent a single K/V entry -type KVPair struct { - // Key is the name of the key. It is also part of the URL path when accessed - // via the API. - Key string - - // CreateIndex holds the index corresponding the creation of this KVPair. This - // is a read-only field. - CreateIndex uint64 - - // ModifyIndex is used for the Check-And-Set operations and can also be fed - // back into the WaitIndex of the QueryOptions in order to perform blocking - // queries. - ModifyIndex uint64 - - // LockIndex holds the index corresponding to a lock on this key, if any. This - // is a read-only field. - LockIndex uint64 - - // Flags are any user-defined flags on the key. It is up to the implementer - // to check these values, since Consul does not treat them specially. - Flags uint64 - - // Value is the value for the key. This can be any value, but it will be - // base64 encoded upon transport. - Value []byte - - // Session is a string representing the ID of the session. Any other - // interactions with this key over the same session must specify the same - // session ID. - Session string - - // Namespace is the namespace the KVPair is associated with - // Namespacing is a Consul Enterprise feature. - Namespace string `json:",omitempty"` - - // Partition is the partition the KVPair is associated with - // Admin Partition is a Consul Enterprise feature. - Partition string `json:",omitempty"` -} - -// KVPairs is a list of KVPair objects -type KVPairs []*KVPair - -// KV is used to manipulate the K/V API -type KV struct { - c *Client -} - -// KV is used to return a handle to the K/V apis -func (c *Client) KV() *KV { - return &KV{c} -} - -// Get is used to lookup a single key. The returned pointer -// to the KVPair will be nil if the key does not exist. -func (k *KV) Get(key string, q *QueryOptions) (*KVPair, *QueryMeta, error) { - resp, qm, err := k.getInternal(key, nil, q) - if err != nil { - return nil, nil, err - } - if resp == nil { - return nil, qm, nil - } - defer closeResponseBody(resp) - - var entries []*KVPair - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, err - } - if len(entries) > 0 { - return entries[0], qm, nil - } - return nil, qm, nil -} - -// List is used to lookup all keys under a prefix -func (k *KV) List(prefix string, q *QueryOptions) (KVPairs, *QueryMeta, error) { - resp, qm, err := k.getInternal(prefix, map[string]string{"recurse": ""}, q) - if err != nil { - return nil, nil, err - } - if resp == nil { - return nil, qm, nil - } - defer closeResponseBody(resp) - - var entries []*KVPair - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, err - } - return entries, qm, nil -} - -// Keys is used to list all the keys under a prefix. Optionally, -// a separator can be used to limit the responses. -func (k *KV) Keys(prefix, separator string, q *QueryOptions) ([]string, *QueryMeta, error) { - params := map[string]string{"keys": ""} - if separator != "" { - params["separator"] = separator - } - resp, qm, err := k.getInternal(prefix, params, q) - if err != nil { - return nil, nil, err - } - if resp == nil { - return nil, qm, nil - } - defer closeResponseBody(resp) - - var entries []string - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, err - } - return entries, qm, nil -} - -func (k *KV) getInternal(key string, params map[string]string, q *QueryOptions) (*http.Response, *QueryMeta, error) { - r := k.c.newRequest("GET", "/v1/kv/"+strings.TrimPrefix(key, "/")) - r.setQueryOptions(q) - for param, val := range params { - r.params.Set(param, val) - } - rtt, resp, err := k.c.doRequest(r) - if err != nil { - return nil, nil, err - } - - err = requireHttpCodes(resp, 200, 404) - if err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if resp.StatusCode == 404 { - closeResponseBody(resp) - return nil, qm, nil - } - - return resp, qm, nil -} - -// Put is used to write a new value. Only the -// Key, Flags and Value is respected. -func (k *KV) Put(p *KVPair, q *WriteOptions) (*WriteMeta, error) { - params := make(map[string]string, 1) - if p.Flags != 0 { - params["flags"] = strconv.FormatUint(p.Flags, 10) - } - _, wm, err := k.put(p.Key, params, p.Value, q) - return wm, err -} - -// CAS is used for a Check-And-Set operation. The Key, -// ModifyIndex, Flags and Value are respected. Returns true -// on success or false on failures. -func (k *KV) CAS(p *KVPair, q *WriteOptions) (bool, *WriteMeta, error) { - params := make(map[string]string, 2) - if p.Flags != 0 { - params["flags"] = strconv.FormatUint(p.Flags, 10) - } - params["cas"] = strconv.FormatUint(p.ModifyIndex, 10) - return k.put(p.Key, params, p.Value, q) -} - -// Acquire is used for a lock acquisition operation. The Key, -// Flags, Value and Session are respected. Returns true -// on success or false on failures. -func (k *KV) Acquire(p *KVPair, q *WriteOptions) (bool, *WriteMeta, error) { - params := make(map[string]string, 2) - if p.Flags != 0 { - params["flags"] = strconv.FormatUint(p.Flags, 10) - } - params["acquire"] = p.Session - return k.put(p.Key, params, p.Value, q) -} - -// Release is used for a lock release operation. The Key, -// Flags, Value and Session are respected. Returns true -// on success or false on failures. -func (k *KV) Release(p *KVPair, q *WriteOptions) (bool, *WriteMeta, error) { - params := make(map[string]string, 2) - if p.Flags != 0 { - params["flags"] = strconv.FormatUint(p.Flags, 10) - } - params["release"] = p.Session - return k.put(p.Key, params, p.Value, q) -} - -func (k *KV) put(key string, params map[string]string, body []byte, q *WriteOptions) (bool, *WriteMeta, error) { - if len(key) > 0 && key[0] == '/' { - return false, nil, fmt.Errorf("Invalid key. Key must not begin with a '/': %s", key) - } - - r := k.c.newRequest("PUT", "/v1/kv/"+key) - r.setWriteOptions(q) - for param, val := range params { - r.params.Set(param, val) - } - r.body = bytes.NewReader(body) - r.header.Set("Content-Type", "application/octet-stream") - rtt, resp, err := k.c.doRequest(r) - if err != nil { - return false, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return false, nil, err - } - - qm := &WriteMeta{} - qm.RequestTime = rtt - - var buf bytes.Buffer - if _, err := io.Copy(&buf, resp.Body); err != nil { - return false, nil, fmt.Errorf("Failed to read response: %v", err) - } - res := strings.Contains(buf.String(), "true") - return res, qm, nil -} - -// Delete is used to delete a single key -func (k *KV) Delete(key string, w *WriteOptions) (*WriteMeta, error) { - _, qm, err := k.deleteInternal(key, nil, w) - return qm, err -} - -// DeleteCAS is used for a Delete Check-And-Set operation. The Key -// and ModifyIndex are respected. Returns true on success or false on failures. -func (k *KV) DeleteCAS(p *KVPair, q *WriteOptions) (bool, *WriteMeta, error) { - params := map[string]string{ - "cas": strconv.FormatUint(p.ModifyIndex, 10), - } - return k.deleteInternal(p.Key, params, q) -} - -// DeleteTree is used to delete all keys under a prefix -func (k *KV) DeleteTree(prefix string, w *WriteOptions) (*WriteMeta, error) { - _, qm, err := k.deleteInternal(prefix, map[string]string{"recurse": ""}, w) - return qm, err -} - -func (k *KV) deleteInternal(key string, params map[string]string, q *WriteOptions) (bool, *WriteMeta, error) { - r := k.c.newRequest("DELETE", "/v1/kv/"+strings.TrimPrefix(key, "/")) - r.setWriteOptions(q) - for param, val := range params { - r.params.Set(param, val) - } - rtt, resp, err := k.c.doRequest(r) - if err != nil { - return false, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return false, nil, err - } - - qm := &WriteMeta{} - qm.RequestTime = rtt - - var buf bytes.Buffer - if _, err := io.Copy(&buf, resp.Body); err != nil { - return false, nil, fmt.Errorf("Failed to read response: %v", err) - } - res := strings.Contains(buf.String(), "true") - return res, qm, nil -} - -// The Txn function has been deprecated from the KV object; please see the Txn -// object for more information about Transactions. -func (k *KV) Txn(txn KVTxnOps, q *QueryOptions) (bool, *KVTxnResponse, *QueryMeta, error) { - var ops TxnOps - for _, op := range txn { - ops = append(ops, &TxnOp{KV: op}) - } - - respOk, txnResp, qm, err := k.c.txn(ops, q) - if err != nil { - return false, nil, nil, err - } - - // Convert from the internal format. - kvResp := KVTxnResponse{ - Errors: txnResp.Errors, - } - for _, result := range txnResp.Results { - kvResp.Results = append(kvResp.Results, result.KV) - } - return respOk, &kvResp, qm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/lock.go b/vendor/github.com/hashicorp/consul/api/lock.go deleted file mode 100644 index e9529f7bde64f..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/lock.go +++ /dev/null @@ -1,411 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "fmt" - "sync" - "time" -) - -const ( - // DefaultLockSessionName is the Session Name we assign if none is provided - DefaultLockSessionName = "Consul API Lock" - - // DefaultLockSessionTTL is the default session TTL if no Session is provided - // when creating a new Lock. This is used because we do not have another - // other check to depend upon. - DefaultLockSessionTTL = "15s" - - // DefaultLockWaitTime is how long we block for at a time to check if lock - // acquisition is possible. This affects the minimum time it takes to cancel - // a Lock acquisition. - DefaultLockWaitTime = 15 * time.Second - - // DefaultLockRetryTime is how long we wait after a failed lock acquisition - // before attempting to do the lock again. This is so that once a lock-delay - // is in effect, we do not hot loop retrying the acquisition. - DefaultLockRetryTime = 5 * time.Second - - // DefaultMonitorRetryTime is how long we wait after a failed monitor check - // of a lock (500 response code). This allows the monitor to ride out brief - // periods of unavailability, subject to the MonitorRetries setting in the - // lock options which is by default set to 0, disabling this feature. This - // affects locks and semaphores. - DefaultMonitorRetryTime = 2 * time.Second - - // LockFlagValue is a magic flag we set to indicate a key - // is being used for a lock. It is used to detect a potential - // conflict with a semaphore. - LockFlagValue = 0x2ddccbc058a50c18 -) - -var ( - // ErrLockHeld is returned if we attempt to double lock - ErrLockHeld = fmt.Errorf("Lock already held") - - // ErrLockNotHeld is returned if we attempt to unlock a lock - // that we do not hold. - ErrLockNotHeld = fmt.Errorf("Lock not held") - - // ErrLockInUse is returned if we attempt to destroy a lock - // that is in use. - ErrLockInUse = fmt.Errorf("Lock in use") - - // ErrLockConflict is returned if the flags on a key - // used for a lock do not match expectation - ErrLockConflict = fmt.Errorf("Existing key does not match lock use") -) - -// Lock is used to implement client-side leader election. It is follows the -// algorithm as described here: https://www.consul.io/docs/guides/leader-election.html. -type Lock struct { - c *Client - opts *LockOptions - - isHeld bool - sessionRenew chan struct{} - lockSession string - l sync.Mutex -} - -// LockOptions is used to parameterize the Lock behavior. -type LockOptions struct { - Key string // Must be set and have write permissions - Value []byte // Optional, value to associate with the lock - Session string // Optional, created if not specified - SessionOpts *SessionEntry // Optional, options to use when creating a session - SessionName string // Optional, defaults to DefaultLockSessionName (ignored if SessionOpts is given) - SessionTTL string // Optional, defaults to DefaultLockSessionTTL (ignored if SessionOpts is given) - MonitorRetries int // Optional, defaults to 0 which means no retries - MonitorRetryTime time.Duration // Optional, defaults to DefaultMonitorRetryTime - LockWaitTime time.Duration // Optional, defaults to DefaultLockWaitTime - LockTryOnce bool // Optional, defaults to false which means try forever - LockDelay time.Duration // Optional, defaults to 15s - Namespace string `json:",omitempty"` // Optional, defaults to API client config, namespace of ACL token, or "default" namespace -} - -// LockKey returns a handle to a lock struct which can be used -// to acquire and release the mutex. The key used must have -// write permissions. -func (c *Client) LockKey(key string) (*Lock, error) { - opts := &LockOptions{ - Key: key, - } - return c.LockOpts(opts) -} - -// LockOpts returns a handle to a lock struct which can be used -// to acquire and release the mutex. The key used must have -// write permissions. -func (c *Client) LockOpts(opts *LockOptions) (*Lock, error) { - if opts.Key == "" { - return nil, fmt.Errorf("missing key") - } - if opts.SessionName == "" { - opts.SessionName = DefaultLockSessionName - } - if opts.SessionTTL == "" { - opts.SessionTTL = DefaultLockSessionTTL - } else { - if _, err := time.ParseDuration(opts.SessionTTL); err != nil { - return nil, fmt.Errorf("invalid SessionTTL: %v", err) - } - } - if opts.MonitorRetryTime == 0 { - opts.MonitorRetryTime = DefaultMonitorRetryTime - } - if opts.LockWaitTime == 0 { - opts.LockWaitTime = DefaultLockWaitTime - } - l := &Lock{ - c: c, - opts: opts, - } - return l, nil -} - -// Lock attempts to acquire the lock and blocks while doing so. -// Providing a non-nil stopCh can be used to abort the lock attempt. -// Returns a channel that is closed if our lock is lost or an error. -// This channel could be closed at any time due to session invalidation, -// communication errors, operator intervention, etc. It is NOT safe to -// assume that the lock is held until Unlock() unless the Session is specifically -// created without any associated health checks. By default Consul sessions -// prefer liveness over safety and an application must be able to handle -// the lock being lost. -func (l *Lock) Lock(stopCh <-chan struct{}) (<-chan struct{}, error) { - // Hold the lock as we try to acquire - l.l.Lock() - defer l.l.Unlock() - - // Check if we already hold the lock - if l.isHeld { - return nil, ErrLockHeld - } - - wOpts := WriteOptions{ - Namespace: l.opts.Namespace, - } - - // Check if we need to create a session first - l.lockSession = l.opts.Session - if l.lockSession == "" { - s, err := l.createSession() - if err != nil { - return nil, fmt.Errorf("failed to create session: %v", err) - } - - l.sessionRenew = make(chan struct{}) - l.lockSession = s - - session := l.c.Session() - go session.RenewPeriodic(l.opts.SessionTTL, s, &wOpts, l.sessionRenew) - - // If we fail to acquire the lock, cleanup the session - defer func() { - if !l.isHeld { - close(l.sessionRenew) - l.sessionRenew = nil - } - }() - } - - // Setup the query options - kv := l.c.KV() - qOpts := QueryOptions{ - WaitTime: l.opts.LockWaitTime, - Namespace: l.opts.Namespace, - } - - start := time.Now() - attempts := 0 -WAIT: - // Check if we should quit - select { - case <-stopCh: - return nil, nil - default: - } - - // Handle the one-shot mode. - if l.opts.LockTryOnce && attempts > 0 { - elapsed := time.Since(start) - if elapsed > l.opts.LockWaitTime { - return nil, nil - } - - // Query wait time should not exceed the lock wait time - qOpts.WaitTime = l.opts.LockWaitTime - elapsed - } - attempts++ - - // Look for an existing lock, blocking until not taken - pair, meta, err := kv.Get(l.opts.Key, &qOpts) - if err != nil { - return nil, fmt.Errorf("failed to read lock: %v", err) - } - if pair != nil && pair.Flags != LockFlagValue { - return nil, ErrLockConflict - } - locked := false - if pair != nil && pair.Session == l.lockSession { - goto HELD - } - if pair != nil && pair.Session != "" { - qOpts.WaitIndex = meta.LastIndex - goto WAIT - } - - // Try to acquire the lock - pair = l.lockEntry(l.lockSession) - - locked, _, err = kv.Acquire(pair, &wOpts) - if err != nil { - return nil, fmt.Errorf("failed to acquire lock: %v", err) - } - - // Handle the case of not getting the lock - if !locked { - // Determine why the lock failed - qOpts.WaitIndex = 0 - pair, meta, err = kv.Get(l.opts.Key, &qOpts) - if err != nil { - return nil, err - } - if pair != nil && pair.Session != "" { - //If the session is not null, this means that a wait can safely happen - //using a long poll - qOpts.WaitIndex = meta.LastIndex - goto WAIT - } else { - // If the session is empty and the lock failed to acquire, then it means - // a lock-delay is in effect and a timed wait must be used - select { - case <-time.After(DefaultLockRetryTime): - goto WAIT - case <-stopCh: - return nil, nil - } - } - } - -HELD: - // Watch to ensure we maintain leadership - leaderCh := make(chan struct{}) - go l.monitorLock(l.lockSession, leaderCh) - - // Set that we own the lock - l.isHeld = true - - // Locked! All done - return leaderCh, nil -} - -// Unlock released the lock. It is an error to call this -// if the lock is not currently held. -func (l *Lock) Unlock() error { - // Hold the lock as we try to release - l.l.Lock() - defer l.l.Unlock() - - // Ensure the lock is actually held - if !l.isHeld { - return ErrLockNotHeld - } - - // Set that we no longer own the lock - l.isHeld = false - - // Stop the session renew - if l.sessionRenew != nil { - defer func() { - close(l.sessionRenew) - l.sessionRenew = nil - }() - } - - // Get the lock entry, and clear the lock session - lockEnt := l.lockEntry(l.lockSession) - l.lockSession = "" - - // Release the lock explicitly - kv := l.c.KV() - w := WriteOptions{Namespace: l.opts.Namespace} - - _, _, err := kv.Release(lockEnt, &w) - if err != nil { - return fmt.Errorf("failed to release lock: %v", err) - } - return nil -} - -// Destroy is used to cleanup the lock entry. It is not necessary -// to invoke. It will fail if the lock is in use. -func (l *Lock) Destroy() error { - // Hold the lock as we try to release - l.l.Lock() - defer l.l.Unlock() - - // Check if we already hold the lock - if l.isHeld { - return ErrLockHeld - } - - // Look for an existing lock - kv := l.c.KV() - q := QueryOptions{Namespace: l.opts.Namespace} - - pair, _, err := kv.Get(l.opts.Key, &q) - if err != nil { - return fmt.Errorf("failed to read lock: %v", err) - } - - // Nothing to do if the lock does not exist - if pair == nil { - return nil - } - - // Check for possible flag conflict - if pair.Flags != LockFlagValue { - return ErrLockConflict - } - - // Check if it is in use - if pair.Session != "" { - return ErrLockInUse - } - - // Attempt the delete - w := WriteOptions{Namespace: l.opts.Namespace} - didRemove, _, err := kv.DeleteCAS(pair, &w) - if err != nil { - return fmt.Errorf("failed to remove lock: %v", err) - } - if !didRemove { - return ErrLockInUse - } - return nil -} - -// createSession is used to create a new managed session -func (l *Lock) createSession() (string, error) { - session := l.c.Session() - se := l.opts.SessionOpts - if se == nil { - se = &SessionEntry{ - Name: l.opts.SessionName, - TTL: l.opts.SessionTTL, - LockDelay: l.opts.LockDelay, - } - } - w := WriteOptions{Namespace: l.opts.Namespace} - id, _, err := session.Create(se, &w) - if err != nil { - return "", err - } - return id, nil -} - -// lockEntry returns a formatted KVPair for the lock -func (l *Lock) lockEntry(session string) *KVPair { - return &KVPair{ - Key: l.opts.Key, - Value: l.opts.Value, - Session: session, - Flags: LockFlagValue, - } -} - -// monitorLock is a long running routine to monitor a lock ownership -// It closes the stopCh if we lose our leadership. -func (l *Lock) monitorLock(session string, stopCh chan struct{}) { - defer close(stopCh) - kv := l.c.KV() - opts := QueryOptions{ - RequireConsistent: true, - Namespace: l.opts.Namespace, - } -WAIT: - retries := l.opts.MonitorRetries -RETRY: - pair, meta, err := kv.Get(l.opts.Key, &opts) - if err != nil { - // If configured we can try to ride out a brief Consul unavailability - // by doing retries. Note that we have to attempt the retry in a non- - // blocking fashion so that we have a clean place to reset the retry - // counter if service is restored. - if retries > 0 && IsRetryableError(err) { - time.Sleep(l.opts.MonitorRetryTime) - retries-- - opts.WaitIndex = 0 - goto RETRY - } - return - } - if pair != nil && pair.Session == session { - opts.WaitIndex = meta.LastIndex - goto WAIT - } -} diff --git a/vendor/github.com/hashicorp/consul/api/namespace.go b/vendor/github.com/hashicorp/consul/api/namespace.go deleted file mode 100644 index 98afd229989d9..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/namespace.go +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "encoding/json" - "fmt" - "time" -) - -// Namespace is the configuration of a single namespace. Namespacing is a Consul Enterprise feature. -type Namespace struct { - // Name is the name of the Namespace. It must be unique and - // must be a DNS hostname. There are also other reserved names - // that may not be used. - Name string `json:"Name"` - - // Description is where the user puts any information they want - // about the namespace. It is not used internally. - Description string `json:"Description,omitempty"` - - // ACLs is the configuration of ACLs for this namespace. It has its - // own struct so that we can add more to it in the future. - // This is nullable so that we can omit if empty when encoding in JSON - ACLs *NamespaceACLConfig `json:"ACLs,omitempty"` - - // Meta is a map that can be used to add kv metadata to the namespace definition - Meta map[string]string `json:"Meta,omitempty"` - - // DeletedAt is the time when the Namespace was marked for deletion - // This is nullable so that we can omit if empty when encoding in JSON - DeletedAt *time.Time `json:"DeletedAt,omitempty" alias:"deleted_at"` - - // Partition which contains the Namespace. - Partition string `json:"Partition,omitempty"` - - // CreateIndex is the Raft index at which the Namespace was created - CreateIndex uint64 `json:"CreateIndex,omitempty"` - - // ModifyIndex is the latest Raft index at which the Namespace was modified. - ModifyIndex uint64 `json:"ModifyIndex,omitempty"` -} - -func (n *Namespace) UnmarshalJSON(data []byte) error { - type Alias Namespace - aux := struct { - DeletedAtSnake *time.Time `json:"deleted_at"` - *Alias - }{ - Alias: (*Alias)(n), - } - if err := json.Unmarshal(data, &aux); err != nil { - return err - } - - if n.DeletedAt == nil && aux.DeletedAtSnake != nil { - n.DeletedAt = aux.DeletedAtSnake - } - - return nil -} - -// NamespaceACLConfig is the Namespace specific ACL configuration container -type NamespaceACLConfig struct { - // PolicyDefaults is the list of policies that should be used for the parent authorizer - // of all tokens in the associated namespace. - PolicyDefaults []ACLLink `json:"PolicyDefaults" alias:"policy_defaults"` - // RoleDefaults is the list of roles that should be used for the parent authorizer - // of all tokens in the associated namespace. - RoleDefaults []ACLLink `json:"RoleDefaults" alias:"role_defaults"` -} - -func (n *NamespaceACLConfig) UnmarshalJSON(data []byte) error { - type Alias NamespaceACLConfig - aux := struct { - PolicyDefaultsSnake []ACLLink `json:"policy_defaults"` - RoleDefaultsSnake []ACLLink `json:"role_defaults"` - *Alias - }{ - Alias: (*Alias)(n), - } - if err := json.Unmarshal(data, &aux); err != nil { - return err - } - - if n.PolicyDefaults == nil { - for _, pd := range aux.PolicyDefaultsSnake { - n.PolicyDefaults = append(n.PolicyDefaults, pd) - } - } - if n.RoleDefaults == nil { - for _, pd := range aux.RoleDefaultsSnake { - n.RoleDefaults = append(n.RoleDefaults, pd) - } - } - return nil -} - -// Namespaces can be used to manage Namespaces in Consul Enterprise.. -type Namespaces struct { - c *Client -} - -// Namespaces returns a handle to the namespaces endpoints. -func (c *Client) Namespaces() *Namespaces { - return &Namespaces{c} -} - -func (n *Namespaces) Create(ns *Namespace, q *WriteOptions) (*Namespace, *WriteMeta, error) { - if ns.Name == "" { - return nil, nil, fmt.Errorf("Must specify a Name for Namespace creation") - } - - r := n.c.newRequest("PUT", "/v1/namespace") - r.setWriteOptions(q) - r.obj = ns - rtt, resp, err := n.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - var out Namespace - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -func (n *Namespaces) Update(ns *Namespace, q *WriteOptions) (*Namespace, *WriteMeta, error) { - if ns.Name == "" { - return nil, nil, fmt.Errorf("Must specify a Name for Namespace updating") - } - - r := n.c.newRequest("PUT", "/v1/namespace/"+ns.Name) - r.setWriteOptions(q) - r.obj = ns - rtt, resp, err := n.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - var out Namespace - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -func (n *Namespaces) Read(name string, q *QueryOptions) (*Namespace, *QueryMeta, error) { - var out Namespace - r := n.c.newRequest("GET", "/v1/namespace/"+name) - r.setQueryOptions(q) - rtt, resp, err := n.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - found, resp, err := requireNotFoundOrOK(resp) - if err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if !found { - return nil, qm, nil - } - - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return &out, qm, nil -} - -func (n *Namespaces) Delete(name string, q *WriteOptions) (*WriteMeta, error) { - r := n.c.newRequest("DELETE", "/v1/namespace/"+name) - r.setWriteOptions(q) - rtt, resp, err := n.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - return wm, nil -} - -func (n *Namespaces) List(q *QueryOptions) ([]*Namespace, *QueryMeta, error) { - var out []*Namespace - r := n.c.newRequest("GET", "/v1/namespaces") - r.setQueryOptions(q) - rtt, resp, err := n.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/operator.go b/vendor/github.com/hashicorp/consul/api/operator.go deleted file mode 100644 index 667dcd872337d..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/operator.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -// Operator can be used to perform low-level operator tasks for Consul. -type Operator struct { - c *Client -} - -// Operator returns a handle to the operator endpoints. -func (c *Client) Operator() *Operator { - return &Operator{c} -} diff --git a/vendor/github.com/hashicorp/consul/api/operator_area.go b/vendor/github.com/hashicorp/consul/api/operator_area.go deleted file mode 100644 index 9228d89b47c08..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/operator_area.go +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -// The /v1/operator/area endpoints are available only in Consul Enterprise and -// interact with its network area subsystem. Network areas are used to link -// together Consul servers in different Consul datacenters. With network areas, -// Consul datacenters can be linked together in ways other than a fully-connected -// mesh, as is required for Consul's WAN. - -import ( - "net" - "time" -) - -// Area defines a network area. -type Area struct { - // ID is this identifier for an area (a UUID). This must be left empty - // when creating a new area. - ID string - - // PeerDatacenter is the peer Consul datacenter that will make up the - // other side of this network area. Network areas always involve a pair - // of datacenters: the datacenter where the area was created, and the - // peer datacenter. This is required. - PeerDatacenter string - - // RetryJoin specifies the address of Consul servers to join to, such as - // an IPs or hostnames with an optional port number. This is optional. - RetryJoin []string - - // UseTLS specifies whether gossip over this area should be encrypted with TLS - // if possible. - UseTLS bool -} - -// AreaJoinResponse is returned when a join occurs and gives the result for each -// address. -type AreaJoinResponse struct { - // The address that was joined. - Address string - - // Whether or not the join was a success. - Joined bool - - // If we couldn't join, this is the message with information. - Error string -} - -// SerfMember is a generic structure for reporting information about members in -// a Serf cluster. This is only used by the area endpoints right now, but this -// could be expanded to other endpoints in the future. -type SerfMember struct { - // ID is the node identifier (a UUID). - ID string - - // Name is the node name. - Name string - - // Addr has the IP address. - Addr net.IP - - // Port is the RPC port. - Port uint16 - - // Datacenter is the DC name. - Datacenter string - - // Role is "client", "server", or "unknown". - Role string - - // Build has the version of the Consul agent. - Build string - - // Protocol is the protocol of the Consul agent. - Protocol int - - // Status is the Serf health status "none", "alive", "leaving", "left", - // or "failed". - Status string - - // RTT is the estimated round trip time from the server handling the - // request to the this member. This will be negative if no RTT estimate - // is available. - RTT time.Duration -} - -// AreaCreate will create a new network area. The ID in the given structure must -// be empty and a generated ID will be returned on success. -func (op *Operator) AreaCreate(area *Area, q *WriteOptions) (string, *WriteMeta, error) { - r := op.c.newRequest("POST", "/v1/operator/area") - r.setWriteOptions(q) - r.obj = area - rtt, resp, err := op.c.doRequest(r) - if err != nil { - return "", nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return "", nil, err - } - - wm := &WriteMeta{} - wm.RequestTime = rtt - - var out struct{ ID string } - if err := decodeBody(resp, &out); err != nil { - return "", nil, err - } - return out.ID, wm, nil -} - -// AreaUpdate will update the configuration of the network area with the given ID. -func (op *Operator) AreaUpdate(areaID string, area *Area, q *WriteOptions) (string, *WriteMeta, error) { - r := op.c.newRequest("PUT", "/v1/operator/area/"+areaID) - r.setWriteOptions(q) - r.obj = area - rtt, resp, err := op.c.doRequest(r) - if err != nil { - return "", nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return "", nil, err - } - - wm := &WriteMeta{} - wm.RequestTime = rtt - - var out struct{ ID string } - if err := decodeBody(resp, &out); err != nil { - return "", nil, err - } - return out.ID, wm, nil -} - -// AreaGet returns a single network area. -func (op *Operator) AreaGet(areaID string, q *QueryOptions) ([]*Area, *QueryMeta, error) { - var out []*Area - qm, err := op.c.query("/v1/operator/area/"+areaID, &out, q) - if err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// AreaList returns all the available network areas. -func (op *Operator) AreaList(q *QueryOptions) ([]*Area, *QueryMeta, error) { - var out []*Area - qm, err := op.c.query("/v1/operator/area", &out, q) - if err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// AreaDelete deletes the given network area. -func (op *Operator) AreaDelete(areaID string, q *WriteOptions) (*WriteMeta, error) { - r := op.c.newRequest("DELETE", "/v1/operator/area/"+areaID) - r.setWriteOptions(q) - rtt, resp, err := op.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{} - wm.RequestTime = rtt - return wm, nil -} - -// AreaJoin attempts to join the given set of join addresses to the given -// network area. See the Area structure for details about join addresses. -func (op *Operator) AreaJoin(areaID string, addresses []string, q *WriteOptions) ([]*AreaJoinResponse, *WriteMeta, error) { - r := op.c.newRequest("PUT", "/v1/operator/area/"+areaID+"/join") - r.setWriteOptions(q) - r.obj = addresses - rtt, resp, err := op.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - wm := &WriteMeta{} - wm.RequestTime = rtt - - var out []*AreaJoinResponse - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, wm, nil -} - -// AreaMembers lists the Serf information about the members in the given area. -func (op *Operator) AreaMembers(areaID string, q *QueryOptions) ([]*SerfMember, *QueryMeta, error) { - var out []*SerfMember - qm, err := op.c.query("/v1/operator/area/"+areaID+"/members", &out, q) - if err != nil { - return nil, nil, err - } - return out, qm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/operator_audit.go b/vendor/github.com/hashicorp/consul/api/operator_audit.go deleted file mode 100644 index 5240d38a70d77..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/operator_audit.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// The /v1/operator/audit-hash endpoint is available only in Consul Enterprise and -// interact with its audit logging subsystem. - -package api - -type AuditHashRequest struct { - Input string -} - -type AuditHashResponse struct { - Hash string -} - -func (op *Operator) AuditHash(a *AuditHashRequest, q *QueryOptions) (*AuditHashResponse, error) { - r := op.c.newRequest("POST", "/v1/operator/audit-hash") - r.setQueryOptions(q) - r.obj = a - - rtt, resp, err := op.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{} - wm.RequestTime = rtt - - var out AuditHashResponse - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - - return &out, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/operator_autopilot.go b/vendor/github.com/hashicorp/consul/api/operator_autopilot.go deleted file mode 100644 index 7628bf6f2fff7..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/operator_autopilot.go +++ /dev/null @@ -1,404 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "bytes" - "fmt" - "io" - "strconv" - "strings" - "time" -) - -// AutopilotConfiguration is used for querying/setting the Autopilot configuration. -// Autopilot helps manage operator tasks related to Consul servers like removing -// failed servers from the Raft quorum. -type AutopilotConfiguration struct { - // CleanupDeadServers controls whether to remove dead servers from the Raft - // peer list when a new server joins - CleanupDeadServers bool - - // LastContactThreshold is the limit on the amount of time a server can go - // without leader contact before being considered unhealthy. - LastContactThreshold *ReadableDuration - - // MaxTrailingLogs is the amount of entries in the Raft Log that a server can - // be behind before being considered unhealthy. - MaxTrailingLogs uint64 - - // MinQuorum sets the minimum number of servers allowed in a cluster before - // autopilot can prune dead servers. - MinQuorum uint - - // ServerStabilizationTime is the minimum amount of time a server must be - // in a stable, healthy state before it can be added to the cluster. Only - // applicable with Raft protocol version 3 or higher. - ServerStabilizationTime *ReadableDuration - - // (Enterprise-only) RedundancyZoneTag is the node tag to use for separating - // servers into zones for redundancy. If left blank, this feature will be disabled. - RedundancyZoneTag string - - // (Enterprise-only) DisableUpgradeMigration will disable Autopilot's upgrade migration - // strategy of waiting until enough newer-versioned servers have been added to the - // cluster before promoting them to voters. - DisableUpgradeMigration bool - - // (Enterprise-only) UpgradeVersionTag is the node tag to use for version info when - // performing upgrade migrations. If left blank, the Consul version will be used. - UpgradeVersionTag string - - // CreateIndex holds the index corresponding the creation of this configuration. - // This is a read-only field. - CreateIndex uint64 - - // ModifyIndex will be set to the index of the last update when retrieving the - // Autopilot configuration. Resubmitting a configuration with - // AutopilotCASConfiguration will perform a check-and-set operation which ensures - // there hasn't been a subsequent update since the configuration was retrieved. - ModifyIndex uint64 -} - -// Defines default values for the AutopilotConfiguration type, consistent with -// https://www.consul.io/api-docs/operator/autopilot#parameters-1 -func NewAutopilotConfiguration() AutopilotConfiguration { - cfg := AutopilotConfiguration{ - CleanupDeadServers: true, - LastContactThreshold: NewReadableDuration(200 * time.Millisecond), - MaxTrailingLogs: 250, - MinQuorum: 0, - ServerStabilizationTime: NewReadableDuration(10 * time.Second), - RedundancyZoneTag: "", - DisableUpgradeMigration: false, - UpgradeVersionTag: "", - } - - return cfg -} - -// ServerHealth is the health (from the leader's point of view) of a server. -type ServerHealth struct { - // ID is the raft ID of the server. - ID string - - // Name is the node name of the server. - Name string - - // Address is the address of the server. - Address string - - // The status of the SerfHealth check for the server. - SerfStatus string - - // Version is the Consul version of the server. - Version string - - // Leader is whether this server is currently the leader. - Leader bool - - // LastContact is the time since this node's last contact with the leader. - LastContact *ReadableDuration - - // LastTerm is the highest leader term this server has a record of in its Raft log. - LastTerm uint64 - - // LastIndex is the last log index this server has a record of in its Raft log. - LastIndex uint64 - - // Healthy is whether or not the server is healthy according to the current - // Autopilot config. - Healthy bool - - // Voter is whether this is a voting server. - Voter bool - - // StableSince is the last time this server's Healthy value changed. - StableSince time.Time -} - -// OperatorHealthReply is a representation of the overall health of the cluster -type OperatorHealthReply struct { - // Healthy is true if all the servers in the cluster are healthy. - Healthy bool - - // FailureTolerance is the number of healthy servers that could be lost without - // an outage occurring. - FailureTolerance int - - // Servers holds the health of each server. - Servers []ServerHealth -} - -type AutopilotState struct { - Healthy bool - FailureTolerance int - OptimisticFailureTolerance int - - Servers map[string]AutopilotServer - Leader string - Voters []string - ReadReplicas []string `json:",omitempty"` - RedundancyZones map[string]AutopilotZone `json:",omitempty"` - Upgrade *AutopilotUpgrade `json:",omitempty"` -} - -type AutopilotServer struct { - ID string - Name string - Address string - NodeStatus string - Version string - LastContact *ReadableDuration - LastTerm uint64 - LastIndex uint64 - Healthy bool - StableSince time.Time - RedundancyZone string `json:",omitempty"` - UpgradeVersion string `json:",omitempty"` - ReadReplica bool - Status AutopilotServerStatus - Meta map[string]string - NodeType AutopilotServerType -} - -type AutopilotServerStatus string - -const ( - AutopilotServerNone AutopilotServerStatus = "none" - AutopilotServerLeader AutopilotServerStatus = "leader" - AutopilotServerVoter AutopilotServerStatus = "voter" - AutopilotServerNonVoter AutopilotServerStatus = "non-voter" - AutopilotServerStaging AutopilotServerStatus = "staging" -) - -type AutopilotServerType string - -const ( - AutopilotTypeVoter AutopilotServerType = "voter" - AutopilotTypeReadReplica AutopilotServerType = "read-replica" - AutopilotTypeZoneVoter AutopilotServerType = "zone-voter" - AutopilotTypeZoneExtraVoter AutopilotServerType = "zone-extra-voter" - AutopilotTypeZoneStandby AutopilotServerType = "zone-standby" -) - -type AutopilotZone struct { - Servers []string - Voters []string - FailureTolerance int -} - -type AutopilotZoneUpgradeVersions struct { - TargetVersionVoters []string `json:",omitempty"` - TargetVersionNonVoters []string `json:",omitempty"` - OtherVersionVoters []string `json:",omitempty"` - OtherVersionNonVoters []string `json:",omitempty"` -} - -type AutopilotUpgrade struct { - Status AutopilotUpgradeStatus - TargetVersion string `json:",omitempty"` - TargetVersionVoters []string `json:",omitempty"` - TargetVersionNonVoters []string `json:",omitempty"` - TargetVersionReadReplicas []string `json:",omitempty"` - OtherVersionVoters []string `json:",omitempty"` - OtherVersionNonVoters []string `json:",omitempty"` - OtherVersionReadReplicas []string `json:",omitempty"` - RedundancyZones map[string]AutopilotZoneUpgradeVersions `json:",omitempty"` -} - -type AutopilotUpgradeStatus string - -const ( - // AutopilotUpgradeIdle is the status when no upgrade is in progress. - AutopilotUpgradeIdle AutopilotUpgradeStatus = "idle" - - // AutopilotUpgradeAwaitNewVoters is the status when more servers of - // the target version must be added in order to start the promotion - // phase of the upgrade - AutopilotUpgradeAwaitNewVoters AutopilotUpgradeStatus = "await-new-voters" - - // AutopilotUpgradePromoting is the status when autopilot is promoting - // servers of the target version. - AutopilotUpgradePromoting AutopilotUpgradeStatus = "promoting" - - // AutopilotUpgradeDemoting is the status when autopilot is demoting - // servers not on the target version - AutopilotUpgradeDemoting AutopilotUpgradeStatus = "demoting" - - // AutopilotUpgradeLeaderTransfer is the status when autopilot is transferring - // leadership from a server running an older version to a server - // using the target version. - AutopilotUpgradeLeaderTransfer AutopilotUpgradeStatus = "leader-transfer" - - // AutopilotUpgradeAwaitNewServers is the status when autpilot has finished - // transferring leadership and has demoted all the other versioned - // servers but wants to indicate that more target version servers - // are needed to replace all the existing other version servers. - AutopilotUpgradeAwaitNewServers AutopilotUpgradeStatus = "await-new-servers" - - // AutopilotUpgradeAwaitServerRemoval is the status when autopilot is waiting - // for the servers on non-target versions to be removed - AutopilotUpgradeAwaitServerRemoval AutopilotUpgradeStatus = "await-server-removal" - - // AutopilotUpgradeDisabled is the status when automated ugprades are - // disabled in the autopilot configuration - AutopilotUpgradeDisabled AutopilotUpgradeStatus = "disabled" -) - -// ReadableDuration is a duration type that is serialized to JSON in human readable format. -type ReadableDuration time.Duration - -func NewReadableDuration(dur time.Duration) *ReadableDuration { - d := ReadableDuration(dur) - return &d -} - -func (d *ReadableDuration) String() string { - return d.Duration().String() -} - -func (d *ReadableDuration) Duration() time.Duration { - if d == nil { - return time.Duration(0) - } - return time.Duration(*d) -} - -func (d *ReadableDuration) MarshalJSON() ([]byte, error) { - return []byte(fmt.Sprintf(`"%s"`, d.Duration().String())), nil -} - -func (d *ReadableDuration) UnmarshalJSON(raw []byte) (err error) { - if d == nil { - return fmt.Errorf("cannot unmarshal to nil pointer") - } - - var dur time.Duration - str := string(raw) - if len(str) >= 2 && str[0] == '"' && str[len(str)-1] == '"' { - // quoted string - dur, err = time.ParseDuration(str[1 : len(str)-1]) - if err != nil { - return err - } - } else { - // no quotes, not a string - v, err := strconv.ParseFloat(str, 64) - if err != nil { - return err - } - dur = time.Duration(v) - } - - *d = ReadableDuration(dur) - return nil -} - -// AutopilotGetConfiguration is used to query the current Autopilot configuration. -func (op *Operator) AutopilotGetConfiguration(q *QueryOptions) (*AutopilotConfiguration, error) { - r := op.c.newRequest("GET", "/v1/operator/autopilot/configuration") - r.setQueryOptions(q) - _, resp, err := op.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - var out AutopilotConfiguration - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - - return &out, nil -} - -// AutopilotSetConfiguration is used to set the current Autopilot configuration. -func (op *Operator) AutopilotSetConfiguration(conf *AutopilotConfiguration, q *WriteOptions) error { - r := op.c.newRequest("PUT", "/v1/operator/autopilot/configuration") - r.setWriteOptions(q) - r.obj = conf - _, resp, err := op.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// AutopilotCASConfiguration is used to perform a Check-And-Set update on the -// Autopilot configuration. The ModifyIndex value will be respected. Returns -// true on success or false on failures. -func (op *Operator) AutopilotCASConfiguration(conf *AutopilotConfiguration, q *WriteOptions) (bool, error) { - r := op.c.newRequest("PUT", "/v1/operator/autopilot/configuration") - r.setWriteOptions(q) - r.params.Set("cas", strconv.FormatUint(conf.ModifyIndex, 10)) - r.obj = conf - _, resp, err := op.c.doRequest(r) - if err != nil { - return false, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return false, err - } - - var buf bytes.Buffer - if _, err := io.Copy(&buf, resp.Body); err != nil { - return false, fmt.Errorf("Failed to read response: %v", err) - } - res := strings.Contains(buf.String(), "true") - - return res, nil -} - -// AutopilotServerHealth -func (op *Operator) AutopilotServerHealth(q *QueryOptions) (*OperatorHealthReply, error) { - r := op.c.newRequest("GET", "/v1/operator/autopilot/health") - r.setQueryOptions(q) - - // we use 429 status to indicate unhealthiness - _, resp, err := op.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - err = requireHttpCodes(resp, 200, 429) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - - var out OperatorHealthReply - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - return &out, nil -} - -func (op *Operator) AutopilotState(q *QueryOptions) (*AutopilotState, error) { - r := op.c.newRequest("GET", "/v1/operator/autopilot/state") - r.setQueryOptions(q) - _, resp, err := op.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - var out AutopilotState - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - - return &out, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/operator_keyring.go b/vendor/github.com/hashicorp/consul/api/operator_keyring.go deleted file mode 100644 index aefec9e2704e4..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/operator_keyring.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -// keyringRequest is used for performing Keyring operations -type keyringRequest struct { - Key string -} - -// KeyringResponse is returned when listing the gossip encryption keys -type KeyringResponse struct { - // Whether this response is for a WAN ring - WAN bool - - // The datacenter name this request corresponds to - Datacenter string - - // Segment has the network segment this request corresponds to. - Segment string - - // Partition has the admin partition this request corresponds to. - Partition string `json:",omitempty"` - - // Messages has information or errors from serf - Messages map[string]string `json:",omitempty"` - - // A map of the encryption keys to the number of nodes they're installed on - Keys map[string]int - - // A map of the encryption primary keys to the number of nodes they're installed on - PrimaryKeys map[string]int - - // The total number of nodes in this ring - NumNodes int -} - -// KeyringInstall is used to install a new gossip encryption key into the cluster -func (op *Operator) KeyringInstall(key string, q *WriteOptions) error { - r := op.c.newRequest("POST", "/v1/operator/keyring") - r.setWriteOptions(q) - r.obj = keyringRequest{ - Key: key, - } - _, resp, err := op.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// KeyringList is used to list the gossip keys installed in the cluster -func (op *Operator) KeyringList(q *QueryOptions) ([]*KeyringResponse, error) { - r := op.c.newRequest("GET", "/v1/operator/keyring") - r.setQueryOptions(q) - _, resp, err := op.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - var out []*KeyringResponse - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - return out, nil -} - -// KeyringRemove is used to remove a gossip encryption key from the cluster -func (op *Operator) KeyringRemove(key string, q *WriteOptions) error { - r := op.c.newRequest("DELETE", "/v1/operator/keyring") - r.setWriteOptions(q) - r.obj = keyringRequest{ - Key: key, - } - _, resp, err := op.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// KeyringUse is used to change the active gossip encryption key -func (op *Operator) KeyringUse(key string, q *WriteOptions) error { - r := op.c.newRequest("PUT", "/v1/operator/keyring") - r.setWriteOptions(q) - r.obj = keyringRequest{ - Key: key, - } - _, resp, err := op.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/hashicorp/consul/api/operator_license.go b/vendor/github.com/hashicorp/consul/api/operator_license.go deleted file mode 100644 index 1e3496da0e1ae..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/operator_license.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "io" - "strings" - "time" -) - -type License struct { - // The unique identifier of the license - LicenseID string `json:"license_id"` - - // The customer ID associated with the license - CustomerID string `json:"customer_id"` - - // If set, an identifier that should be used to lock the license to a - // particular site, cluster, etc. - InstallationID string `json:"installation_id"` - - // The time at which the license was issued - IssueTime time.Time `json:"issue_time"` - - // The time at which the license starts being valid - StartTime time.Time `json:"start_time"` - - // The time after which the license expires - ExpirationTime time.Time `json:"expiration_time"` - - // The time at which the license ceases to function and can - // no longer be used in any capacity - TerminationTime time.Time `json:"termination_time"` - - // Whether the license will ignore termination - IgnoreTermination bool `json:"ignore_termination"` - - // The product the license is valid for - Product string `json:"product"` - - // License Specific Flags - Flags map[string]interface{} `json:"flags"` - - // Modules is a list of the licensed enterprise modules - Modules []string `json:"modules"` - - // List of features enabled by the license - Features []string `json:"features"` -} - -type LicenseReply struct { - Valid bool - License *License - Warnings []string -} - -func (op *Operator) LicenseGet(q *QueryOptions) (*LicenseReply, error) { - var reply LicenseReply - if _, err := op.c.query("/v1/operator/license", &reply, q); err != nil { - return nil, err - } else { - return &reply, nil - } -} - -func (op *Operator) LicenseGetSigned(q *QueryOptions) (string, error) { - r := op.c.newRequest("GET", "/v1/operator/license") - r.params.Set("signed", "1") - r.setQueryOptions(q) - _, resp, err := op.c.doRequest(r) - if err != nil { - return "", err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return "", err - } - - data, err := io.ReadAll(resp.Body) - if err != nil { - return "", err - } - - return string(data), nil -} - -// LicenseReset will reset the license to the builtin one if it is still valid. -// If the builtin license is invalid, the current license stays active. -// -// DEPRECATED: Consul 1.10 removes the corresponding HTTP endpoint as licenses -// are now set via agent configuration instead of through the API -func (op *Operator) LicenseReset(opts *WriteOptions) (*LicenseReply, error) { - var reply LicenseReply - r := op.c.newRequest("DELETE", "/v1/operator/license") - r.setWriteOptions(opts) - _, resp, err := op.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - if err := decodeBody(resp, &reply); err != nil { - return nil, err - } - return &reply, nil -} - -// LicensePut will configure the Consul Enterprise license for the target datacenter -// -// DEPRECATED: Consul 1.10 removes the corresponding HTTP endpoint as licenses -// are now set via agent configuration instead of through the API -func (op *Operator) LicensePut(license string, opts *WriteOptions) (*LicenseReply, error) { - var reply LicenseReply - r := op.c.newRequest("PUT", "/v1/operator/license") - r.setWriteOptions(opts) - r.body = strings.NewReader(license) - _, resp, err := op.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - if err := decodeBody(resp, &reply); err != nil { - return nil, err - } - - return &reply, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/operator_raft.go b/vendor/github.com/hashicorp/consul/api/operator_raft.go deleted file mode 100644 index f0f5794aa5af0..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/operator_raft.go +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -// RaftServer has information about a server in the Raft configuration. -type RaftServer struct { - // ID is the unique ID for the server. These are currently the same - // as the address, but they will be changed to a real GUID in a future - // release of Consul. - ID string - - // Node is the node name of the server, as known by Consul, or this - // will be set to "(unknown)" otherwise. - Node string - - // Address is the IP:port of the server, used for Raft communications. - Address string - - // Leader is true if this server is the current cluster leader. - Leader bool - - // Protocol version is the raft protocol version used by the server - ProtocolVersion string - - // Voter is true if this server has a vote in the cluster. This might - // be false if the server is staging and still coming online, or if - // it's a non-voting server, which will be added in a future release of - // Consul. - Voter bool - - // LastIndex is the last log index this server has a record of in its Raft log. - LastIndex uint64 -} - -// RaftConfiguration is returned when querying for the current Raft configuration. -type RaftConfiguration struct { - // Servers has the list of servers in the Raft configuration. - Servers []*RaftServer - - // Index has the Raft index of this configuration. - Index uint64 -} - -// TransferLeaderResponse is returned when querying for the current Raft configuration. -type TransferLeaderResponse struct { - Success bool -} - -// RaftGetConfiguration is used to query the current Raft peer set. -func (op *Operator) RaftGetConfiguration(q *QueryOptions) (*RaftConfiguration, error) { - r := op.c.newRequest("GET", "/v1/operator/raft/configuration") - r.setQueryOptions(q) - _, resp, err := op.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - var out RaftConfiguration - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - return &out, nil -} - -// RaftLeaderTransfer is used to transfer the current raft leader to another node -// Optionally accepts a non-empty id of another node to transfer leadership to. -func (op *Operator) RaftLeaderTransfer(id string, q *QueryOptions) (*TransferLeaderResponse, error) { - r := op.c.newRequest("POST", "/v1/operator/raft/transfer-leader") - r.setQueryOptions(q) - - if id != "" { - r.params.Set("id", id) - } - _, resp, err := op.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - var out TransferLeaderResponse - if err := decodeBody(resp, &out); err != nil { - return nil, err - } - return &out, nil -} - -// RaftRemovePeerByAddress is used to kick a stale peer (one that it in the Raft -// quorum but no longer known to Serf or the catalog) by address in the form of -// "IP:port". -func (op *Operator) RaftRemovePeerByAddress(address string, q *WriteOptions) error { - r := op.c.newRequest("DELETE", "/v1/operator/raft/peer") - r.setWriteOptions(q) - - r.params.Set("address", address) - - _, resp, err := op.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} - -// RaftRemovePeerByID is used to kick a stale peer (one that it in the Raft -// quorum but no longer known to Serf or the catalog) by ID. -func (op *Operator) RaftRemovePeerByID(id string, q *WriteOptions) error { - r := op.c.newRequest("DELETE", "/v1/operator/raft/peer") - r.setWriteOptions(q) - - r.params.Set("id", id) - - _, resp, err := op.c.doRequest(r) - if err != nil { - return err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/hashicorp/consul/api/operator_segment.go b/vendor/github.com/hashicorp/consul/api/operator_segment.go deleted file mode 100644 index 6115a7ab4b58e..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/operator_segment.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -// SegmentList returns all the available LAN segments. -func (op *Operator) SegmentList(q *QueryOptions) ([]string, *QueryMeta, error) { - var out []string - qm, err := op.c.query("/v1/operator/segment", &out, q) - if err != nil { - return nil, nil, err - } - return out, qm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/operator_usage.go b/vendor/github.com/hashicorp/consul/api/operator_usage.go deleted file mode 100644 index 8977449ddd361..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/operator_usage.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -type Usage struct { - // Usage is a map of datacenter -> usage information - Usage map[string]ServiceUsage -} - -// ServiceUsage contains information about the number of services and service instances for a datacenter. -type ServiceUsage struct { - Nodes int - Services int - ServiceInstances int - ConnectServiceInstances map[string]int - - // Billable services are of "typical" service kind (i.e. non-connect or connect-native), - // excluding the "consul" service. - BillableServiceInstances int - - // A map of partition+namespace to number of unique services registered in that namespace - PartitionNamespaceServices map[string]map[string]int - - // A map of partition+namespace to number of service instances registered in that namespace - PartitionNamespaceServiceInstances map[string]map[string]int - - // A map of partition+namespace+kind to number of service-mesh instances registered in that namespace - PartitionNamespaceConnectServiceInstances map[string]map[string]map[string]int - - // A map of partition+namespace to number of billable instances registered in that namespace - PartitionNamespaceBillableServiceInstances map[string]map[string]int -} - -// Usage is used to query for usage information in the given datacenter. -func (op *Operator) Usage(q *QueryOptions) (*Usage, *QueryMeta, error) { - r := op.c.newRequest("GET", "/v1/operator/usage") - r.setQueryOptions(q) - rtt, resp, err := op.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out *Usage - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/partition.go b/vendor/github.com/hashicorp/consul/api/partition.go deleted file mode 100644 index 8a9bfb482fcc1..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/partition.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "context" - "fmt" - "time" -) - -// Partition is the configuration of a single admin partition. Admin Partitions are a Consul Enterprise feature. -type Partition struct { - // Name is the name of the Partition. - Name string `json:"Name"` - - // Description is where the user puts any information they want - // about the admin partition. It is not used internally. - Description string `json:"Description,omitempty"` - - // DeletedAt is the time when the Partition was marked for deletion - // This is nullable so that we can omit if empty when encoding in JSON - DeletedAt *time.Time `json:"DeletedAt,omitempty" alias:"deleted_at"` - - // CreateIndex is the Raft index at which the Partition was created - CreateIndex uint64 `json:"CreateIndex,omitempty"` - - // ModifyIndex is the latest Raft index at which the Partition was modified. - ModifyIndex uint64 `json:"ModifyIndex,omitempty"` - - // DisableGossip will not enable a gossip pool for the partition - DisableGossip bool `json:"DisableGossip,omitempty"` -} - -// PartitionDefaultName is the default partition value. -const PartitionDefaultName = "default" - -// Partitions can be used to manage Partitions in Consul Enterprise. -type Partitions struct { - c *Client -} - -// Operator returns a handle to the operator endpoints. -func (c *Client) Partitions() *Partitions { - return &Partitions{c} -} - -func (p *Partitions) Create(ctx context.Context, partition *Partition, q *WriteOptions) (*Partition, *WriteMeta, error) { - if partition.Name == "" { - return nil, nil, fmt.Errorf("Must specify a Name for Partition creation") - } - - r := p.c.newRequest("PUT", "/v1/partition") - r.setWriteOptions(q) - r.ctx = ctx - r.obj = partition - rtt, resp, err := p.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - var out Partition - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -func (p *Partitions) Update(ctx context.Context, partition *Partition, q *WriteOptions) (*Partition, *WriteMeta, error) { - if partition.Name == "" { - return nil, nil, fmt.Errorf("Must specify a Name for Partition updating") - } - - r := p.c.newRequest("PUT", "/v1/partition/"+partition.Name) - r.setWriteOptions(q) - r.ctx = ctx - r.obj = partition - rtt, resp, err := p.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - var out Partition - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -func (p *Partitions) Read(ctx context.Context, name string, q *QueryOptions) (*Partition, *QueryMeta, error) { - var out Partition - r := p.c.newRequest("GET", "/v1/partition/"+name) - r.setQueryOptions(q) - r.ctx = ctx - rtt, resp, err := p.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - found, resp, err := requireNotFoundOrOK(resp) - if err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if !found { - return nil, qm, nil - } - - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return &out, qm, nil -} - -func (p *Partitions) Delete(ctx context.Context, name string, q *WriteOptions) (*WriteMeta, error) { - r := p.c.newRequest("DELETE", "/v1/partition/"+name) - r.setWriteOptions(q) - r.ctx = ctx - rtt, resp, err := p.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - return wm, nil -} - -func (p *Partitions) List(ctx context.Context, q *QueryOptions) ([]*Partition, *QueryMeta, error) { - var out []*Partition - r := p.c.newRequest("GET", "/v1/partitions") - r.setQueryOptions(q) - r.ctx = ctx - rtt, resp, err := p.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - return out, qm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/peering.go b/vendor/github.com/hashicorp/consul/api/peering.go deleted file mode 100644 index dd7780f630a63..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/peering.go +++ /dev/null @@ -1,295 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "context" - "fmt" - "time" -) - -// PeeringState enumerates all the states a peering can be in -type PeeringState string - -const ( - // PeeringStateUndefined represents an unset value for PeeringState during - // writes. - PeeringStateUndefined PeeringState = "UNDEFINED" - - // PeeringStatePending means the peering was created by generating a peering token. - // Peerings stay in a pending state until the peer uses the token to dial - // the local cluster. - PeeringStatePending PeeringState = "PENDING" - - // PeeringStateEstablishing means the peering is being established from a peering token. - // This is the initial state for dialing peers. - PeeringStateEstablishing PeeringState = "ESTABLISHING" - - // PeeringStateActive means that the peering connection is active and - // healthy. - PeeringStateActive PeeringState = "ACTIVE" - - // PeeringStateFailing means the peering connection has been interrupted - // but has not yet been terminated. - PeeringStateFailing PeeringState = "FAILING" - - // PeeringStateDeleting means a peering was marked for deletion and is in the process - // of being deleted. - PeeringStateDeleting PeeringState = "DELETING" - - // PeeringStateTerminated means the peering relationship has been removed. - PeeringStateTerminated PeeringState = "TERMINATED" -) - -type PeeringRemoteInfo struct { - // Partition is the remote peer's partition. - Partition string - // Datacenter is the remote peer's datacenter. - Datacenter string - Locality *Locality `json:",omitempty"` -} - -// Locality identifies where a given entity is running. -type Locality struct { - // Region is region the zone belongs to. - Region string - - // Zone is the zone the entity is running in. - Zone string -} - -type Peering struct { - // ID is a datacenter-scoped UUID for the peering. - ID string - // Name is the local alias for the peering relationship. - Name string - // Partition is the local partition connecting to the peer. - Partition string `json:",omitempty"` - // DeletedAt is the time when the Peering was marked for deletion - DeletedAt *time.Time `json:",omitempty" alias:"deleted_at"` - // Meta is a mapping of some string value to any other string value - Meta map[string]string `json:",omitempty"` - // State is one of the valid PeeringState values to represent the status of - // peering relationship. - State PeeringState - // PeerID is the ID that our peer assigned to this peering. This ID is to - // be used when dialing the peer, so that it can know who dialed it. - PeerID string `json:",omitempty"` - // PeerCAPems contains all the CA certificates for the remote peer. - PeerCAPems []string `json:",omitempty"` - // PeerServerName is the name of the remote server as it relates to TLS. - PeerServerName string `json:",omitempty"` - // PeerServerAddresses contains all the connection addresses for the remote peer. - PeerServerAddresses []string `json:",omitempty"` - // StreamStatus contains information computed on read based on the state of the stream. - StreamStatus PeeringStreamStatus - // CreateIndex is the Raft index at which the Peering was created. - CreateIndex uint64 - // ModifyIndex is the latest Raft index at which the Peering was modified. - ModifyIndex uint64 - // Remote contains metadata for the remote peer. - Remote PeeringRemoteInfo -} - -type PeeringStreamStatus struct { - // ImportedServices is the list of services imported from this peering. - ImportedServices []string - // ExportedServices is the list of services exported to this peering. - ExportedServices []string - // LastHeartbeat represents when the last heartbeat message was received. - LastHeartbeat *time.Time - // LastReceive represents when any message was last received, regardless of success or error. - LastReceive *time.Time - // LastSend represents when any message was last sent, regardless of success or error. - LastSend *time.Time -} - -type PeeringReadResponse struct { - Peering *Peering -} - -type PeeringGenerateTokenRequest struct { - // PeerName is the name of the remote peer. - PeerName string - // Partition to be peered. - Partition string `json:",omitempty"` - // Meta is a mapping of some string value to any other string value - Meta map[string]string `json:",omitempty"` - // ServerExternalAddresses is a list of addresses to put into the generated token. This could be used to specify - // load balancer(s) or external IPs to reach the servers from the dialing side, and will override any server - // addresses obtained from the "consul" service. - ServerExternalAddresses []string `json:",omitempty"` -} - -type PeeringGenerateTokenResponse struct { - // PeeringToken is an opaque string provided to the remote peer for it to complete - // the peering initialization handshake. - PeeringToken string -} - -type PeeringEstablishRequest struct { - // Name of the remote peer. - PeerName string - // The peering token returned from the peer's GenerateToken endpoint. - PeeringToken string `json:",omitempty"` - // Partition to be peered. - Partition string `json:",omitempty"` - // Meta is a mapping of some string value to any other string value - Meta map[string]string `json:",omitempty"` -} - -type PeeringEstablishResponse struct { -} - -type PeeringListRequest struct { - // future proofing in case we extend List functionality -} - -type Peerings struct { - c *Client -} - -// Peerings returns a handle to the operator endpoints. -func (c *Client) Peerings() *Peerings { - return &Peerings{c: c} -} - -func (p *Peerings) Read(ctx context.Context, name string, q *QueryOptions) (*Peering, *QueryMeta, error) { - if name == "" { - return nil, nil, fmt.Errorf("peering name cannot be empty") - } - - req := p.c.newRequest("GET", fmt.Sprintf("/v1/peering/%s", name)) - req.setQueryOptions(q) - req.ctx = ctx - - rtt, resp, err := p.c.doRequest(req) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - found, resp, err := requireNotFoundOrOK(resp) - if err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if !found { - return nil, qm, nil - } - - var out Peering - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, qm, nil -} - -func (p *Peerings) Delete(ctx context.Context, name string, q *WriteOptions) (*WriteMeta, error) { - if name == "" { - return nil, fmt.Errorf("peering name cannot be empty") - } - - req := p.c.newRequest("DELETE", fmt.Sprintf("/v1/peering/%s", name)) - req.setWriteOptions(q) - req.ctx = ctx - - rtt, resp, err := p.c.doRequest(req) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - return wm, nil -} - -// TODO(peering): verify this is the ultimate signature we want -func (p *Peerings) GenerateToken(ctx context.Context, g PeeringGenerateTokenRequest, wq *WriteOptions) (*PeeringGenerateTokenResponse, *WriteMeta, error) { - if g.PeerName == "" { - return nil, nil, fmt.Errorf("peer name cannot be empty") - } - - req := p.c.newRequest("POST", fmt.Sprint("/v1/peering/token")) - req.setWriteOptions(wq) - req.ctx = ctx - req.obj = g - - rtt, resp, err := p.c.doRequest(req) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - - var out PeeringGenerateTokenResponse - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -// TODO(peering): verify this is the ultimate signature we want -func (p *Peerings) Establish(ctx context.Context, i PeeringEstablishRequest, wq *WriteOptions) (*PeeringEstablishResponse, *WriteMeta, error) { - req := p.c.newRequest("POST", fmt.Sprint("/v1/peering/establish")) - req.setWriteOptions(wq) - req.ctx = ctx - req.obj = i - - rtt, resp, err := p.c.doRequest(req) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - wm := &WriteMeta{RequestTime: rtt} - - var out PeeringEstablishResponse - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return &out, wm, nil -} - -func (p *Peerings) List(ctx context.Context, q *QueryOptions) ([]*Peering, *QueryMeta, error) { - req := p.c.newRequest("GET", "/v1/peerings") - req.setQueryOptions(q) - req.ctx = ctx - - rtt, resp, err := p.c.doRequest(req) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - var out []*Peering - if err := decodeBody(resp, &out); err != nil { - return nil, nil, err - } - - return out, qm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/prepared_query.go b/vendor/github.com/hashicorp/consul/api/prepared_query.go deleted file mode 100644 index 8ebc852f3ac5a..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/prepared_query.go +++ /dev/null @@ -1,269 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -// QueryFailoverOptions sets options about how we fail over if there are no -// healthy nodes in the local datacenter. -type QueryFailoverOptions struct { - // NearestN is set to the number of remote datacenters to try, based on - // network coordinates. - NearestN int - - // Datacenters is a fixed list of datacenters to try after NearestN. We - // never try a datacenter multiple times, so those are subtracted from - // this list before proceeding. - Datacenters []string - - // Targets is a fixed list of datacenters and peers to try. This field cannot - // be populated with NearestN or Datacenters. - Targets []QueryFailoverTarget -} - -// Deprecated: use QueryFailoverOptions instead. -type QueryDatacenterOptions = QueryFailoverOptions - -type QueryFailoverTarget struct { - // Peer specifies a peer to try during failover. - Peer string - - // Datacenter specifies a datacenter to try during failover. - Datacenter string - - // Partition specifies a partition to try during failover - // Note: Partition are available only in Consul Enterprise - Partition string `json:",omitempty"` - - // Namespace specifies a namespace to try during failover - // Note: Namespaces are available only in Consul Enterprise - Namespace string `json:",omitempty"` -} - -// QueryDNSOptions controls settings when query results are served over DNS. -type QueryDNSOptions struct { - // TTL is the time to live for the served DNS results. - TTL string -} - -// ServiceQuery is used to query for a set of healthy nodes offering a specific -// service. -type ServiceQuery struct { - // Service is the service to query. - Service string - - // SamenessGroup specifies a sameness group to query. The first member of the Sameness Group will - // be targeted first on PQ execution and subsequent members will be targeted during failover scenarios. - // This field is mutually exclusive with Failover. - SamenessGroup string `json:",omitempty"` - - // Namespace of the service to query - Namespace string `json:",omitempty"` - - // Partition of the service to query - Partition string `json:",omitempty"` - - // Near allows baking in the name of a node to automatically distance- - // sort from. The magic "_agent" value is supported, which sorts near - // the agent which initiated the request by default. - Near string - - // Failover controls what we do if there are no healthy nodes in the - // local datacenter. - Failover QueryFailoverOptions `json:",omitempty"` - - // IgnoreCheckIDs is an optional list of health check IDs to ignore when - // considering which nodes are healthy. It is useful as an emergency measure - // to temporarily override some health check that is producing false negatives - // for example. - IgnoreCheckIDs []string - - // If OnlyPassing is true then we will only include nodes with passing - // health checks (critical AND warning checks will cause a node to be - // discarded) - OnlyPassing bool - - // Tags are a set of required and/or disallowed tags. If a tag is in - // this list it must be present. If the tag is preceded with "!" then - // it is disallowed. - Tags []string - - // NodeMeta is a map of required node metadata fields. If a key/value - // pair is in this map it must be present on the node in order for the - // service entry to be returned. - NodeMeta map[string]string - - // ServiceMeta is a map of required service metadata fields. If a key/value - // pair is in this map it must be present on the node in order for the - // service entry to be returned. - ServiceMeta map[string]string - - // Connect if true will filter the prepared query results to only - // include Connect-capable services. These include both native services - // and proxies for matching services. Note that if a proxy matches, - // the constraints in the query above (Near, OnlyPassing, etc.) apply - // to the _proxy_ and not the service being proxied. In practice, proxies - // should be directly next to their services so this isn't an issue. - Connect bool -} - -// QueryTemplate carries the arguments for creating a templated query. -type QueryTemplate struct { - // Type specifies the type of the query template. Currently only - // "name_prefix_match" is supported. This field is required. - Type string - - // Regexp allows specifying a regex pattern to match against the name - // of the query being executed. - Regexp string - - // RemoveEmptyTags if set to true, will cause the Tags list inside - // the Service structure to be stripped of any empty strings. This is useful - // when interpolating into tags in a way where the tag is optional, and - // where searching for an empty tag would yield no results from the query. - RemoveEmptyTags bool -} - -// PreparedQueryDefinition defines a complete prepared query. -type PreparedQueryDefinition struct { - // ID is this UUID-based ID for the query, always generated by Consul. - ID string - - // Name is an optional friendly name for the query supplied by the - // user. NOTE - if this feature is used then it will reduce the security - // of any read ACL associated with this query/service since this name - // can be used to locate nodes with supplying any ACL. - Name string - - // Session is an optional session to tie this query's lifetime to. If - // this is omitted then the query will not expire. - Session string - - // Token is the ACL token used when the query was created, and it is - // used when a query is subsequently executed. This token, or a token - // with management privileges, must be used to change the query later. - Token string - - // Service defines a service query (leaving things open for other types - // later). - Service ServiceQuery - - // DNS has options that control how the results of this query are - // served over DNS. - DNS QueryDNSOptions - - // Template is used to pass through the arguments for creating a - // prepared query with an attached template. If a template is given, - // interpolations are possible in other struct fields. - Template QueryTemplate -} - -// PreparedQueryExecuteResponse has the results of executing a query. -type PreparedQueryExecuteResponse struct { - // Service is the service that was queried. - Service string - - // Namespace of the service that was queried - Namespace string `json:",omitempty"` - - // Nodes has the nodes that were output by the query. - Nodes []ServiceEntry - - // DNS has the options for serving these results over DNS. - DNS QueryDNSOptions - - // Datacenter is the datacenter that these results came from. - Datacenter string - - // Failovers is a count of how many times we had to query a remote - // datacenter. - Failovers int -} - -// PreparedQuery can be used to query the prepared query endpoints. -type PreparedQuery struct { - c *Client -} - -// PreparedQuery returns a handle to the prepared query endpoints. -func (c *Client) PreparedQuery() *PreparedQuery { - return &PreparedQuery{c} -} - -// Create makes a new prepared query. The ID of the new query is returned. -func (c *PreparedQuery) Create(query *PreparedQueryDefinition, q *WriteOptions) (string, *WriteMeta, error) { - r := c.c.newRequest("POST", "/v1/query") - r.setWriteOptions(q) - r.obj = query - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return "", nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return "", nil, err - } - - wm := &WriteMeta{} - wm.RequestTime = rtt - - var out struct{ ID string } - if err := decodeBody(resp, &out); err != nil { - return "", nil, err - } - return out.ID, wm, nil -} - -// Update makes updates to an existing prepared query. -func (c *PreparedQuery) Update(query *PreparedQueryDefinition, q *WriteOptions) (*WriteMeta, error) { - return c.c.write("/v1/query/"+query.ID, query, nil, q) -} - -// List is used to fetch all the prepared queries (always requires a management -// token). -func (c *PreparedQuery) List(q *QueryOptions) ([]*PreparedQueryDefinition, *QueryMeta, error) { - var out []*PreparedQueryDefinition - qm, err := c.c.query("/v1/query", &out, q) - if err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// Get is used to fetch a specific prepared query. -func (c *PreparedQuery) Get(queryID string, q *QueryOptions) ([]*PreparedQueryDefinition, *QueryMeta, error) { - var out []*PreparedQueryDefinition - qm, err := c.c.query("/v1/query/"+queryID, &out, q) - if err != nil { - return nil, nil, err - } - return out, qm, nil -} - -// Delete is used to delete a specific prepared query. -func (c *PreparedQuery) Delete(queryID string, q *WriteOptions) (*WriteMeta, error) { - r := c.c.newRequest("DELETE", "/v1/query/"+queryID) - r.setWriteOptions(q) - rtt, resp, err := c.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - wm := &WriteMeta{} - wm.RequestTime = rtt - return wm, nil -} - -// Execute is used to execute a specific prepared query. You can execute using -// a query ID or name. -func (c *PreparedQuery) Execute(queryIDOrName string, q *QueryOptions) (*PreparedQueryExecuteResponse, *QueryMeta, error) { - var out *PreparedQueryExecuteResponse - qm, err := c.c.query("/v1/query/"+queryIDOrName+"/execute", &out, q) - if err != nil { - return nil, nil, err - } - return out, qm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/raw.go b/vendor/github.com/hashicorp/consul/api/raw.go deleted file mode 100644 index 7fb9c390c9353..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/raw.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -// Raw can be used to do raw queries against custom endpoints -type Raw struct { - c *Client -} - -// Raw returns a handle to query endpoints -func (c *Client) Raw() *Raw { - return &Raw{c} -} - -// Query is used to do a GET request against an endpoint -// and deserialize the response into an interface using -// standard Consul conventions. -func (raw *Raw) Query(endpoint string, out interface{}, q *QueryOptions) (*QueryMeta, error) { - return raw.c.query(endpoint, out, q) -} - -// Write is used to do a PUT request against an endpoint -// and serialize/deserialized using the standard Consul conventions. -func (raw *Raw) Write(endpoint string, in, out interface{}, q *WriteOptions) (*WriteMeta, error) { - return raw.c.write(endpoint, in, out, q) -} - -// Delete is used to do a DELETE request against an endpoint -func (raw *Raw) Delete(endpoint string, q *QueryOptions) (*WriteMeta, error) { - return raw.c.delete(endpoint, q) -} diff --git a/vendor/github.com/hashicorp/consul/api/semaphore.go b/vendor/github.com/hashicorp/consul/api/semaphore.go deleted file mode 100644 index 9d98ff5c29b72..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/semaphore.go +++ /dev/null @@ -1,533 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "encoding/json" - "fmt" - "path" - "sync" - "time" -) - -const ( - // DefaultSemaphoreSessionName is the Session Name we assign if none is provided - DefaultSemaphoreSessionName = "Consul API Semaphore" - - // DefaultSemaphoreSessionTTL is the default session TTL if no Session is provided - // when creating a new Semaphore. This is used because we do not have another - // other check to depend upon. - DefaultSemaphoreSessionTTL = "15s" - - // DefaultSemaphoreWaitTime is how long we block for at a time to check if semaphore - // acquisition is possible. This affects the minimum time it takes to cancel - // a Semaphore acquisition. - DefaultSemaphoreWaitTime = 15 * time.Second - - // DefaultSemaphoreKey is the key used within the prefix to - // use for coordination between all the contenders. - DefaultSemaphoreKey = ".lock" - - // SemaphoreFlagValue is a magic flag we set to indicate a key - // is being used for a semaphore. It is used to detect a potential - // conflict with a lock. - SemaphoreFlagValue = 0xe0f69a2baa414de0 -) - -var ( - // ErrSemaphoreHeld is returned if we attempt to double lock - ErrSemaphoreHeld = fmt.Errorf("Semaphore already held") - - // ErrSemaphoreNotHeld is returned if we attempt to unlock a semaphore - // that we do not hold. - ErrSemaphoreNotHeld = fmt.Errorf("Semaphore not held") - - // ErrSemaphoreInUse is returned if we attempt to destroy a semaphore - // that is in use. - ErrSemaphoreInUse = fmt.Errorf("Semaphore in use") - - // ErrSemaphoreConflict is returned if the flags on a key - // used for a semaphore do not match expectation - ErrSemaphoreConflict = fmt.Errorf("Existing key does not match semaphore use") -) - -// Semaphore is used to implement a distributed semaphore -// using the Consul KV primitives. -type Semaphore struct { - c *Client - opts *SemaphoreOptions - - isHeld bool - sessionRenew chan struct{} - lockSession string - l sync.Mutex -} - -// SemaphoreOptions is used to parameterize the Semaphore -type SemaphoreOptions struct { - Prefix string // Must be set and have write permissions - Limit int // Must be set, and be positive - Value []byte // Optional, value to associate with the contender entry - Session string // Optional, created if not specified - SessionName string // Optional, defaults to DefaultLockSessionName - SessionTTL string // Optional, defaults to DefaultLockSessionTTL - MonitorRetries int // Optional, defaults to 0 which means no retries - MonitorRetryTime time.Duration // Optional, defaults to DefaultMonitorRetryTime - SemaphoreWaitTime time.Duration // Optional, defaults to DefaultSemaphoreWaitTime - SemaphoreTryOnce bool // Optional, defaults to false which means try forever - Namespace string `json:",omitempty"` // Optional, defaults to API client config, namespace of ACL token, or "default" namespace -} - -// semaphoreLock is written under the DefaultSemaphoreKey and -// is used to coordinate between all the contenders. -type semaphoreLock struct { - // Limit is the integer limit of holders. This is used to - // verify that all the holders agree on the value. - Limit int - - // Holders is a list of all the semaphore holders. - // It maps the session ID to true. It is used as a set effectively. - Holders map[string]bool -} - -// SemaphorePrefix is used to created a Semaphore which will operate -// at the given KV prefix and uses the given limit for the semaphore. -// The prefix must have write privileges, and the limit must be agreed -// upon by all contenders. -func (c *Client) SemaphorePrefix(prefix string, limit int) (*Semaphore, error) { - opts := &SemaphoreOptions{ - Prefix: prefix, - Limit: limit, - } - return c.SemaphoreOpts(opts) -} - -// SemaphoreOpts is used to create a Semaphore with the given options. -// The prefix must have write privileges, and the limit must be agreed -// upon by all contenders. If a Session is not provided, one will be created. -func (c *Client) SemaphoreOpts(opts *SemaphoreOptions) (*Semaphore, error) { - if opts.Prefix == "" { - return nil, fmt.Errorf("missing prefix") - } - if opts.Limit <= 0 { - return nil, fmt.Errorf("semaphore limit must be positive") - } - if opts.SessionName == "" { - opts.SessionName = DefaultSemaphoreSessionName - } - if opts.SessionTTL == "" { - opts.SessionTTL = DefaultSemaphoreSessionTTL - } else { - if _, err := time.ParseDuration(opts.SessionTTL); err != nil { - return nil, fmt.Errorf("invalid SessionTTL: %v", err) - } - } - if opts.MonitorRetryTime == 0 { - opts.MonitorRetryTime = DefaultMonitorRetryTime - } - if opts.SemaphoreWaitTime == 0 { - opts.SemaphoreWaitTime = DefaultSemaphoreWaitTime - } - s := &Semaphore{ - c: c, - opts: opts, - } - return s, nil -} - -// Acquire attempts to reserve a slot in the semaphore, blocking until -// success, interrupted via the stopCh or an error is encountered. -// Providing a non-nil stopCh can be used to abort the attempt. -// On success, a channel is returned that represents our slot. -// This channel could be closed at any time due to session invalidation, -// communication errors, operator intervention, etc. It is NOT safe to -// assume that the slot is held until Release() unless the Session is specifically -// created without any associated health checks. By default Consul sessions -// prefer liveness over safety and an application must be able to handle -// the session being lost. -func (s *Semaphore) Acquire(stopCh <-chan struct{}) (<-chan struct{}, error) { - // Hold the lock as we try to acquire - s.l.Lock() - defer s.l.Unlock() - - // Check if we already hold the semaphore - if s.isHeld { - return nil, ErrSemaphoreHeld - } - - // Check if we need to create a session first - s.lockSession = s.opts.Session - if s.lockSession == "" { - sess, err := s.createSession() - if err != nil { - return nil, fmt.Errorf("failed to create session: %v", err) - } - - s.sessionRenew = make(chan struct{}) - s.lockSession = sess - session := s.c.Session() - go session.RenewPeriodic(s.opts.SessionTTL, sess, nil, s.sessionRenew) - - // If we fail to acquire the lock, cleanup the session - defer func() { - if !s.isHeld { - close(s.sessionRenew) - s.sessionRenew = nil - } - }() - } - - // Create the contender entry - kv := s.c.KV() - wOpts := WriteOptions{Namespace: s.opts.Namespace} - - made, _, err := kv.Acquire(s.contenderEntry(s.lockSession), &wOpts) - if err != nil || !made { - return nil, fmt.Errorf("failed to make contender entry: %v", err) - } - - // Setup the query options - qOpts := QueryOptions{ - WaitTime: s.opts.SemaphoreWaitTime, - Namespace: s.opts.Namespace, - } - - start := time.Now() - attempts := 0 -WAIT: - // Check if we should quit - select { - case <-stopCh: - return nil, nil - default: - } - - // Handle the one-shot mode. - if s.opts.SemaphoreTryOnce && attempts > 0 { - elapsed := time.Since(start) - if elapsed > s.opts.SemaphoreWaitTime { - return nil, nil - } - - // Query wait time should not exceed the semaphore wait time - qOpts.WaitTime = s.opts.SemaphoreWaitTime - elapsed - } - attempts++ - - // Read the prefix - pairs, meta, err := kv.List(s.opts.Prefix, &qOpts) - if err != nil { - return nil, fmt.Errorf("failed to read prefix: %v", err) - } - - // Decode the lock - lockPair := s.findLock(pairs) - if lockPair.Flags != SemaphoreFlagValue { - return nil, ErrSemaphoreConflict - } - lock, err := s.decodeLock(lockPair) - if err != nil { - return nil, err - } - - // Verify we agree with the limit - if lock.Limit != s.opts.Limit { - return nil, fmt.Errorf("semaphore limit conflict (lock: %d, local: %d)", - lock.Limit, s.opts.Limit) - } - - // Prune the dead holders - s.pruneDeadHolders(lock, pairs) - - // Check if the lock is held - if len(lock.Holders) >= lock.Limit { - qOpts.WaitIndex = meta.LastIndex - goto WAIT - } - - // Create a new lock with us as a holder - lock.Holders[s.lockSession] = true - newLock, err := s.encodeLock(lock, lockPair.ModifyIndex) - if err != nil { - return nil, err - } - - // Attempt the acquisition - didSet, _, err := kv.CAS(newLock, &wOpts) - if err != nil { - return nil, fmt.Errorf("failed to update lock: %v", err) - } - if !didSet { - // Update failed, could have been a race with another contender, - // retry the operation - goto WAIT - } - - // Watch to ensure we maintain ownership of the slot - lockCh := make(chan struct{}) - go s.monitorLock(s.lockSession, lockCh) - - // Set that we own the lock - s.isHeld = true - - // Acquired! All done - return lockCh, nil -} - -// Release is used to voluntarily give up our semaphore slot. It is -// an error to call this if the semaphore has not been acquired. -func (s *Semaphore) Release() error { - // Hold the lock as we try to release - s.l.Lock() - defer s.l.Unlock() - - // Ensure the lock is actually held - if !s.isHeld { - return ErrSemaphoreNotHeld - } - - // Set that we no longer own the lock - s.isHeld = false - - // Stop the session renew - if s.sessionRenew != nil { - defer func() { - close(s.sessionRenew) - s.sessionRenew = nil - }() - } - - // Get and clear the lock session - lockSession := s.lockSession - s.lockSession = "" - - // Remove ourselves as a lock holder - kv := s.c.KV() - key := path.Join(s.opts.Prefix, DefaultSemaphoreKey) - - wOpts := WriteOptions{Namespace: s.opts.Namespace} - qOpts := QueryOptions{Namespace: s.opts.Namespace} - -READ: - pair, _, err := kv.Get(key, &qOpts) - if err != nil { - return err - } - if pair == nil { - pair = &KVPair{} - } - lock, err := s.decodeLock(pair) - if err != nil { - return err - } - - // Create a new lock without us as a holder - if _, ok := lock.Holders[lockSession]; ok { - delete(lock.Holders, lockSession) - newLock, err := s.encodeLock(lock, pair.ModifyIndex) - if err != nil { - return err - } - - // Swap the locks - didSet, _, err := kv.CAS(newLock, &wOpts) - if err != nil { - return fmt.Errorf("failed to update lock: %v", err) - } - if !didSet { - goto READ - } - } - - // Destroy the contender entry - contenderKey := path.Join(s.opts.Prefix, lockSession) - if _, err := kv.Delete(contenderKey, &wOpts); err != nil { - return err - } - return nil -} - -// Destroy is used to cleanup the semaphore entry. It is not necessary -// to invoke. It will fail if the semaphore is in use. -func (s *Semaphore) Destroy() error { - // Hold the lock as we try to acquire - s.l.Lock() - defer s.l.Unlock() - - // Check if we already hold the semaphore - if s.isHeld { - return ErrSemaphoreHeld - } - - // List for the semaphore - kv := s.c.KV() - - q := QueryOptions{Namespace: s.opts.Namespace} - pairs, _, err := kv.List(s.opts.Prefix, &q) - if err != nil { - return fmt.Errorf("failed to read prefix: %v", err) - } - - // Find the lock pair, bail if it doesn't exist - lockPair := s.findLock(pairs) - if lockPair.ModifyIndex == 0 { - return nil - } - if lockPair.Flags != SemaphoreFlagValue { - return ErrSemaphoreConflict - } - - // Decode the lock - lock, err := s.decodeLock(lockPair) - if err != nil { - return err - } - - // Prune the dead holders - s.pruneDeadHolders(lock, pairs) - - // Check if there are any holders - if len(lock.Holders) > 0 { - return ErrSemaphoreInUse - } - - // Attempt the delete - w := WriteOptions{Namespace: s.opts.Namespace} - didRemove, _, err := kv.DeleteCAS(lockPair, &w) - if err != nil { - return fmt.Errorf("failed to remove semaphore: %v", err) - } - if !didRemove { - return ErrSemaphoreInUse - } - return nil -} - -// createSession is used to create a new managed session -func (s *Semaphore) createSession() (string, error) { - session := s.c.Session() - se := &SessionEntry{ - Name: s.opts.SessionName, - TTL: s.opts.SessionTTL, - Behavior: SessionBehaviorDelete, - } - - w := WriteOptions{Namespace: s.opts.Namespace} - id, _, err := session.Create(se, &w) - if err != nil { - return "", err - } - return id, nil -} - -// contenderEntry returns a formatted KVPair for the contender -func (s *Semaphore) contenderEntry(session string) *KVPair { - return &KVPair{ - Key: path.Join(s.opts.Prefix, session), - Value: s.opts.Value, - Session: session, - Flags: SemaphoreFlagValue, - } -} - -// findLock is used to find the KV Pair which is used for coordination -func (s *Semaphore) findLock(pairs KVPairs) *KVPair { - key := path.Join(s.opts.Prefix, DefaultSemaphoreKey) - for _, pair := range pairs { - if pair.Key == key { - return pair - } - } - return &KVPair{Flags: SemaphoreFlagValue} -} - -// decodeLock is used to decode a semaphoreLock from an -// entry in Consul -func (s *Semaphore) decodeLock(pair *KVPair) (*semaphoreLock, error) { - // Handle if there is no lock - if pair == nil || pair.Value == nil { - return &semaphoreLock{ - Limit: s.opts.Limit, - Holders: make(map[string]bool), - }, nil - } - - l := &semaphoreLock{} - if err := json.Unmarshal(pair.Value, l); err != nil { - return nil, fmt.Errorf("lock decoding failed: %v", err) - } - return l, nil -} - -// encodeLock is used to encode a semaphoreLock into a KVPair -// that can be PUT -func (s *Semaphore) encodeLock(l *semaphoreLock, oldIndex uint64) (*KVPair, error) { - enc, err := json.Marshal(l) - if err != nil { - return nil, fmt.Errorf("lock encoding failed: %v", err) - } - pair := &KVPair{ - Key: path.Join(s.opts.Prefix, DefaultSemaphoreKey), - Value: enc, - Flags: SemaphoreFlagValue, - ModifyIndex: oldIndex, - } - return pair, nil -} - -// pruneDeadHolders is used to remove all the dead lock holders -func (s *Semaphore) pruneDeadHolders(lock *semaphoreLock, pairs KVPairs) { - // Gather all the live holders - alive := make(map[string]struct{}, len(pairs)) - for _, pair := range pairs { - if pair.Session != "" { - alive[pair.Session] = struct{}{} - } - } - - // Remove any holders that are dead - for holder := range lock.Holders { - if _, ok := alive[holder]; !ok { - delete(lock.Holders, holder) - } - } -} - -// monitorLock is a long running routine to monitor a semaphore ownership -// It closes the stopCh if we lose our slot. -func (s *Semaphore) monitorLock(session string, stopCh chan struct{}) { - defer close(stopCh) - kv := s.c.KV() - opts := QueryOptions{ - RequireConsistent: true, - Namespace: s.opts.Namespace, - } -WAIT: - retries := s.opts.MonitorRetries -RETRY: - pairs, meta, err := kv.List(s.opts.Prefix, &opts) - if err != nil { - // If configured we can try to ride out a brief Consul unavailability - // by doing retries. Note that we have to attempt the retry in a non- - // blocking fashion so that we have a clean place to reset the retry - // counter if service is restored. - if retries > 0 && IsRetryableError(err) { - time.Sleep(s.opts.MonitorRetryTime) - retries-- - opts.WaitIndex = 0 - goto RETRY - } - return - } - lockPair := s.findLock(pairs) - lock, err := s.decodeLock(lockPair) - if err != nil { - return - } - s.pruneDeadHolders(lock, pairs) - if _, ok := lock.Holders[session]; ok { - opts.WaitIndex = meta.LastIndex - goto WAIT - } -} diff --git a/vendor/github.com/hashicorp/consul/api/session.go b/vendor/github.com/hashicorp/consul/api/session.go deleted file mode 100644 index 69fd77d2790c9..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/session.go +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "errors" - "fmt" - "time" -) - -const ( - // SessionBehaviorRelease is the default behavior and causes - // all associated locks to be released on session invalidation. - SessionBehaviorRelease = "release" - - // SessionBehaviorDelete is new in Consul 0.5 and changes the - // behavior to delete all associated locks on session invalidation. - // It can be used in a way similar to Ephemeral Nodes in ZooKeeper. - SessionBehaviorDelete = "delete" -) - -var ErrSessionExpired = errors.New("session expired") - -// SessionEntry represents a session in consul -type SessionEntry struct { - CreateIndex uint64 - ID string - Name string - Node string - LockDelay time.Duration - Behavior string - TTL string - Namespace string `json:",omitempty"` - - // Deprecated for Consul Enterprise in v1.7.0. - Checks []string - - // NodeChecks and ServiceChecks are new in Consul 1.7.0. - // When associating checks with sessions, namespaces can be specified for service checks. - NodeChecks []string - ServiceChecks []ServiceCheck -} - -type ServiceCheck struct { - ID string - Namespace string -} - -// Session can be used to query the Session endpoints -type Session struct { - c *Client -} - -// Session returns a handle to the session endpoints -func (c *Client) Session() *Session { - return &Session{c} -} - -// CreateNoChecks is like Create but is used specifically to create -// a session with no associated health checks. -func (s *Session) CreateNoChecks(se *SessionEntry, q *WriteOptions) (string, *WriteMeta, error) { - body := make(map[string]interface{}) - body["NodeChecks"] = []string{} - if se != nil { - if se.Name != "" { - body["Name"] = se.Name - } - if se.Node != "" { - body["Node"] = se.Node - } - if se.LockDelay != 0 { - body["LockDelay"] = durToMsec(se.LockDelay) - } - if se.Behavior != "" { - body["Behavior"] = se.Behavior - } - if se.TTL != "" { - body["TTL"] = se.TTL - } - } - return s.create(body, q) - -} - -// Create makes a new session. Providing a session entry can -// customize the session. It can also be nil to use defaults. -func (s *Session) Create(se *SessionEntry, q *WriteOptions) (string, *WriteMeta, error) { - var obj interface{} - if se != nil { - body := make(map[string]interface{}) - obj = body - if se.Name != "" { - body["Name"] = se.Name - } - if se.Node != "" { - body["Node"] = se.Node - } - if se.LockDelay != 0 { - body["LockDelay"] = durToMsec(se.LockDelay) - } - if len(se.Checks) > 0 { - body["Checks"] = se.Checks - } - if len(se.NodeChecks) > 0 { - body["NodeChecks"] = se.NodeChecks - } - if len(se.ServiceChecks) > 0 { - body["ServiceChecks"] = se.ServiceChecks - } - if se.Behavior != "" { - body["Behavior"] = se.Behavior - } - if se.TTL != "" { - body["TTL"] = se.TTL - } - } - return s.create(obj, q) -} - -func (s *Session) create(obj interface{}, q *WriteOptions) (string, *WriteMeta, error) { - var out struct{ ID string } - wm, err := s.c.write("/v1/session/create", obj, &out, q) - if err != nil { - return "", nil, err - } - return out.ID, wm, nil -} - -// Destroy invalidates a given session -func (s *Session) Destroy(id string, q *WriteOptions) (*WriteMeta, error) { - wm, err := s.c.write("/v1/session/destroy/"+id, nil, nil, q) - if err != nil { - return nil, err - } - return wm, nil -} - -// Renew renews the TTL on a given session -func (s *Session) Renew(id string, q *WriteOptions) (*SessionEntry, *WriteMeta, error) { - r := s.c.newRequest("PUT", "/v1/session/renew/"+id) - r.setWriteOptions(q) - rtt, resp, err := s.c.doRequest(r) - if err != nil { - return nil, nil, err - } - defer closeResponseBody(resp) - - wm := &WriteMeta{RequestTime: rtt} - - if resp.StatusCode == 404 { - return nil, wm, nil - } else if resp.StatusCode != 200 { - return nil, nil, fmt.Errorf("Unexpected response code: %d", resp.StatusCode) - } - - var entries []*SessionEntry - if err := decodeBody(resp, &entries); err != nil { - return nil, nil, fmt.Errorf("Failed to read response: %v", err) - } - if len(entries) > 0 { - return entries[0], wm, nil - } - return nil, wm, nil -} - -// RenewPeriodic is used to periodically invoke Session.Renew on a -// session until a doneCh is closed. This is meant to be used in a long running -// goroutine to ensure a session stays valid. -func (s *Session) RenewPeriodic(initialTTL string, id string, q *WriteOptions, doneCh <-chan struct{}) error { - ctx := q.Context() - - ttl, err := time.ParseDuration(initialTTL) - if err != nil { - return err - } - - waitDur := ttl / 2 - lastRenewTime := time.Now() - var lastErr error - for { - if time.Since(lastRenewTime) > ttl { - return lastErr - } - select { - case <-time.After(waitDur): - entry, _, err := s.Renew(id, q) - if err != nil { - waitDur = time.Second - lastErr = err - continue - } - if entry == nil { - return ErrSessionExpired - } - - // Handle the server updating the TTL - ttl, _ = time.ParseDuration(entry.TTL) - waitDur = ttl / 2 - lastRenewTime = time.Now() - - case <-doneCh: - // Attempt a session destroy - s.Destroy(id, q) - return nil - - case <-ctx.Done(): - // Bail immediately since attempting the destroy would - // use the canceled context in q, which would just bail. - return ctx.Err() - } - } -} - -// Info looks up a single session -func (s *Session) Info(id string, q *QueryOptions) (*SessionEntry, *QueryMeta, error) { - var entries []*SessionEntry - qm, err := s.c.query("/v1/session/info/"+id, &entries, q) - if err != nil { - return nil, nil, err - } - if len(entries) > 0 { - return entries[0], qm, nil - } - return nil, qm, nil -} - -// List gets sessions for a node -func (s *Session) Node(node string, q *QueryOptions) ([]*SessionEntry, *QueryMeta, error) { - var entries []*SessionEntry - qm, err := s.c.query("/v1/session/node/"+node, &entries, q) - if err != nil { - return nil, nil, err - } - return entries, qm, nil -} - -// List gets all active sessions -func (s *Session) List(q *QueryOptions) ([]*SessionEntry, *QueryMeta, error) { - var entries []*SessionEntry - qm, err := s.c.query("/v1/session/list", &entries, q) - if err != nil { - return nil, nil, err - } - return entries, qm, nil -} diff --git a/vendor/github.com/hashicorp/consul/api/snapshot.go b/vendor/github.com/hashicorp/consul/api/snapshot.go deleted file mode 100644 index bcc80e5b3dea1..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/snapshot.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "io" -) - -// Snapshot can be used to query the /v1/snapshot endpoint to take snapshots of -// Consul's internal state and restore snapshots for disaster recovery. -type Snapshot struct { - c *Client -} - -// Snapshot returns a handle that exposes the snapshot endpoints. -func (c *Client) Snapshot() *Snapshot { - return &Snapshot{c} -} - -// Save requests a new snapshot and provides an io.ReadCloser with the snapshot -// data to save. If this doesn't return an error, then it's the responsibility -// of the caller to close it. Only a subset of the QueryOptions are supported: -// Datacenter, AllowStale, and Token. -func (s *Snapshot) Save(q *QueryOptions) (io.ReadCloser, *QueryMeta, error) { - r := s.c.newRequest("GET", "/v1/snapshot") - r.setQueryOptions(q) - - rtt, resp, err := s.c.doRequest(r) - if err != nil { - return nil, nil, err - } - if err := requireOK(resp); err != nil { - return nil, nil, err - } - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - return resp.Body, qm, nil -} - -// Restore streams in an existing snapshot and attempts to restore it. -func (s *Snapshot) Restore(q *WriteOptions, in io.Reader) error { - r := s.c.newRequest("PUT", "/v1/snapshot") - r.body = in - r.header.Set("Content-Type", "application/octet-stream") - r.setWriteOptions(q) - _, resp, err := s.c.doRequest(r) - if err != nil { - return err - } - if err := requireOK(resp); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/hashicorp/consul/api/status.go b/vendor/github.com/hashicorp/consul/api/status.go deleted file mode 100644 index 8c52eb222bf75..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/status.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -// Status can be used to query the Status endpoints -type Status struct { - c *Client -} - -// Status returns a handle to the status endpoints -func (c *Client) Status() *Status { - return &Status{c} -} - -// Leader is used to query for a known leader -func (s *Status) LeaderWithQueryOptions(q *QueryOptions) (string, error) { - r := s.c.newRequest("GET", "/v1/status/leader") - - if q != nil { - r.setQueryOptions(q) - } - - _, resp, err := s.c.doRequest(r) - if err != nil { - return "", err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return "", err - } - - var leader string - if err := decodeBody(resp, &leader); err != nil { - return "", err - } - return leader, nil -} - -func (s *Status) Leader() (string, error) { - return s.LeaderWithQueryOptions(nil) -} - -// Peers is used to query for a known raft peers -func (s *Status) PeersWithQueryOptions(q *QueryOptions) ([]string, error) { - r := s.c.newRequest("GET", "/v1/status/peers") - - if q != nil { - r.setQueryOptions(q) - } - - _, resp, err := s.c.doRequest(r) - if err != nil { - return nil, err - } - defer closeResponseBody(resp) - if err := requireOK(resp); err != nil { - return nil, err - } - - var peers []string - if err := decodeBody(resp, &peers); err != nil { - return nil, err - } - return peers, nil -} - -func (s *Status) Peers() ([]string, error) { - return s.PeersWithQueryOptions(nil) -} diff --git a/vendor/github.com/hashicorp/consul/api/txn.go b/vendor/github.com/hashicorp/consul/api/txn.go deleted file mode 100644 index 59adafdac3de6..0000000000000 --- a/vendor/github.com/hashicorp/consul/api/txn.go +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "bytes" - "fmt" - "io" - "net/http" -) - -// Txn is used to manipulate the Txn API -type Txn struct { - c *Client -} - -// Txn is used to return a handle to the K/V apis -func (c *Client) Txn() *Txn { - return &Txn{c} -} - -// TxnOp is the internal format we send to Consul. Currently only K/V and -// check operations are supported. -type TxnOp struct { - KV *KVTxnOp - Node *NodeTxnOp - Service *ServiceTxnOp - Check *CheckTxnOp -} - -// TxnOps is a list of transaction operations. -type TxnOps []*TxnOp - -// TxnResult is the internal format we receive from Consul. -type TxnResult struct { - KV *KVPair - Node *Node - Service *CatalogService - Check *HealthCheck -} - -// TxnResults is a list of TxnResult objects. -type TxnResults []*TxnResult - -// TxnError is used to return information about an operation in a transaction. -type TxnError struct { - OpIndex int - What string -} - -// TxnErrors is a list of TxnError objects. -type TxnErrors []*TxnError - -// TxnResponse is the internal format we receive from Consul. -type TxnResponse struct { - Results TxnResults - Errors TxnErrors -} - -// KVOp constants give possible operations available in a transaction. -type KVOp string - -const ( - KVSet KVOp = "set" - KVDelete KVOp = "delete" - KVDeleteCAS KVOp = "delete-cas" - KVDeleteTree KVOp = "delete-tree" - KVCAS KVOp = "cas" - KVLock KVOp = "lock" - KVUnlock KVOp = "unlock" - KVGet KVOp = "get" - KVGetOrEmpty KVOp = "get-or-empty" - KVGetTree KVOp = "get-tree" - KVCheckSession KVOp = "check-session" - KVCheckIndex KVOp = "check-index" - KVCheckNotExists KVOp = "check-not-exists" -) - -// KVTxnOp defines a single operation inside a transaction. -type KVTxnOp struct { - Verb KVOp - Key string - Value []byte - Flags uint64 - Index uint64 - Session string - Namespace string `json:",omitempty"` - Partition string `json:",omitempty"` -} - -// KVTxnOps defines a set of operations to be performed inside a single -// transaction. -type KVTxnOps []*KVTxnOp - -// KVTxnResponse has the outcome of a transaction. -type KVTxnResponse struct { - Results []*KVPair - Errors TxnErrors -} - -// SessionOp constants give possible operations available in a transaction. -type SessionOp string - -const ( - SessionDelete SessionOp = "delete" -) - -// SessionTxnOp defines a single operation inside a transaction. -type SessionTxnOp struct { - Verb SessionOp - Session Session -} - -// NodeOp constants give possible operations available in a transaction. -type NodeOp string - -const ( - NodeGet NodeOp = "get" - NodeSet NodeOp = "set" - NodeCAS NodeOp = "cas" - NodeDelete NodeOp = "delete" - NodeDeleteCAS NodeOp = "delete-cas" -) - -// NodeTxnOp defines a single operation inside a transaction. -type NodeTxnOp struct { - Verb NodeOp - Node Node -} - -// ServiceOp constants give possible operations available in a transaction. -type ServiceOp string - -const ( - ServiceGet ServiceOp = "get" - ServiceSet ServiceOp = "set" - ServiceCAS ServiceOp = "cas" - ServiceDelete ServiceOp = "delete" - ServiceDeleteCAS ServiceOp = "delete-cas" -) - -// ServiceTxnOp defines a single operation inside a transaction. -type ServiceTxnOp struct { - Verb ServiceOp - Node string - Service AgentService -} - -// CheckOp constants give possible operations available in a transaction. -type CheckOp string - -const ( - CheckGet CheckOp = "get" - CheckSet CheckOp = "set" - CheckCAS CheckOp = "cas" - CheckDelete CheckOp = "delete" - CheckDeleteCAS CheckOp = "delete-cas" -) - -// CheckTxnOp defines a single operation inside a transaction. -type CheckTxnOp struct { - Verb CheckOp - Check HealthCheck -} - -// Txn is used to apply multiple Consul operations in a single, atomic transaction. -// -// Note that Go will perform the required base64 encoding on the values -// automatically because the type is a byte slice. Transactions are defined as a -// list of operations to perform, using the different fields in the TxnOp structure -// to define operations. If any operation fails, none of the changes are applied -// to the state store. -// -// Even though this is generally a write operation, we take a QueryOptions input -// and return a QueryMeta output. If the transaction contains only read ops, then -// Consul will fast-path it to a different endpoint internally which supports -// consistency controls, but not blocking. If there are write operations then -// the request will always be routed through raft and any consistency settings -// will be ignored. -// -// Here's an example: -// -// ops := KVTxnOps{ -// &KVTxnOp{ -// Verb: KVLock, -// Key: "test/lock", -// Session: "adf4238a-882b-9ddc-4a9d-5b6758e4159e", -// Value: []byte("hello"), -// }, -// &KVTxnOp{ -// Verb: KVGet, -// Key: "another/key", -// }, -// &CheckTxnOp{ -// Verb: CheckSet, -// HealthCheck: HealthCheck{ -// Node: "foo", -// CheckID: "redis:a", -// Name: "Redis Health Check", -// Status: "passing", -// }, -// } -// } -// ok, response, _, err := kv.Txn(&ops, nil) -// -// If there is a problem making the transaction request then an error will be -// returned. Otherwise, the ok value will be true if the transaction succeeded -// or false if it was rolled back. The response is a structured return value which -// will have the outcome of the transaction. Its Results member will have entries -// for each operation. For KV operations, Deleted keys will have a nil entry in the -// results, and to save space, the Value of each key in the Results will be nil -// unless the operation is a KVGet. If the transaction was rolled back, the Errors -// member will have entries referencing the index of the operation that failed -// along with an error message. -func (t *Txn) Txn(txn TxnOps, q *QueryOptions) (bool, *TxnResponse, *QueryMeta, error) { - return t.c.txn(txn, q) -} - -func (c *Client) txn(txn TxnOps, q *QueryOptions) (bool, *TxnResponse, *QueryMeta, error) { - r := c.newRequest("PUT", "/v1/txn") - r.setQueryOptions(q) - - r.obj = txn - rtt, resp, err := c.doRequest(r) - if err != nil { - return false, nil, nil, err - } - defer closeResponseBody(resp) - - qm := &QueryMeta{} - parseQueryMeta(resp, qm) - qm.RequestTime = rtt - - if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusConflict { - var txnResp TxnResponse - if err := decodeBody(resp, &txnResp); err != nil { - return false, nil, nil, err - } - - return resp.StatusCode == http.StatusOK, &txnResp, qm, nil - } - - var buf bytes.Buffer - if _, err := io.Copy(&buf, resp.Body); err != nil { - return false, nil, nil, fmt.Errorf("Failed to read response: %v", err) - } - return false, nil, nil, fmt.Errorf("Failed request: %s", buf.String()) -} diff --git a/vendor/github.com/hashicorp/go-cleanhttp/LICENSE b/vendor/github.com/hashicorp/go-cleanhttp/LICENSE deleted file mode 100644 index e87a115e462e1..0000000000000 --- a/vendor/github.com/hashicorp/go-cleanhttp/LICENSE +++ /dev/null @@ -1,363 +0,0 @@ -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. "Contributor" - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. "Contributor Version" - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. - -1.6. "Executable Form" - - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. - -1.8. "License" - - means this document. - -1.9. "Licensable" - - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. - -1.10. "Modifications" - - means any of the following: - - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. "Patent Claims" of a Contributor - - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. - -1.12. "Secondary License" - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. "Source Code Form" - - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. - - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice - - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. - diff --git a/vendor/github.com/hashicorp/go-cleanhttp/README.md b/vendor/github.com/hashicorp/go-cleanhttp/README.md deleted file mode 100644 index 036e5313fc8f9..0000000000000 --- a/vendor/github.com/hashicorp/go-cleanhttp/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# cleanhttp - -Functions for accessing "clean" Go http.Client values - -------------- - -The Go standard library contains a default `http.Client` called -`http.DefaultClient`. It is a common idiom in Go code to start with -`http.DefaultClient` and tweak it as necessary, and in fact, this is -encouraged; from the `http` package documentation: - -> The Client's Transport typically has internal state (cached TCP connections), -so Clients should be reused instead of created as needed. Clients are safe for -concurrent use by multiple goroutines. - -Unfortunately, this is a shared value, and it is not uncommon for libraries to -assume that they are free to modify it at will. With enough dependencies, it -can be very easy to encounter strange problems and race conditions due to -manipulation of this shared value across libraries and goroutines (clients are -safe for concurrent use, but writing values to the client struct itself is not -protected). - -Making things worse is the fact that a bare `http.Client` will use a default -`http.Transport` called `http.DefaultTransport`, which is another global value -that behaves the same way. So it is not simply enough to replace -`http.DefaultClient` with `&http.Client{}`. - -This repository provides some simple functions to get a "clean" `http.Client` --- one that uses the same default values as the Go standard library, but -returns a client that does not share any state with other clients. diff --git a/vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go b/vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go deleted file mode 100644 index fe28d15b6f939..0000000000000 --- a/vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go +++ /dev/null @@ -1,58 +0,0 @@ -package cleanhttp - -import ( - "net" - "net/http" - "runtime" - "time" -) - -// DefaultTransport returns a new http.Transport with similar default values to -// http.DefaultTransport, but with idle connections and keepalives disabled. -func DefaultTransport() *http.Transport { - transport := DefaultPooledTransport() - transport.DisableKeepAlives = true - transport.MaxIdleConnsPerHost = -1 - return transport -} - -// DefaultPooledTransport returns a new http.Transport with similar default -// values to http.DefaultTransport. Do not use this for transient transports as -// it can leak file descriptors over time. Only use this for transports that -// will be re-used for the same host(s). -func DefaultPooledTransport() *http.Transport { - transport := &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - DualStack: true, - }).DialContext, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - ForceAttemptHTTP2: true, - MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1, - } - return transport -} - -// DefaultClient returns a new http.Client with similar default values to -// http.Client, but with a non-shared Transport, idle connections disabled, and -// keepalives disabled. -func DefaultClient() *http.Client { - return &http.Client{ - Transport: DefaultTransport(), - } -} - -// DefaultPooledClient returns a new http.Client with similar default values to -// http.Client, but with a shared Transport. Do not use this function for -// transient clients as it can leak file descriptors over time. Only use this -// for clients that will be re-used for the same host(s). -func DefaultPooledClient() *http.Client { - return &http.Client{ - Transport: DefaultPooledTransport(), - } -} diff --git a/vendor/github.com/hashicorp/go-cleanhttp/doc.go b/vendor/github.com/hashicorp/go-cleanhttp/doc.go deleted file mode 100644 index 05841092a7b34..0000000000000 --- a/vendor/github.com/hashicorp/go-cleanhttp/doc.go +++ /dev/null @@ -1,20 +0,0 @@ -// Package cleanhttp offers convenience utilities for acquiring "clean" -// http.Transport and http.Client structs. -// -// Values set on http.DefaultClient and http.DefaultTransport affect all -// callers. This can have detrimental effects, esepcially in TLS contexts, -// where client or root certificates set to talk to multiple endpoints can end -// up displacing each other, leading to hard-to-debug issues. This package -// provides non-shared http.Client and http.Transport structs to ensure that -// the configuration will not be overwritten by other parts of the application -// or dependencies. -// -// The DefaultClient and DefaultTransport functions disable idle connections -// and keepalives. Without ensuring that idle connections are closed before -// garbage collection, short-term clients/transports can leak file descriptors, -// eventually leading to "too many open files" errors. If you will be -// connecting to the same hosts repeatedly from the same client, you can use -// DefaultPooledClient to receive a client that has connection pooling -// semantics similar to http.DefaultClient. -// -package cleanhttp diff --git a/vendor/github.com/hashicorp/go-cleanhttp/handlers.go b/vendor/github.com/hashicorp/go-cleanhttp/handlers.go deleted file mode 100644 index 3c845dc0dc6f8..0000000000000 --- a/vendor/github.com/hashicorp/go-cleanhttp/handlers.go +++ /dev/null @@ -1,48 +0,0 @@ -package cleanhttp - -import ( - "net/http" - "strings" - "unicode" -) - -// HandlerInput provides input options to cleanhttp's handlers -type HandlerInput struct { - ErrStatus int -} - -// PrintablePathCheckHandler is a middleware that ensures the request path -// contains only printable runes. -func PrintablePathCheckHandler(next http.Handler, input *HandlerInput) http.Handler { - // Nil-check on input to make it optional - if input == nil { - input = &HandlerInput{ - ErrStatus: http.StatusBadRequest, - } - } - - // Default to http.StatusBadRequest on error - if input.ErrStatus == 0 { - input.ErrStatus = http.StatusBadRequest - } - - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r != nil { - // Check URL path for non-printable characters - idx := strings.IndexFunc(r.URL.Path, func(c rune) bool { - return !unicode.IsPrint(c) - }) - - if idx != -1 { - w.WriteHeader(input.ErrStatus) - return - } - - if next != nil { - next.ServeHTTP(w, r) - } - } - - return - }) -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/.gitignore b/vendor/github.com/hashicorp/go-immutable-radix/.gitignore deleted file mode 100644 index daf913b1b347a..0000000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof diff --git a/vendor/github.com/hashicorp/go-immutable-radix/CHANGELOG.md b/vendor/github.com/hashicorp/go-immutable-radix/CHANGELOG.md deleted file mode 100644 index 86c6d03fbaac5..0000000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/CHANGELOG.md +++ /dev/null @@ -1,23 +0,0 @@ -# UNRELEASED - -# 1.3.0 (September 17th, 2020) - -FEATURES - -* Add reverse tree traversal [[GH-30](https://github.com/hashicorp/go-immutable-radix/pull/30)] - -# 1.2.0 (March 18th, 2020) - -FEATURES - -* Adds a `Clone` method to `Txn` allowing transactions to be split either into two independently mutable trees. [[GH-26](https://github.com/hashicorp/go-immutable-radix/pull/26)] - -# 1.1.0 (May 22nd, 2019) - -FEATURES - -* Add `SeekLowerBound` to allow for range scans. [[GH-24](https://github.com/hashicorp/go-immutable-radix/pull/24)] - -# 1.0.0 (August 30th, 2018) - -* go mod adopted diff --git a/vendor/github.com/hashicorp/go-immutable-radix/LICENSE b/vendor/github.com/hashicorp/go-immutable-radix/LICENSE deleted file mode 100644 index e87a115e462e1..0000000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/LICENSE +++ /dev/null @@ -1,363 +0,0 @@ -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. "Contributor" - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. "Contributor Version" - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. - -1.6. "Executable Form" - - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. - -1.8. "License" - - means this document. - -1.9. "Licensable" - - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. - -1.10. "Modifications" - - means any of the following: - - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. "Patent Claims" of a Contributor - - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. - -1.12. "Secondary License" - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. "Source Code Form" - - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. - - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice - - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. - diff --git a/vendor/github.com/hashicorp/go-immutable-radix/README.md b/vendor/github.com/hashicorp/go-immutable-radix/README.md deleted file mode 100644 index aca15a64212a7..0000000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/README.md +++ /dev/null @@ -1,66 +0,0 @@ -go-immutable-radix [![CircleCI](https://circleci.com/gh/hashicorp/go-immutable-radix/tree/master.svg?style=svg)](https://circleci.com/gh/hashicorp/go-immutable-radix/tree/master) -========= - -Provides the `iradix` package that implements an immutable [radix tree](http://en.wikipedia.org/wiki/Radix_tree). -The package only provides a single `Tree` implementation, optimized for sparse nodes. - -As a radix tree, it provides the following: - * O(k) operations. In many cases, this can be faster than a hash table since - the hash function is an O(k) operation, and hash tables have very poor cache locality. - * Minimum / Maximum value lookups - * Ordered iteration - -A tree supports using a transaction to batch multiple updates (insert, delete) -in a more efficient manner than performing each operation one at a time. - -For a mutable variant, see [go-radix](https://github.com/armon/go-radix). - -Documentation -============= - -The full documentation is available on [Godoc](http://godoc.org/github.com/hashicorp/go-immutable-radix). - -Example -======= - -Below is a simple example of usage - -```go -// Create a tree -r := iradix.New() -r, _, _ = r.Insert([]byte("foo"), 1) -r, _, _ = r.Insert([]byte("bar"), 2) -r, _, _ = r.Insert([]byte("foobar"), 2) - -// Find the longest prefix match -m, _, _ := r.Root().LongestPrefix([]byte("foozip")) -if string(m) != "foo" { - panic("should be foo") -} -``` - -Here is an example of performing a range scan of the keys. - -```go -// Create a tree -r := iradix.New() -r, _, _ = r.Insert([]byte("001"), 1) -r, _, _ = r.Insert([]byte("002"), 2) -r, _, _ = r.Insert([]byte("005"), 5) -r, _, _ = r.Insert([]byte("010"), 10) -r, _, _ = r.Insert([]byte("100"), 10) - -// Range scan over the keys that sort lexicographically between [003, 050) -it := r.Root().Iterator() -it.SeekLowerBound([]byte("003")) -for key, _, ok := it.Next(); ok; key, _, ok = it.Next() { - if key >= "050" { - break - } - fmt.Println(key) -} -// Output: -// 005 -// 010 -``` - diff --git a/vendor/github.com/hashicorp/go-immutable-radix/edges.go b/vendor/github.com/hashicorp/go-immutable-radix/edges.go deleted file mode 100644 index a63674775f2f4..0000000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/edges.go +++ /dev/null @@ -1,21 +0,0 @@ -package iradix - -import "sort" - -type edges []edge - -func (e edges) Len() int { - return len(e) -} - -func (e edges) Less(i, j int) bool { - return e[i].label < e[j].label -} - -func (e edges) Swap(i, j int) { - e[i], e[j] = e[j], e[i] -} - -func (e edges) Sort() { - sort.Sort(e) -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/iradix.go b/vendor/github.com/hashicorp/go-immutable-radix/iradix.go deleted file mode 100644 index 168bda76dfb88..0000000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/iradix.go +++ /dev/null @@ -1,676 +0,0 @@ -package iradix - -import ( - "bytes" - "strings" - - "github.com/hashicorp/golang-lru/simplelru" -) - -const ( - // defaultModifiedCache is the default size of the modified node - // cache used per transaction. This is used to cache the updates - // to the nodes near the root, while the leaves do not need to be - // cached. This is important for very large transactions to prevent - // the modified cache from growing to be enormous. This is also used - // to set the max size of the mutation notify maps since those should - // also be bounded in a similar way. - defaultModifiedCache = 8192 -) - -// Tree implements an immutable radix tree. This can be treated as a -// Dictionary abstract data type. The main advantage over a standard -// hash map is prefix-based lookups and ordered iteration. The immutability -// means that it is safe to concurrently read from a Tree without any -// coordination. -type Tree struct { - root *Node - size int -} - -// New returns an empty Tree -func New() *Tree { - t := &Tree{ - root: &Node{ - mutateCh: make(chan struct{}), - }, - } - return t -} - -// Len is used to return the number of elements in the tree -func (t *Tree) Len() int { - return t.size -} - -// Txn is a transaction on the tree. This transaction is applied -// atomically and returns a new tree when committed. A transaction -// is not thread safe, and should only be used by a single goroutine. -type Txn struct { - // root is the modified root for the transaction. - root *Node - - // snap is a snapshot of the root node for use if we have to run the - // slow notify algorithm. - snap *Node - - // size tracks the size of the tree as it is modified during the - // transaction. - size int - - // writable is a cache of writable nodes that have been created during - // the course of the transaction. This allows us to re-use the same - // nodes for further writes and avoid unnecessary copies of nodes that - // have never been exposed outside the transaction. This will only hold - // up to defaultModifiedCache number of entries. - writable *simplelru.LRU - - // trackChannels is used to hold channels that need to be notified to - // signal mutation of the tree. This will only hold up to - // defaultModifiedCache number of entries, after which we will set the - // trackOverflow flag, which will cause us to use a more expensive - // algorithm to perform the notifications. Mutation tracking is only - // performed if trackMutate is true. - trackChannels map[chan struct{}]struct{} - trackOverflow bool - trackMutate bool -} - -// Txn starts a new transaction that can be used to mutate the tree -func (t *Tree) Txn() *Txn { - txn := &Txn{ - root: t.root, - snap: t.root, - size: t.size, - } - return txn -} - -// Clone makes an independent copy of the transaction. The new transaction -// does not track any nodes and has TrackMutate turned off. The cloned transaction will contain any uncommitted writes in the original transaction but further mutations to either will be independent and result in different radix trees on Commit. A cloned transaction may be passed to another goroutine and mutated there independently however each transaction may only be mutated in a single thread. -func (t *Txn) Clone() *Txn { - // reset the writable node cache to avoid leaking future writes into the clone - t.writable = nil - - txn := &Txn{ - root: t.root, - snap: t.snap, - size: t.size, - } - return txn -} - -// TrackMutate can be used to toggle if mutations are tracked. If this is enabled -// then notifications will be issued for affected internal nodes and leaves when -// the transaction is committed. -func (t *Txn) TrackMutate(track bool) { - t.trackMutate = track -} - -// trackChannel safely attempts to track the given mutation channel, setting the -// overflow flag if we can no longer track any more. This limits the amount of -// state that will accumulate during a transaction and we have a slower algorithm -// to switch to if we overflow. -func (t *Txn) trackChannel(ch chan struct{}) { - // In overflow, make sure we don't store any more objects. - if t.trackOverflow { - return - } - - // If this would overflow the state we reject it and set the flag (since - // we aren't tracking everything that's required any longer). - if len(t.trackChannels) >= defaultModifiedCache { - // Mark that we are in the overflow state - t.trackOverflow = true - - // Clear the map so that the channels can be garbage collected. It is - // safe to do this since we have already overflowed and will be using - // the slow notify algorithm. - t.trackChannels = nil - return - } - - // Create the map on the fly when we need it. - if t.trackChannels == nil { - t.trackChannels = make(map[chan struct{}]struct{}) - } - - // Otherwise we are good to track it. - t.trackChannels[ch] = struct{}{} -} - -// writeNode returns a node to be modified, if the current node has already been -// modified during the course of the transaction, it is used in-place. Set -// forLeafUpdate to true if you are getting a write node to update the leaf, -// which will set leaf mutation tracking appropriately as well. -func (t *Txn) writeNode(n *Node, forLeafUpdate bool) *Node { - // Ensure the writable set exists. - if t.writable == nil { - lru, err := simplelru.NewLRU(defaultModifiedCache, nil) - if err != nil { - panic(err) - } - t.writable = lru - } - - // If this node has already been modified, we can continue to use it - // during this transaction. We know that we don't need to track it for - // a node update since the node is writable, but if this is for a leaf - // update we track it, in case the initial write to this node didn't - // update the leaf. - if _, ok := t.writable.Get(n); ok { - if t.trackMutate && forLeafUpdate && n.leaf != nil { - t.trackChannel(n.leaf.mutateCh) - } - return n - } - - // Mark this node as being mutated. - if t.trackMutate { - t.trackChannel(n.mutateCh) - } - - // Mark its leaf as being mutated, if appropriate. - if t.trackMutate && forLeafUpdate && n.leaf != nil { - t.trackChannel(n.leaf.mutateCh) - } - - // Copy the existing node. If you have set forLeafUpdate it will be - // safe to replace this leaf with another after you get your node for - // writing. You MUST replace it, because the channel associated with - // this leaf will be closed when this transaction is committed. - nc := &Node{ - mutateCh: make(chan struct{}), - leaf: n.leaf, - } - if n.prefix != nil { - nc.prefix = make([]byte, len(n.prefix)) - copy(nc.prefix, n.prefix) - } - if len(n.edges) != 0 { - nc.edges = make([]edge, len(n.edges)) - copy(nc.edges, n.edges) - } - - // Mark this node as writable. - t.writable.Add(nc, nil) - return nc -} - -// Visit all the nodes in the tree under n, and add their mutateChannels to the transaction -// Returns the size of the subtree visited -func (t *Txn) trackChannelsAndCount(n *Node) int { - // Count only leaf nodes - leaves := 0 - if n.leaf != nil { - leaves = 1 - } - // Mark this node as being mutated. - if t.trackMutate { - t.trackChannel(n.mutateCh) - } - - // Mark its leaf as being mutated, if appropriate. - if t.trackMutate && n.leaf != nil { - t.trackChannel(n.leaf.mutateCh) - } - - // Recurse on the children - for _, e := range n.edges { - leaves += t.trackChannelsAndCount(e.node) - } - return leaves -} - -// mergeChild is called to collapse the given node with its child. This is only -// called when the given node is not a leaf and has a single edge. -func (t *Txn) mergeChild(n *Node) { - // Mark the child node as being mutated since we are about to abandon - // it. We don't need to mark the leaf since we are retaining it if it - // is there. - e := n.edges[0] - child := e.node - if t.trackMutate { - t.trackChannel(child.mutateCh) - } - - // Merge the nodes. - n.prefix = concat(n.prefix, child.prefix) - n.leaf = child.leaf - if len(child.edges) != 0 { - n.edges = make([]edge, len(child.edges)) - copy(n.edges, child.edges) - } else { - n.edges = nil - } -} - -// insert does a recursive insertion -func (t *Txn) insert(n *Node, k, search []byte, v interface{}) (*Node, interface{}, bool) { - // Handle key exhaustion - if len(search) == 0 { - var oldVal interface{} - didUpdate := false - if n.isLeaf() { - oldVal = n.leaf.val - didUpdate = true - } - - nc := t.writeNode(n, true) - nc.leaf = &leafNode{ - mutateCh: make(chan struct{}), - key: k, - val: v, - } - return nc, oldVal, didUpdate - } - - // Look for the edge - idx, child := n.getEdge(search[0]) - - // No edge, create one - if child == nil { - e := edge{ - label: search[0], - node: &Node{ - mutateCh: make(chan struct{}), - leaf: &leafNode{ - mutateCh: make(chan struct{}), - key: k, - val: v, - }, - prefix: search, - }, - } - nc := t.writeNode(n, false) - nc.addEdge(e) - return nc, nil, false - } - - // Determine longest prefix of the search key on match - commonPrefix := longestPrefix(search, child.prefix) - if commonPrefix == len(child.prefix) { - search = search[commonPrefix:] - newChild, oldVal, didUpdate := t.insert(child, k, search, v) - if newChild != nil { - nc := t.writeNode(n, false) - nc.edges[idx].node = newChild - return nc, oldVal, didUpdate - } - return nil, oldVal, didUpdate - } - - // Split the node - nc := t.writeNode(n, false) - splitNode := &Node{ - mutateCh: make(chan struct{}), - prefix: search[:commonPrefix], - } - nc.replaceEdge(edge{ - label: search[0], - node: splitNode, - }) - - // Restore the existing child node - modChild := t.writeNode(child, false) - splitNode.addEdge(edge{ - label: modChild.prefix[commonPrefix], - node: modChild, - }) - modChild.prefix = modChild.prefix[commonPrefix:] - - // Create a new leaf node - leaf := &leafNode{ - mutateCh: make(chan struct{}), - key: k, - val: v, - } - - // If the new key is a subset, add to to this node - search = search[commonPrefix:] - if len(search) == 0 { - splitNode.leaf = leaf - return nc, nil, false - } - - // Create a new edge for the node - splitNode.addEdge(edge{ - label: search[0], - node: &Node{ - mutateCh: make(chan struct{}), - leaf: leaf, - prefix: search, - }, - }) - return nc, nil, false -} - -// delete does a recursive deletion -func (t *Txn) delete(parent, n *Node, search []byte) (*Node, *leafNode) { - // Check for key exhaustion - if len(search) == 0 { - if !n.isLeaf() { - return nil, nil - } - // Copy the pointer in case we are in a transaction that already - // modified this node since the node will be reused. Any changes - // made to the node will not affect returning the original leaf - // value. - oldLeaf := n.leaf - - // Remove the leaf node - nc := t.writeNode(n, true) - nc.leaf = nil - - // Check if this node should be merged - if n != t.root && len(nc.edges) == 1 { - t.mergeChild(nc) - } - return nc, oldLeaf - } - - // Look for an edge - label := search[0] - idx, child := n.getEdge(label) - if child == nil || !bytes.HasPrefix(search, child.prefix) { - return nil, nil - } - - // Consume the search prefix - search = search[len(child.prefix):] - newChild, leaf := t.delete(n, child, search) - if newChild == nil { - return nil, nil - } - - // Copy this node. WATCH OUT - it's safe to pass "false" here because we - // will only ADD a leaf via nc.mergeChild() if there isn't one due to - // the !nc.isLeaf() check in the logic just below. This is pretty subtle, - // so be careful if you change any of the logic here. - nc := t.writeNode(n, false) - - // Delete the edge if the node has no edges - if newChild.leaf == nil && len(newChild.edges) == 0 { - nc.delEdge(label) - if n != t.root && len(nc.edges) == 1 && !nc.isLeaf() { - t.mergeChild(nc) - } - } else { - nc.edges[idx].node = newChild - } - return nc, leaf -} - -// delete does a recursive deletion -func (t *Txn) deletePrefix(parent, n *Node, search []byte) (*Node, int) { - // Check for key exhaustion - if len(search) == 0 { - nc := t.writeNode(n, true) - if n.isLeaf() { - nc.leaf = nil - } - nc.edges = nil - return nc, t.trackChannelsAndCount(n) - } - - // Look for an edge - label := search[0] - idx, child := n.getEdge(label) - // We make sure that either the child node's prefix starts with the search term, or the search term starts with the child node's prefix - // Need to do both so that we can delete prefixes that don't correspond to any node in the tree - if child == nil || (!bytes.HasPrefix(child.prefix, search) && !bytes.HasPrefix(search, child.prefix)) { - return nil, 0 - } - - // Consume the search prefix - if len(child.prefix) > len(search) { - search = []byte("") - } else { - search = search[len(child.prefix):] - } - newChild, numDeletions := t.deletePrefix(n, child, search) - if newChild == nil { - return nil, 0 - } - // Copy this node. WATCH OUT - it's safe to pass "false" here because we - // will only ADD a leaf via nc.mergeChild() if there isn't one due to - // the !nc.isLeaf() check in the logic just below. This is pretty subtle, - // so be careful if you change any of the logic here. - - nc := t.writeNode(n, false) - - // Delete the edge if the node has no edges - if newChild.leaf == nil && len(newChild.edges) == 0 { - nc.delEdge(label) - if n != t.root && len(nc.edges) == 1 && !nc.isLeaf() { - t.mergeChild(nc) - } - } else { - nc.edges[idx].node = newChild - } - return nc, numDeletions -} - -// Insert is used to add or update a given key. The return provides -// the previous value and a bool indicating if any was set. -func (t *Txn) Insert(k []byte, v interface{}) (interface{}, bool) { - newRoot, oldVal, didUpdate := t.insert(t.root, k, k, v) - if newRoot != nil { - t.root = newRoot - } - if !didUpdate { - t.size++ - } - return oldVal, didUpdate -} - -// Delete is used to delete a given key. Returns the old value if any, -// and a bool indicating if the key was set. -func (t *Txn) Delete(k []byte) (interface{}, bool) { - newRoot, leaf := t.delete(nil, t.root, k) - if newRoot != nil { - t.root = newRoot - } - if leaf != nil { - t.size-- - return leaf.val, true - } - return nil, false -} - -// DeletePrefix is used to delete an entire subtree that matches the prefix -// This will delete all nodes under that prefix -func (t *Txn) DeletePrefix(prefix []byte) bool { - newRoot, numDeletions := t.deletePrefix(nil, t.root, prefix) - if newRoot != nil { - t.root = newRoot - t.size = t.size - numDeletions - return true - } - return false - -} - -// Root returns the current root of the radix tree within this -// transaction. The root is not safe across insert and delete operations, -// but can be used to read the current state during a transaction. -func (t *Txn) Root() *Node { - return t.root -} - -// Get is used to lookup a specific key, returning -// the value and if it was found -func (t *Txn) Get(k []byte) (interface{}, bool) { - return t.root.Get(k) -} - -// GetWatch is used to lookup a specific key, returning -// the watch channel, value and if it was found -func (t *Txn) GetWatch(k []byte) (<-chan struct{}, interface{}, bool) { - return t.root.GetWatch(k) -} - -// Commit is used to finalize the transaction and return a new tree. If mutation -// tracking is turned on then notifications will also be issued. -func (t *Txn) Commit() *Tree { - nt := t.CommitOnly() - if t.trackMutate { - t.Notify() - } - return nt -} - -// CommitOnly is used to finalize the transaction and return a new tree, but -// does not issue any notifications until Notify is called. -func (t *Txn) CommitOnly() *Tree { - nt := &Tree{t.root, t.size} - t.writable = nil - return nt -} - -// slowNotify does a complete comparison of the before and after trees in order -// to trigger notifications. This doesn't require any additional state but it -// is very expensive to compute. -func (t *Txn) slowNotify() { - snapIter := t.snap.rawIterator() - rootIter := t.root.rawIterator() - for snapIter.Front() != nil || rootIter.Front() != nil { - // If we've exhausted the nodes in the old snapshot, we know - // there's nothing remaining to notify. - if snapIter.Front() == nil { - return - } - snapElem := snapIter.Front() - - // If we've exhausted the nodes in the new root, we know we need - // to invalidate everything that remains in the old snapshot. We - // know from the loop condition there's something in the old - // snapshot. - if rootIter.Front() == nil { - close(snapElem.mutateCh) - if snapElem.isLeaf() { - close(snapElem.leaf.mutateCh) - } - snapIter.Next() - continue - } - - // Do one string compare so we can check the various conditions - // below without repeating the compare. - cmp := strings.Compare(snapIter.Path(), rootIter.Path()) - - // If the snapshot is behind the root, then we must have deleted - // this node during the transaction. - if cmp < 0 { - close(snapElem.mutateCh) - if snapElem.isLeaf() { - close(snapElem.leaf.mutateCh) - } - snapIter.Next() - continue - } - - // If the snapshot is ahead of the root, then we must have added - // this node during the transaction. - if cmp > 0 { - rootIter.Next() - continue - } - - // If we have the same path, then we need to see if we mutated a - // node and possibly the leaf. - rootElem := rootIter.Front() - if snapElem != rootElem { - close(snapElem.mutateCh) - if snapElem.leaf != nil && (snapElem.leaf != rootElem.leaf) { - close(snapElem.leaf.mutateCh) - } - } - snapIter.Next() - rootIter.Next() - } -} - -// Notify is used along with TrackMutate to trigger notifications. This must -// only be done once a transaction is committed via CommitOnly, and it is called -// automatically by Commit. -func (t *Txn) Notify() { - if !t.trackMutate { - return - } - - // If we've overflowed the tracking state we can't use it in any way and - // need to do a full tree compare. - if t.trackOverflow { - t.slowNotify() - } else { - for ch := range t.trackChannels { - close(ch) - } - } - - // Clean up the tracking state so that a re-notify is safe (will trigger - // the else clause above which will be a no-op). - t.trackChannels = nil - t.trackOverflow = false -} - -// Insert is used to add or update a given key. The return provides -// the new tree, previous value and a bool indicating if any was set. -func (t *Tree) Insert(k []byte, v interface{}) (*Tree, interface{}, bool) { - txn := t.Txn() - old, ok := txn.Insert(k, v) - return txn.Commit(), old, ok -} - -// Delete is used to delete a given key. Returns the new tree, -// old value if any, and a bool indicating if the key was set. -func (t *Tree) Delete(k []byte) (*Tree, interface{}, bool) { - txn := t.Txn() - old, ok := txn.Delete(k) - return txn.Commit(), old, ok -} - -// DeletePrefix is used to delete all nodes starting with a given prefix. Returns the new tree, -// and a bool indicating if the prefix matched any nodes -func (t *Tree) DeletePrefix(k []byte) (*Tree, bool) { - txn := t.Txn() - ok := txn.DeletePrefix(k) - return txn.Commit(), ok -} - -// Root returns the root node of the tree which can be used for richer -// query operations. -func (t *Tree) Root() *Node { - return t.root -} - -// Get is used to lookup a specific key, returning -// the value and if it was found -func (t *Tree) Get(k []byte) (interface{}, bool) { - return t.root.Get(k) -} - -// longestPrefix finds the length of the shared prefix -// of two strings -func longestPrefix(k1, k2 []byte) int { - max := len(k1) - if l := len(k2); l < max { - max = l - } - var i int - for i = 0; i < max; i++ { - if k1[i] != k2[i] { - break - } - } - return i -} - -// concat two byte slices, returning a third new copy -func concat(a, b []byte) []byte { - c := make([]byte, len(a)+len(b)) - copy(c, a) - copy(c[len(a):], b) - return c -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/iter.go b/vendor/github.com/hashicorp/go-immutable-radix/iter.go deleted file mode 100644 index f17d0a644f46b..0000000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/iter.go +++ /dev/null @@ -1,205 +0,0 @@ -package iradix - -import ( - "bytes" -) - -// Iterator is used to iterate over a set of nodes -// in pre-order -type Iterator struct { - node *Node - stack []edges -} - -// SeekPrefixWatch is used to seek the iterator to a given prefix -// and returns the watch channel of the finest granularity -func (i *Iterator) SeekPrefixWatch(prefix []byte) (watch <-chan struct{}) { - // Wipe the stack - i.stack = nil - n := i.node - watch = n.mutateCh - search := prefix - for { - // Check for key exhaustion - if len(search) == 0 { - i.node = n - return - } - - // Look for an edge - _, n = n.getEdge(search[0]) - if n == nil { - i.node = nil - return - } - - // Update to the finest granularity as the search makes progress - watch = n.mutateCh - - // Consume the search prefix - if bytes.HasPrefix(search, n.prefix) { - search = search[len(n.prefix):] - - } else if bytes.HasPrefix(n.prefix, search) { - i.node = n - return - } else { - i.node = nil - return - } - } -} - -// SeekPrefix is used to seek the iterator to a given prefix -func (i *Iterator) SeekPrefix(prefix []byte) { - i.SeekPrefixWatch(prefix) -} - -func (i *Iterator) recurseMin(n *Node) *Node { - // Traverse to the minimum child - if n.leaf != nil { - return n - } - nEdges := len(n.edges) - if nEdges > 1 { - // Add all the other edges to the stack (the min node will be added as - // we recurse) - i.stack = append(i.stack, n.edges[1:]) - } - if nEdges > 0 { - return i.recurseMin(n.edges[0].node) - } - // Shouldn't be possible - return nil -} - -// SeekLowerBound is used to seek the iterator to the smallest key that is -// greater or equal to the given key. There is no watch variant as it's hard to -// predict based on the radix structure which node(s) changes might affect the -// result. -func (i *Iterator) SeekLowerBound(key []byte) { - // Wipe the stack. Unlike Prefix iteration, we need to build the stack as we - // go because we need only a subset of edges of many nodes in the path to the - // leaf with the lower bound. Note that the iterator will still recurse into - // children that we don't traverse on the way to the reverse lower bound as it - // walks the stack. - i.stack = []edges{} - // i.node starts off in the common case as pointing to the root node of the - // tree. By the time we return we have either found a lower bound and setup - // the stack to traverse all larger keys, or we have not and the stack and - // node should both be nil to prevent the iterator from assuming it is just - // iterating the whole tree from the root node. Either way this needs to end - // up as nil so just set it here. - n := i.node - i.node = nil - search := key - - found := func(n *Node) { - i.stack = append(i.stack, edges{edge{node: n}}) - } - - findMin := func(n *Node) { - n = i.recurseMin(n) - if n != nil { - found(n) - return - } - } - - for { - // Compare current prefix with the search key's same-length prefix. - var prefixCmp int - if len(n.prefix) < len(search) { - prefixCmp = bytes.Compare(n.prefix, search[0:len(n.prefix)]) - } else { - prefixCmp = bytes.Compare(n.prefix, search) - } - - if prefixCmp > 0 { - // Prefix is larger, that means the lower bound is greater than the search - // and from now on we need to follow the minimum path to the smallest - // leaf under this subtree. - findMin(n) - return - } - - if prefixCmp < 0 { - // Prefix is smaller than search prefix, that means there is no lower - // bound - i.node = nil - return - } - - // Prefix is equal, we are still heading for an exact match. If this is a - // leaf and an exact match we're done. - if n.leaf != nil && bytes.Equal(n.leaf.key, key) { - found(n) - return - } - - // Consume the search prefix if the current node has one. Note that this is - // safe because if n.prefix is longer than the search slice prefixCmp would - // have been > 0 above and the method would have already returned. - search = search[len(n.prefix):] - - if len(search) == 0 { - // We've exhausted the search key, but the current node is not an exact - // match or not a leaf. That means that the leaf value if it exists, and - // all child nodes must be strictly greater, the smallest key in this - // subtree must be the lower bound. - findMin(n) - return - } - - // Otherwise, take the lower bound next edge. - idx, lbNode := n.getLowerBoundEdge(search[0]) - if lbNode == nil { - return - } - - // Create stack edges for the all strictly higher edges in this node. - if idx+1 < len(n.edges) { - i.stack = append(i.stack, n.edges[idx+1:]) - } - - // Recurse - n = lbNode - } -} - -// Next returns the next node in order -func (i *Iterator) Next() ([]byte, interface{}, bool) { - // Initialize our stack if needed - if i.stack == nil && i.node != nil { - i.stack = []edges{ - { - edge{node: i.node}, - }, - } - } - - for len(i.stack) > 0 { - // Inspect the last element of the stack - n := len(i.stack) - last := i.stack[n-1] - elem := last[0].node - - // Update the stack - if len(last) > 1 { - i.stack[n-1] = last[1:] - } else { - i.stack = i.stack[:n-1] - } - - // Push the edges onto the frontier - if len(elem.edges) > 0 { - i.stack = append(i.stack, elem.edges) - } - - // Return the leaf values if any - if elem.leaf != nil { - return elem.leaf.key, elem.leaf.val, true - } - } - return nil, nil, false -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/node.go b/vendor/github.com/hashicorp/go-immutable-radix/node.go deleted file mode 100644 index 35985480872c0..0000000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/node.go +++ /dev/null @@ -1,334 +0,0 @@ -package iradix - -import ( - "bytes" - "sort" -) - -// WalkFn is used when walking the tree. Takes a -// key and value, returning if iteration should -// be terminated. -type WalkFn func(k []byte, v interface{}) bool - -// leafNode is used to represent a value -type leafNode struct { - mutateCh chan struct{} - key []byte - val interface{} -} - -// edge is used to represent an edge node -type edge struct { - label byte - node *Node -} - -// Node is an immutable node in the radix tree -type Node struct { - // mutateCh is closed if this node is modified - mutateCh chan struct{} - - // leaf is used to store possible leaf - leaf *leafNode - - // prefix is the common prefix we ignore - prefix []byte - - // Edges should be stored in-order for iteration. - // We avoid a fully materialized slice to save memory, - // since in most cases we expect to be sparse - edges edges -} - -func (n *Node) isLeaf() bool { - return n.leaf != nil -} - -func (n *Node) addEdge(e edge) { - num := len(n.edges) - idx := sort.Search(num, func(i int) bool { - return n.edges[i].label >= e.label - }) - n.edges = append(n.edges, e) - if idx != num { - copy(n.edges[idx+1:], n.edges[idx:num]) - n.edges[idx] = e - } -} - -func (n *Node) replaceEdge(e edge) { - num := len(n.edges) - idx := sort.Search(num, func(i int) bool { - return n.edges[i].label >= e.label - }) - if idx < num && n.edges[idx].label == e.label { - n.edges[idx].node = e.node - return - } - panic("replacing missing edge") -} - -func (n *Node) getEdge(label byte) (int, *Node) { - num := len(n.edges) - idx := sort.Search(num, func(i int) bool { - return n.edges[i].label >= label - }) - if idx < num && n.edges[idx].label == label { - return idx, n.edges[idx].node - } - return -1, nil -} - -func (n *Node) getLowerBoundEdge(label byte) (int, *Node) { - num := len(n.edges) - idx := sort.Search(num, func(i int) bool { - return n.edges[i].label >= label - }) - // we want lower bound behavior so return even if it's not an exact match - if idx < num { - return idx, n.edges[idx].node - } - return -1, nil -} - -func (n *Node) delEdge(label byte) { - num := len(n.edges) - idx := sort.Search(num, func(i int) bool { - return n.edges[i].label >= label - }) - if idx < num && n.edges[idx].label == label { - copy(n.edges[idx:], n.edges[idx+1:]) - n.edges[len(n.edges)-1] = edge{} - n.edges = n.edges[:len(n.edges)-1] - } -} - -func (n *Node) GetWatch(k []byte) (<-chan struct{}, interface{}, bool) { - search := k - watch := n.mutateCh - for { - // Check for key exhaustion - if len(search) == 0 { - if n.isLeaf() { - return n.leaf.mutateCh, n.leaf.val, true - } - break - } - - // Look for an edge - _, n = n.getEdge(search[0]) - if n == nil { - break - } - - // Update to the finest granularity as the search makes progress - watch = n.mutateCh - - // Consume the search prefix - if bytes.HasPrefix(search, n.prefix) { - search = search[len(n.prefix):] - } else { - break - } - } - return watch, nil, false -} - -func (n *Node) Get(k []byte) (interface{}, bool) { - _, val, ok := n.GetWatch(k) - return val, ok -} - -// LongestPrefix is like Get, but instead of an -// exact match, it will return the longest prefix match. -func (n *Node) LongestPrefix(k []byte) ([]byte, interface{}, bool) { - var last *leafNode - search := k - for { - // Look for a leaf node - if n.isLeaf() { - last = n.leaf - } - - // Check for key exhaution - if len(search) == 0 { - break - } - - // Look for an edge - _, n = n.getEdge(search[0]) - if n == nil { - break - } - - // Consume the search prefix - if bytes.HasPrefix(search, n.prefix) { - search = search[len(n.prefix):] - } else { - break - } - } - if last != nil { - return last.key, last.val, true - } - return nil, nil, false -} - -// Minimum is used to return the minimum value in the tree -func (n *Node) Minimum() ([]byte, interface{}, bool) { - for { - if n.isLeaf() { - return n.leaf.key, n.leaf.val, true - } - if len(n.edges) > 0 { - n = n.edges[0].node - } else { - break - } - } - return nil, nil, false -} - -// Maximum is used to return the maximum value in the tree -func (n *Node) Maximum() ([]byte, interface{}, bool) { - for { - if num := len(n.edges); num > 0 { - n = n.edges[num-1].node - continue - } - if n.isLeaf() { - return n.leaf.key, n.leaf.val, true - } else { - break - } - } - return nil, nil, false -} - -// Iterator is used to return an iterator at -// the given node to walk the tree -func (n *Node) Iterator() *Iterator { - return &Iterator{node: n} -} - -// ReverseIterator is used to return an iterator at -// the given node to walk the tree backwards -func (n *Node) ReverseIterator() *ReverseIterator { - return NewReverseIterator(n) -} - -// rawIterator is used to return a raw iterator at the given node to walk the -// tree. -func (n *Node) rawIterator() *rawIterator { - iter := &rawIterator{node: n} - iter.Next() - return iter -} - -// Walk is used to walk the tree -func (n *Node) Walk(fn WalkFn) { - recursiveWalk(n, fn) -} - -// WalkBackwards is used to walk the tree in reverse order -func (n *Node) WalkBackwards(fn WalkFn) { - reverseRecursiveWalk(n, fn) -} - -// WalkPrefix is used to walk the tree under a prefix -func (n *Node) WalkPrefix(prefix []byte, fn WalkFn) { - search := prefix - for { - // Check for key exhaution - if len(search) == 0 { - recursiveWalk(n, fn) - return - } - - // Look for an edge - _, n = n.getEdge(search[0]) - if n == nil { - break - } - - // Consume the search prefix - if bytes.HasPrefix(search, n.prefix) { - search = search[len(n.prefix):] - - } else if bytes.HasPrefix(n.prefix, search) { - // Child may be under our search prefix - recursiveWalk(n, fn) - return - } else { - break - } - } -} - -// WalkPath is used to walk the tree, but only visiting nodes -// from the root down to a given leaf. Where WalkPrefix walks -// all the entries *under* the given prefix, this walks the -// entries *above* the given prefix. -func (n *Node) WalkPath(path []byte, fn WalkFn) { - search := path - for { - // Visit the leaf values if any - if n.leaf != nil && fn(n.leaf.key, n.leaf.val) { - return - } - - // Check for key exhaution - if len(search) == 0 { - return - } - - // Look for an edge - _, n = n.getEdge(search[0]) - if n == nil { - return - } - - // Consume the search prefix - if bytes.HasPrefix(search, n.prefix) { - search = search[len(n.prefix):] - } else { - break - } - } -} - -// recursiveWalk is used to do a pre-order walk of a node -// recursively. Returns true if the walk should be aborted -func recursiveWalk(n *Node, fn WalkFn) bool { - // Visit the leaf values if any - if n.leaf != nil && fn(n.leaf.key, n.leaf.val) { - return true - } - - // Recurse on the children - for _, e := range n.edges { - if recursiveWalk(e.node, fn) { - return true - } - } - return false -} - -// reverseRecursiveWalk is used to do a reverse pre-order -// walk of a node recursively. Returns true if the walk -// should be aborted -func reverseRecursiveWalk(n *Node, fn WalkFn) bool { - // Visit the leaf values if any - if n.leaf != nil && fn(n.leaf.key, n.leaf.val) { - return true - } - - // Recurse on the children in reverse order - for i := len(n.edges) - 1; i >= 0; i-- { - e := n.edges[i] - if reverseRecursiveWalk(e.node, fn) { - return true - } - } - return false -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/raw_iter.go b/vendor/github.com/hashicorp/go-immutable-radix/raw_iter.go deleted file mode 100644 index 3c6a22525c8ea..0000000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/raw_iter.go +++ /dev/null @@ -1,78 +0,0 @@ -package iradix - -// rawIterator visits each of the nodes in the tree, even the ones that are not -// leaves. It keeps track of the effective path (what a leaf at a given node -// would be called), which is useful for comparing trees. -type rawIterator struct { - // node is the starting node in the tree for the iterator. - node *Node - - // stack keeps track of edges in the frontier. - stack []rawStackEntry - - // pos is the current position of the iterator. - pos *Node - - // path is the effective path of the current iterator position, - // regardless of whether the current node is a leaf. - path string -} - -// rawStackEntry is used to keep track of the cumulative common path as well as -// its associated edges in the frontier. -type rawStackEntry struct { - path string - edges edges -} - -// Front returns the current node that has been iterated to. -func (i *rawIterator) Front() *Node { - return i.pos -} - -// Path returns the effective path of the current node, even if it's not actually -// a leaf. -func (i *rawIterator) Path() string { - return i.path -} - -// Next advances the iterator to the next node. -func (i *rawIterator) Next() { - // Initialize our stack if needed. - if i.stack == nil && i.node != nil { - i.stack = []rawStackEntry{ - { - edges: edges{ - edge{node: i.node}, - }, - }, - } - } - - for len(i.stack) > 0 { - // Inspect the last element of the stack. - n := len(i.stack) - last := i.stack[n-1] - elem := last.edges[0].node - - // Update the stack. - if len(last.edges) > 1 { - i.stack[n-1].edges = last.edges[1:] - } else { - i.stack = i.stack[:n-1] - } - - // Push the edges onto the frontier. - if len(elem.edges) > 0 { - path := last.path + string(elem.prefix) - i.stack = append(i.stack, rawStackEntry{path, elem.edges}) - } - - i.pos = elem - i.path = last.path + string(elem.prefix) - return - } - - i.pos = nil - i.path = "" -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/reverse_iter.go b/vendor/github.com/hashicorp/go-immutable-radix/reverse_iter.go deleted file mode 100644 index 554fa7129c1c5..0000000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/reverse_iter.go +++ /dev/null @@ -1,239 +0,0 @@ -package iradix - -import ( - "bytes" -) - -// ReverseIterator is used to iterate over a set of nodes -// in reverse in-order -type ReverseIterator struct { - i *Iterator - - // expandedParents stores the set of parent nodes whose relevant children have - // already been pushed into the stack. This can happen during seek or during - // iteration. - // - // Unlike forward iteration we need to recurse into children before we can - // output the value stored in an internal leaf since all children are greater. - // We use this to track whether we have already ensured all the children are - // in the stack. - expandedParents map[*Node]struct{} -} - -// NewReverseIterator returns a new ReverseIterator at a node -func NewReverseIterator(n *Node) *ReverseIterator { - return &ReverseIterator{ - i: &Iterator{node: n}, - } -} - -// SeekPrefixWatch is used to seek the iterator to a given prefix -// and returns the watch channel of the finest granularity -func (ri *ReverseIterator) SeekPrefixWatch(prefix []byte) (watch <-chan struct{}) { - return ri.i.SeekPrefixWatch(prefix) -} - -// SeekPrefix is used to seek the iterator to a given prefix -func (ri *ReverseIterator) SeekPrefix(prefix []byte) { - ri.i.SeekPrefixWatch(prefix) -} - -// SeekReverseLowerBound is used to seek the iterator to the largest key that is -// lower or equal to the given key. There is no watch variant as it's hard to -// predict based on the radix structure which node(s) changes might affect the -// result. -func (ri *ReverseIterator) SeekReverseLowerBound(key []byte) { - // Wipe the stack. Unlike Prefix iteration, we need to build the stack as we - // go because we need only a subset of edges of many nodes in the path to the - // leaf with the lower bound. Note that the iterator will still recurse into - // children that we don't traverse on the way to the reverse lower bound as it - // walks the stack. - ri.i.stack = []edges{} - // ri.i.node starts off in the common case as pointing to the root node of the - // tree. By the time we return we have either found a lower bound and setup - // the stack to traverse all larger keys, or we have not and the stack and - // node should both be nil to prevent the iterator from assuming it is just - // iterating the whole tree from the root node. Either way this needs to end - // up as nil so just set it here. - n := ri.i.node - ri.i.node = nil - search := key - - if ri.expandedParents == nil { - ri.expandedParents = make(map[*Node]struct{}) - } - - found := func(n *Node) { - ri.i.stack = append(ri.i.stack, edges{edge{node: n}}) - // We need to mark this node as expanded in advance too otherwise the - // iterator will attempt to walk all of its children even though they are - // greater than the lower bound we have found. We've expanded it in the - // sense that all of its children that we want to walk are already in the - // stack (i.e. none of them). - ri.expandedParents[n] = struct{}{} - } - - for { - // Compare current prefix with the search key's same-length prefix. - var prefixCmp int - if len(n.prefix) < len(search) { - prefixCmp = bytes.Compare(n.prefix, search[0:len(n.prefix)]) - } else { - prefixCmp = bytes.Compare(n.prefix, search) - } - - if prefixCmp < 0 { - // Prefix is smaller than search prefix, that means there is no exact - // match for the search key. But we are looking in reverse, so the reverse - // lower bound will be the largest leaf under this subtree, since it is - // the value that would come right before the current search key if it - // were in the tree. So we need to follow the maximum path in this subtree - // to find it. Note that this is exactly what the iterator will already do - // if it finds a node in the stack that has _not_ been marked as expanded - // so in this one case we don't call `found` and instead let the iterator - // do the expansion and recursion through all the children. - ri.i.stack = append(ri.i.stack, edges{edge{node: n}}) - return - } - - if prefixCmp > 0 { - // Prefix is larger than search prefix, or there is no prefix but we've - // also exhausted the search key. Either way, that means there is no - // reverse lower bound since nothing comes before our current search - // prefix. - return - } - - // If this is a leaf, something needs to happen! Note that if it's a leaf - // and prefixCmp was zero (which it must be to get here) then the leaf value - // is either an exact match for the search, or it's lower. It can't be - // greater. - if n.isLeaf() { - - // Firstly, if it's an exact match, we're done! - if bytes.Equal(n.leaf.key, key) { - found(n) - return - } - - // It's not so this node's leaf value must be lower and could still be a - // valid contender for reverse lower bound. - - // If it has no children then we are also done. - if len(n.edges) == 0 { - // This leaf is the lower bound. - found(n) - return - } - - // Finally, this leaf is internal (has children) so we'll keep searching, - // but we need to add it to the iterator's stack since it has a leaf value - // that needs to be iterated over. It needs to be added to the stack - // before its children below as it comes first. - ri.i.stack = append(ri.i.stack, edges{edge{node: n}}) - // We also need to mark it as expanded since we'll be adding any of its - // relevant children below and so don't want the iterator to re-add them - // on its way back up the stack. - ri.expandedParents[n] = struct{}{} - } - - // Consume the search prefix. Note that this is safe because if n.prefix is - // longer than the search slice prefixCmp would have been > 0 above and the - // method would have already returned. - search = search[len(n.prefix):] - - if len(search) == 0 { - // We've exhausted the search key but we are not at a leaf. That means all - // children are greater than the search key so a reverse lower bound - // doesn't exist in this subtree. Note that there might still be one in - // the whole radix tree by following a different path somewhere further - // up. If that's the case then the iterator's stack will contain all the - // smaller nodes already and Previous will walk through them correctly. - return - } - - // Otherwise, take the lower bound next edge. - idx, lbNode := n.getLowerBoundEdge(search[0]) - - // From here, we need to update the stack with all values lower than - // the lower bound edge. Since getLowerBoundEdge() returns -1 when the - // search prefix is larger than all edges, we need to place idx at the - // last edge index so they can all be place in the stack, since they - // come before our search prefix. - if idx == -1 { - idx = len(n.edges) - } - - // Create stack edges for the all strictly lower edges in this node. - if len(n.edges[:idx]) > 0 { - ri.i.stack = append(ri.i.stack, n.edges[:idx]) - } - - // Exit if there's no lower bound edge. The stack will have the previous - // nodes already. - if lbNode == nil { - return - } - - // Recurse - n = lbNode - } -} - -// Previous returns the previous node in reverse order -func (ri *ReverseIterator) Previous() ([]byte, interface{}, bool) { - // Initialize our stack if needed - if ri.i.stack == nil && ri.i.node != nil { - ri.i.stack = []edges{ - { - edge{node: ri.i.node}, - }, - } - } - - if ri.expandedParents == nil { - ri.expandedParents = make(map[*Node]struct{}) - } - - for len(ri.i.stack) > 0 { - // Inspect the last element of the stack - n := len(ri.i.stack) - last := ri.i.stack[n-1] - m := len(last) - elem := last[m-1].node - - _, alreadyExpanded := ri.expandedParents[elem] - - // If this is an internal node and we've not seen it already, we need to - // leave it in the stack so we can return its possible leaf value _after_ - // we've recursed through all its children. - if len(elem.edges) > 0 && !alreadyExpanded { - // record that we've seen this node! - ri.expandedParents[elem] = struct{}{} - // push child edges onto stack and skip the rest of the loop to recurse - // into the largest one. - ri.i.stack = append(ri.i.stack, elem.edges) - continue - } - - // Remove the node from the stack - if m > 1 { - ri.i.stack[n-1] = last[:m-1] - } else { - ri.i.stack = ri.i.stack[:n-1] - } - // We don't need this state any more as it's no longer in the stack so we - // won't visit it again - if alreadyExpanded { - delete(ri.expandedParents, elem) - } - - // If this is a leaf, return it - if elem.leaf != nil { - return elem.leaf.key, elem.leaf.val, true - } - - // it's not a leaf so keep walking the stack to find the previous leaf - } - return nil, nil, false -} diff --git a/vendor/github.com/hashicorp/go-rootcerts/.travis.yml b/vendor/github.com/hashicorp/go-rootcerts/.travis.yml deleted file mode 100644 index 80e1de44e96d3..0000000000000 --- a/vendor/github.com/hashicorp/go-rootcerts/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -sudo: false - -language: go - -go: - - 1.6 - -branches: - only: - - master - -script: make test diff --git a/vendor/github.com/hashicorp/go-rootcerts/LICENSE b/vendor/github.com/hashicorp/go-rootcerts/LICENSE deleted file mode 100644 index e87a115e462e1..0000000000000 --- a/vendor/github.com/hashicorp/go-rootcerts/LICENSE +++ /dev/null @@ -1,363 +0,0 @@ -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. "Contributor" - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. "Contributor Version" - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. - -1.6. "Executable Form" - - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. - -1.8. "License" - - means this document. - -1.9. "Licensable" - - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. - -1.10. "Modifications" - - means any of the following: - - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. "Patent Claims" of a Contributor - - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. - -1.12. "Secondary License" - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. "Source Code Form" - - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. - - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice - - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. - diff --git a/vendor/github.com/hashicorp/go-rootcerts/Makefile b/vendor/github.com/hashicorp/go-rootcerts/Makefile deleted file mode 100644 index c3989e789f690..0000000000000 --- a/vendor/github.com/hashicorp/go-rootcerts/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -TEST?=./... - -test: - go test $(TEST) $(TESTARGS) -timeout=3s -parallel=4 - go vet $(TEST) - go test $(TEST) -race - -.PHONY: test diff --git a/vendor/github.com/hashicorp/go-rootcerts/README.md b/vendor/github.com/hashicorp/go-rootcerts/README.md deleted file mode 100644 index 6a128e1e14a29..0000000000000 --- a/vendor/github.com/hashicorp/go-rootcerts/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# rootcerts - -Functions for loading root certificates for TLS connections. - ------ - -Go's standard library `crypto/tls` provides a common mechanism for configuring -TLS connections in `tls.Config`. The `RootCAs` field on this struct is a pool -of certificates for the client to use as a trust store when verifying server -certificates. - -This library contains utility functions for loading certificates destined for -that field, as well as one other important thing: - -When the `RootCAs` field is `nil`, the standard library attempts to load the -host's root CA set. This behavior is OS-specific, and the Darwin -implementation contains [a bug that prevents trusted certificates from the -System and Login keychains from being loaded][1]. This library contains -Darwin-specific behavior that works around that bug. - -[1]: https://github.com/golang/go/issues/14514 - -## Example Usage - -Here's a snippet demonstrating how this library is meant to be used: - -```go -func httpClient() (*http.Client, error) - tlsConfig := &tls.Config{} - err := rootcerts.ConfigureTLS(tlsConfig, &rootcerts.Config{ - CAFile: os.Getenv("MYAPP_CAFILE"), - CAPath: os.Getenv("MYAPP_CAPATH"), - Certificate: os.Getenv("MYAPP_CERTIFICATE"), - }) - if err != nil { - return nil, err - } - c := cleanhttp.DefaultClient() - t := cleanhttp.DefaultTransport() - t.TLSClientConfig = tlsConfig - c.Transport = t - return c, nil -} -``` diff --git a/vendor/github.com/hashicorp/go-rootcerts/doc.go b/vendor/github.com/hashicorp/go-rootcerts/doc.go deleted file mode 100644 index b55cc62848504..0000000000000 --- a/vendor/github.com/hashicorp/go-rootcerts/doc.go +++ /dev/null @@ -1,9 +0,0 @@ -// Package rootcerts contains functions to aid in loading CA certificates for -// TLS connections. -// -// In addition, its default behavior on Darwin works around an open issue [1] -// in Go's crypto/x509 that prevents certicates from being loaded from the -// System or Login keychains. -// -// [1] https://github.com/golang/go/issues/14514 -package rootcerts diff --git a/vendor/github.com/hashicorp/go-rootcerts/rootcerts.go b/vendor/github.com/hashicorp/go-rootcerts/rootcerts.go deleted file mode 100644 index 69aabd6bc74ad..0000000000000 --- a/vendor/github.com/hashicorp/go-rootcerts/rootcerts.go +++ /dev/null @@ -1,123 +0,0 @@ -package rootcerts - -import ( - "crypto/tls" - "crypto/x509" - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" -) - -// Config determines where LoadCACerts will load certificates from. When CAFile, -// CACertificate and CAPath are blank, this library's functions will either load -// system roots explicitly and return them, or set the CertPool to nil to allow -// Go's standard library to load system certs. -type Config struct { - // CAFile is a path to a PEM-encoded certificate file or bundle. Takes - // precedence over CACertificate and CAPath. - CAFile string - - // CACertificate is a PEM-encoded certificate or bundle. Takes precedence - // over CAPath. - CACertificate []byte - - // CAPath is a path to a directory populated with PEM-encoded certificates. - CAPath string -} - -// ConfigureTLS sets up the RootCAs on the provided tls.Config based on the -// Config specified. -func ConfigureTLS(t *tls.Config, c *Config) error { - if t == nil { - return nil - } - pool, err := LoadCACerts(c) - if err != nil { - return err - } - t.RootCAs = pool - return nil -} - -// LoadCACerts loads a CertPool based on the Config specified. -func LoadCACerts(c *Config) (*x509.CertPool, error) { - if c == nil { - c = &Config{} - } - if c.CAFile != "" { - return LoadCAFile(c.CAFile) - } - if len(c.CACertificate) != 0 { - return AppendCertificate(c.CACertificate) - } - if c.CAPath != "" { - return LoadCAPath(c.CAPath) - } - - return LoadSystemCAs() -} - -// LoadCAFile loads a single PEM-encoded file from the path specified. -func LoadCAFile(caFile string) (*x509.CertPool, error) { - pool := x509.NewCertPool() - - pem, err := ioutil.ReadFile(caFile) - if err != nil { - return nil, fmt.Errorf("Error loading CA File: %s", err) - } - - ok := pool.AppendCertsFromPEM(pem) - if !ok { - return nil, fmt.Errorf("Error loading CA File: Couldn't parse PEM in: %s", caFile) - } - - return pool, nil -} - -// AppendCertificate appends an in-memory PEM-encoded certificate or bundle and returns a pool. -func AppendCertificate(ca []byte) (*x509.CertPool, error) { - pool := x509.NewCertPool() - - ok := pool.AppendCertsFromPEM(ca) - if !ok { - return nil, errors.New("Error appending CA: Couldn't parse PEM") - } - - return pool, nil -} - -// LoadCAPath walks the provided path and loads all certificates encounted into -// a pool. -func LoadCAPath(caPath string) (*x509.CertPool, error) { - pool := x509.NewCertPool() - walkFn := func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if info.IsDir() { - return nil - } - - pem, err := ioutil.ReadFile(path) - if err != nil { - return fmt.Errorf("Error loading file from CAPath: %s", err) - } - - ok := pool.AppendCertsFromPEM(pem) - if !ok { - return fmt.Errorf("Error loading CA Path: Couldn't parse PEM in: %s", path) - } - - return nil - } - - err := filepath.Walk(caPath, walkFn) - if err != nil { - return nil, err - } - - return pool, nil -} diff --git a/vendor/github.com/hashicorp/go-rootcerts/rootcerts_base.go b/vendor/github.com/hashicorp/go-rootcerts/rootcerts_base.go deleted file mode 100644 index 66b1472c4a043..0000000000000 --- a/vendor/github.com/hashicorp/go-rootcerts/rootcerts_base.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build !darwin - -package rootcerts - -import "crypto/x509" - -// LoadSystemCAs does nothing on non-Darwin systems. We return nil so that -// default behavior of standard TLS config libraries is triggered, which is to -// load system certs. -func LoadSystemCAs() (*x509.CertPool, error) { - return nil, nil -} diff --git a/vendor/github.com/hashicorp/go-rootcerts/rootcerts_darwin.go b/vendor/github.com/hashicorp/go-rootcerts/rootcerts_darwin.go deleted file mode 100644 index a9a040657fe3f..0000000000000 --- a/vendor/github.com/hashicorp/go-rootcerts/rootcerts_darwin.go +++ /dev/null @@ -1,48 +0,0 @@ -package rootcerts - -import ( - "crypto/x509" - "os/exec" - "path" - - "github.com/mitchellh/go-homedir" -) - -// LoadSystemCAs has special behavior on Darwin systems to work around -func LoadSystemCAs() (*x509.CertPool, error) { - pool := x509.NewCertPool() - - for _, keychain := range certKeychains() { - err := addCertsFromKeychain(pool, keychain) - if err != nil { - return nil, err - } - } - - return pool, nil -} - -func addCertsFromKeychain(pool *x509.CertPool, keychain string) error { - cmd := exec.Command("/usr/bin/security", "find-certificate", "-a", "-p", keychain) - data, err := cmd.Output() - if err != nil { - return err - } - - pool.AppendCertsFromPEM(data) - - return nil -} - -func certKeychains() []string { - keychains := []string{ - "/System/Library/Keychains/SystemRootCertificates.keychain", - "/Library/Keychains/System.keychain", - } - home, err := homedir.Dir() - if err == nil { - loginKeychain := path.Join(home, "Library", "Keychains", "login.keychain") - keychains = append(keychains, loginKeychain) - } - return keychains -} diff --git a/vendor/github.com/hashicorp/golang-lru/LICENSE b/vendor/github.com/hashicorp/golang-lru/LICENSE deleted file mode 100644 index be2cc4dfb609f..0000000000000 --- a/vendor/github.com/hashicorp/golang-lru/LICENSE +++ /dev/null @@ -1,362 +0,0 @@ -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. "Contributor" - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. "Contributor Version" - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. - -1.6. "Executable Form" - - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. - -1.8. "License" - - means this document. - -1.9. "Licensable" - - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. - -1.10. "Modifications" - - means any of the following: - - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. "Patent Claims" of a Contributor - - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. - -1.12. "Secondary License" - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. "Source Code Form" - - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. - - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice - - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go deleted file mode 100644 index a86c8539e0663..0000000000000 --- a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go +++ /dev/null @@ -1,177 +0,0 @@ -package simplelru - -import ( - "container/list" - "errors" -) - -// EvictCallback is used to get a callback when a cache entry is evicted -type EvictCallback func(key interface{}, value interface{}) - -// LRU implements a non-thread safe fixed size LRU cache -type LRU struct { - size int - evictList *list.List - items map[interface{}]*list.Element - onEvict EvictCallback -} - -// entry is used to hold a value in the evictList -type entry struct { - key interface{} - value interface{} -} - -// NewLRU constructs an LRU of the given size -func NewLRU(size int, onEvict EvictCallback) (*LRU, error) { - if size <= 0 { - return nil, errors.New("Must provide a positive size") - } - c := &LRU{ - size: size, - evictList: list.New(), - items: make(map[interface{}]*list.Element), - onEvict: onEvict, - } - return c, nil -} - -// Purge is used to completely clear the cache. -func (c *LRU) Purge() { - for k, v := range c.items { - if c.onEvict != nil { - c.onEvict(k, v.Value.(*entry).value) - } - delete(c.items, k) - } - c.evictList.Init() -} - -// Add adds a value to the cache. Returns true if an eviction occurred. -func (c *LRU) Add(key, value interface{}) (evicted bool) { - // Check for existing item - if ent, ok := c.items[key]; ok { - c.evictList.MoveToFront(ent) - ent.Value.(*entry).value = value - return false - } - - // Add new item - ent := &entry{key, value} - entry := c.evictList.PushFront(ent) - c.items[key] = entry - - evict := c.evictList.Len() > c.size - // Verify size not exceeded - if evict { - c.removeOldest() - } - return evict -} - -// Get looks up a key's value from the cache. -func (c *LRU) Get(key interface{}) (value interface{}, ok bool) { - if ent, ok := c.items[key]; ok { - c.evictList.MoveToFront(ent) - if ent.Value.(*entry) == nil { - return nil, false - } - return ent.Value.(*entry).value, true - } - return -} - -// Contains checks if a key is in the cache, without updating the recent-ness -// or deleting it for being stale. -func (c *LRU) Contains(key interface{}) (ok bool) { - _, ok = c.items[key] - return ok -} - -// Peek returns the key value (or undefined if not found) without updating -// the "recently used"-ness of the key. -func (c *LRU) Peek(key interface{}) (value interface{}, ok bool) { - var ent *list.Element - if ent, ok = c.items[key]; ok { - return ent.Value.(*entry).value, true - } - return nil, ok -} - -// Remove removes the provided key from the cache, returning if the -// key was contained. -func (c *LRU) Remove(key interface{}) (present bool) { - if ent, ok := c.items[key]; ok { - c.removeElement(ent) - return true - } - return false -} - -// RemoveOldest removes the oldest item from the cache. -func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) { - ent := c.evictList.Back() - if ent != nil { - c.removeElement(ent) - kv := ent.Value.(*entry) - return kv.key, kv.value, true - } - return nil, nil, false -} - -// GetOldest returns the oldest entry -func (c *LRU) GetOldest() (key interface{}, value interface{}, ok bool) { - ent := c.evictList.Back() - if ent != nil { - kv := ent.Value.(*entry) - return kv.key, kv.value, true - } - return nil, nil, false -} - -// Keys returns a slice of the keys in the cache, from oldest to newest. -func (c *LRU) Keys() []interface{} { - keys := make([]interface{}, len(c.items)) - i := 0 - for ent := c.evictList.Back(); ent != nil; ent = ent.Prev() { - keys[i] = ent.Value.(*entry).key - i++ - } - return keys -} - -// Len returns the number of items in the cache. -func (c *LRU) Len() int { - return c.evictList.Len() -} - -// Resize changes the cache size. -func (c *LRU) Resize(size int) (evicted int) { - diff := c.Len() - size - if diff < 0 { - diff = 0 - } - for i := 0; i < diff; i++ { - c.removeOldest() - } - c.size = size - return diff -} - -// removeOldest removes the oldest item from the cache. -func (c *LRU) removeOldest() { - ent := c.evictList.Back() - if ent != nil { - c.removeElement(ent) - } -} - -// removeElement is used to remove a given list element from the cache -func (c *LRU) removeElement(e *list.Element) { - c.evictList.Remove(e) - kv := e.Value.(*entry) - delete(c.items, kv.key) - if c.onEvict != nil { - c.onEvict(kv.key, kv.value) - } -} diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go deleted file mode 100644 index 92d70934d632f..0000000000000 --- a/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go +++ /dev/null @@ -1,39 +0,0 @@ -package simplelru - -// LRUCache is the interface for simple LRU cache. -type LRUCache interface { - // Adds a value to the cache, returns true if an eviction occurred and - // updates the "recently used"-ness of the key. - Add(key, value interface{}) bool - - // Returns key's value from the cache and - // updates the "recently used"-ness of the key. #value, isFound - Get(key interface{}) (value interface{}, ok bool) - - // Checks if a key exists in cache without updating the recent-ness. - Contains(key interface{}) (ok bool) - - // Returns key's value without updating the "recently used"-ness of the key. - Peek(key interface{}) (value interface{}, ok bool) - - // Removes a key from the cache. - Remove(key interface{}) bool - - // Removes the oldest entry from cache. - RemoveOldest() (interface{}, interface{}, bool) - - // Returns the oldest entry from the cache. #key, value, isFound - GetOldest() (interface{}, interface{}, bool) - - // Returns a slice of the keys in the cache, from oldest to newest. - Keys() []interface{} - - // Returns the number of items in the cache. - Len() int - - // Clears all cache entries. - Purge() - - // Resizes cache, returning number evicted - Resize(int) int -} diff --git a/vendor/github.com/hashicorp/serf/LICENSE b/vendor/github.com/hashicorp/serf/LICENSE deleted file mode 100644 index c33dcc7c928c6..0000000000000 --- a/vendor/github.com/hashicorp/serf/LICENSE +++ /dev/null @@ -1,354 +0,0 @@ -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. “Contributor” - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. “Contributor Version” - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor’s Contribution. - -1.3. “Contribution” - - means Covered Software of a particular Contributor. - -1.4. “Covered Software” - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. “Incompatible With Secondary Licenses” - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of version - 1.1 or earlier of the License, but not also under the terms of a - Secondary License. - -1.6. “Executable Form” - - means any form of the work other than Source Code Form. - -1.7. “Larger Work” - - means a work that combines Covered Software with other material, in a separate - file or files, that is not Covered Software. - -1.8. “License” - - means this document. - -1.9. “Licensable” - - means having the right to grant, to the maximum extent possible, whether at the - time of the initial grant or subsequently, any and all of the rights conveyed by - this License. - -1.10. “Modifications” - - means any of the following: - - a. any file in Source Code Form that results from an addition to, deletion - from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. “Patent Claims” of a Contributor - - means any patent claim(s), including without limitation, method, process, - and apparatus claims, in any patent Licensable by such Contributor that - would be infringed, but for the grant of the License, by the making, - using, selling, offering for sale, having made, import, or transfer of - either its Contributions or its Contributor Version. - -1.12. “Secondary License” - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. “Source Code Form” - - means the form of the work preferred for making modifications. - -1.14. “You” (or “Your”) - - means an individual or a legal entity exercising rights under this - License. For legal entities, “You” includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, “control” means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or as - part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its Contributions - or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution become - effective for each Contribution on the date the Contributor first distributes - such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under this - License. No additional rights or licenses will be implied from the distribution - or licensing of Covered Software under this License. Notwithstanding Section - 2.1(b) above, no patent license is granted by a Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party’s - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of its - Contributions. - - This License does not grant any rights in the trademarks, service marks, or - logos of any Contributor (except as may be necessary to comply with the - notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this License - (see Section 10.2) or under the terms of a Secondary License (if permitted - under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its Contributions - are its original creation(s) or it has sufficient rights to grant the - rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under applicable - copyright doctrines of fair use, fair dealing, or other equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under the - terms of this License. You must inform recipients that the Source Code Form - of the Covered Software is governed by the terms of this License, and how - they can obtain a copy of this License. You may not attempt to alter or - restrict the recipients’ rights in the Source Code Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this License, - or sublicense it under different terms, provided that the license for - the Executable Form does not attempt to limit or alter the recipients’ - rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for the - Covered Software. If the Larger Work is a combination of Covered Software - with a work governed by one or more Secondary Licenses, and the Covered - Software is not Incompatible With Secondary Licenses, this License permits - You to additionally distribute such Covered Software under the terms of - such Secondary License(s), so that the recipient of the Larger Work may, at - their option, further distribute the Covered Software under the terms of - either this License or such Secondary License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices (including - copyright notices, patent notices, disclaimers of warranty, or limitations - of liability) contained within the Source Code Form of the Covered - Software, except that You may alter any license notices to the extent - required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on behalf - of any Contributor. You must make it absolutely clear that any such - warranty, support, indemnity, or liability obligation is offered by You - alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, judicial - order, or regulation then You must: (a) comply with the terms of this License - to the maximum extent possible; and (b) describe the limitations and the code - they affect. Such description must be placed in a text file included with all - distributions of the Covered Software under this License. Except to the - extent prohibited by statute or regulation, such description must be - sufficiently detailed for a recipient of ordinary skill to be able to - understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing basis, - if such Contributor fails to notify You of the non-compliance by some - reasonable means prior to 60 days after You have come back into compliance. - Moreover, Your grants from a particular Contributor are reinstated on an - ongoing basis if such Contributor notifies You of the non-compliance by - some reasonable means, this is the first time You have received notice of - non-compliance with this License from such Contributor, and You become - compliant prior to 30 days after Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, counter-claims, - and cross-claims) alleging that a Contributor Version directly or - indirectly infringes any patent, then the rights granted to You by any and - all Contributors for the Covered Software under Section 2.1 of this License - shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an “as is” basis, without - warranty of any kind, either expressed, implied, or statutory, including, - without limitation, warranties that the Covered Software is free of defects, - merchantable, fit for a particular purpose or non-infringing. The entire - risk as to the quality and performance of the Covered Software is with You. - Should any Covered Software prove defective in any respect, You (not any - Contributor) assume the cost of any necessary servicing, repair, or - correction. This disclaimer of warranty constitutes an essential part of this - License. No use of any Covered Software is authorized under this License - except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from such - party’s negligence to the extent applicable law prohibits such limitation. - Some jurisdictions do not allow the exclusion or limitation of incidental or - consequential damages, so this exclusion and limitation may not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts of - a jurisdiction where the defendant maintains its principal place of business - and such litigation shall be governed by laws of that jurisdiction, without - reference to its conflict-of-law provisions. Nothing in this Section shall - prevent a party’s ability to bring cross-claims or counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject matter - hereof. If any provision of this License is held to be unenforceable, such - provision shall be reformed only to the extent necessary to make it - enforceable. Any law or regulation which provides that the language of a - contract shall be construed against the drafter shall not be used to construe - this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version of - the License under which You originally received the Covered Software, or - under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a modified - version of this License if you rename the license and remove any - references to the name of the license steward (except to note that such - modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses - If You choose to distribute Source Code Form that is Incompatible With - Secondary Licenses under the terms of this version of the License, the - notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, then -You may include the notice in a location (such as a LICENSE file in a relevant -directory) where a recipient would be likely to look for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - “Incompatible With Secondary Licenses” Notice - - This Source Code Form is “Incompatible - With Secondary Licenses”, as defined by - the Mozilla Public License, v. 2.0. - diff --git a/vendor/github.com/hashicorp/serf/coordinate/client.go b/vendor/github.com/hashicorp/serf/coordinate/client.go deleted file mode 100644 index 32124a73a2088..0000000000000 --- a/vendor/github.com/hashicorp/serf/coordinate/client.go +++ /dev/null @@ -1,243 +0,0 @@ -package coordinate - -import ( - "fmt" - "math" - "sort" - "sync" - "time" - - "github.com/armon/go-metrics" -) - -// Client manages the estimated network coordinate for a given node, and adjusts -// it as the node observes round trip times and estimated coordinates from other -// nodes. The core algorithm is based on Vivaldi, see the documentation for Config -// for more details. -type Client struct { - // coord is the current estimate of the client's network coordinate. - coord *Coordinate - - // origin is a coordinate sitting at the origin. - origin *Coordinate - - // config contains the tuning parameters that govern the performance of - // the algorithm. - config *Config - - // adjustmentIndex is the current index into the adjustmentSamples slice. - adjustmentIndex uint - - // adjustment is used to store samples for the adjustment calculation. - adjustmentSamples []float64 - - // latencyFilterSamples is used to store the last several RTT samples, - // keyed by node name. We will use the config's LatencyFilterSamples - // value to determine how many samples we keep, per node. - latencyFilterSamples map[string][]float64 - - // stats is used to record events that occur when updating coordinates. - stats ClientStats - - // mutex enables safe concurrent access to the client. - mutex sync.RWMutex -} - -// ClientStats is used to record events that occur when updating coordinates. -type ClientStats struct { - // Resets is incremented any time we reset our local coordinate because - // our calculations have resulted in an invalid state. - Resets int -} - -// NewClient creates a new Client and verifies the configuration is valid. -func NewClient(config *Config) (*Client, error) { - if !(config.Dimensionality > 0) { - return nil, fmt.Errorf("dimensionality must be >0") - } - - return &Client{ - coord: NewCoordinate(config), - origin: NewCoordinate(config), - config: config, - adjustmentIndex: 0, - adjustmentSamples: make([]float64, config.AdjustmentWindowSize), - latencyFilterSamples: make(map[string][]float64), - }, nil -} - -// GetCoordinate returns a copy of the coordinate for this client. -func (c *Client) GetCoordinate() *Coordinate { - c.mutex.RLock() - defer c.mutex.RUnlock() - - return c.coord.Clone() -} - -// SetCoordinate forces the client's coordinate to a known state. -func (c *Client) SetCoordinate(coord *Coordinate) error { - c.mutex.Lock() - defer c.mutex.Unlock() - - if err := c.checkCoordinate(coord); err != nil { - return err - } - - c.coord = coord.Clone() - return nil -} - -// ForgetNode removes any client state for the given node. -func (c *Client) ForgetNode(node string) { - c.mutex.Lock() - defer c.mutex.Unlock() - - delete(c.latencyFilterSamples, node) -} - -// Stats returns a copy of stats for the client. -func (c *Client) Stats() ClientStats { - c.mutex.Lock() - defer c.mutex.Unlock() - - return c.stats -} - -// checkCoordinate returns an error if the coordinate isn't compatible with -// this client, or if the coordinate itself isn't valid. This assumes the mutex -// has been locked already. -func (c *Client) checkCoordinate(coord *Coordinate) error { - if !c.coord.IsCompatibleWith(coord) { - return fmt.Errorf("dimensions aren't compatible") - } - - if !coord.IsValid() { - return fmt.Errorf("coordinate is invalid") - } - - return nil -} - -// latencyFilter applies a simple moving median filter with a new sample for -// a node. This assumes that the mutex has been locked already. -func (c *Client) latencyFilter(node string, rttSeconds float64) float64 { - samples, ok := c.latencyFilterSamples[node] - if !ok { - samples = make([]float64, 0, c.config.LatencyFilterSize) - } - - // Add the new sample and trim the list, if needed. - samples = append(samples, rttSeconds) - if len(samples) > int(c.config.LatencyFilterSize) { - samples = samples[1:] - } - c.latencyFilterSamples[node] = samples - - // Sort a copy of the samples and return the median. - sorted := make([]float64, len(samples)) - copy(sorted, samples) - sort.Float64s(sorted) - return sorted[len(sorted)/2] -} - -// updateVivialdi updates the Vivaldi portion of the client's coordinate. This -// assumes that the mutex has been locked already. -func (c *Client) updateVivaldi(other *Coordinate, rttSeconds float64) { - const zeroThreshold = 1.0e-6 - - dist := c.coord.DistanceTo(other).Seconds() - if rttSeconds < zeroThreshold { - rttSeconds = zeroThreshold - } - wrongness := math.Abs(dist-rttSeconds) / rttSeconds - - totalError := c.coord.Error + other.Error - if totalError < zeroThreshold { - totalError = zeroThreshold - } - weight := c.coord.Error / totalError - - c.coord.Error = c.config.VivaldiCE*weight*wrongness + c.coord.Error*(1.0-c.config.VivaldiCE*weight) - if c.coord.Error > c.config.VivaldiErrorMax { - c.coord.Error = c.config.VivaldiErrorMax - } - - delta := c.config.VivaldiCC * weight - force := delta * (rttSeconds - dist) - c.coord = c.coord.ApplyForce(c.config, force, other) -} - -// updateAdjustment updates the adjustment portion of the client's coordinate, if -// the feature is enabled. This assumes that the mutex has been locked already. -func (c *Client) updateAdjustment(other *Coordinate, rttSeconds float64) { - if c.config.AdjustmentWindowSize == 0 { - return - } - - // Note that the existing adjustment factors don't figure in to this - // calculation so we use the raw distance here. - dist := c.coord.rawDistanceTo(other) - c.adjustmentSamples[c.adjustmentIndex] = rttSeconds - dist - c.adjustmentIndex = (c.adjustmentIndex + 1) % c.config.AdjustmentWindowSize - - sum := 0.0 - for _, sample := range c.adjustmentSamples { - sum += sample - } - c.coord.Adjustment = sum / (2.0 * float64(c.config.AdjustmentWindowSize)) -} - -// updateGravity applies a small amount of gravity to pull coordinates towards -// the center of the coordinate system to combat drift. This assumes that the -// mutex is locked already. -func (c *Client) updateGravity() { - dist := c.origin.DistanceTo(c.coord).Seconds() - force := -1.0 * math.Pow(dist/c.config.GravityRho, 2.0) - c.coord = c.coord.ApplyForce(c.config, force, c.origin) -} - -// Update takes other, a coordinate for another node, and rtt, a round trip -// time observation for a ping to that node, and updates the estimated position of -// the client's coordinate. Returns the updated coordinate. -func (c *Client) Update(node string, other *Coordinate, rtt time.Duration) (*Coordinate, error) { - c.mutex.Lock() - defer c.mutex.Unlock() - - if err := c.checkCoordinate(other); err != nil { - return nil, err - } - - // The code down below can handle zero RTTs, which we have seen in - // https://github.com/hashicorp/consul/issues/3789, presumably in - // environments with coarse-grained monotonic clocks (we are still - // trying to pin this down). In any event, this is ok from a code PoV - // so we don't need to alert operators with spammy messages. We did - // add a counter so this is still observable, though. - const maxRTT = 10 * time.Second - if rtt < 0 || rtt > maxRTT { - return nil, fmt.Errorf("round trip time not in valid range, duration %v is not a positive value less than %v ", rtt, maxRTT) - } - if rtt == 0 { - metrics.IncrCounterWithLabels([]string{"serf", "coordinate", "zero-rtt"}, 1, c.config.MetricLabels) - } - - rttSeconds := c.latencyFilter(node, rtt.Seconds()) - c.updateVivaldi(other, rttSeconds) - c.updateAdjustment(other, rttSeconds) - c.updateGravity() - if !c.coord.IsValid() { - c.stats.Resets++ - c.coord = NewCoordinate(c.config) - } - - return c.coord.Clone(), nil -} - -// DistanceTo returns the estimated RTT from the client's coordinate to other, the -// coordinate for another node. -func (c *Client) DistanceTo(other *Coordinate) time.Duration { - c.mutex.RLock() - defer c.mutex.RUnlock() - - return c.coord.DistanceTo(other) -} diff --git a/vendor/github.com/hashicorp/serf/coordinate/config.go b/vendor/github.com/hashicorp/serf/coordinate/config.go deleted file mode 100644 index 09c0cafe830f8..0000000000000 --- a/vendor/github.com/hashicorp/serf/coordinate/config.go +++ /dev/null @@ -1,77 +0,0 @@ -package coordinate - -import ( - "github.com/armon/go-metrics" -) - -// Config is used to set the parameters of the Vivaldi-based coordinate mapping -// algorithm. -// -// The following references are called out at various points in the documentation -// here: -// -// [1] Dabek, Frank, et al. "Vivaldi: A decentralized network coordinate system." -// ACM SIGCOMM Computer Communication Review. Vol. 34. No. 4. ACM, 2004. -// [2] Ledlie, Jonathan, Paul Gardner, and Margo I. Seltzer. "Network Coordinates -// in the Wild." NSDI. Vol. 7. 2007. -// [3] Lee, Sanghwan, et al. "On suitability of Euclidean embedding for -// host-based network coordinate systems." Networking, IEEE/ACM Transactions -// on 18.1 (2010): 27-40. -type Config struct { - // The dimensionality of the coordinate system. As discussed in [2], more - // dimensions improves the accuracy of the estimates up to a point. Per [2] - // we chose 8 dimensions plus a non-Euclidean height. - Dimensionality uint - - // VivaldiErrorMax is the default error value when a node hasn't yet made - // any observations. It also serves as an upper limit on the error value in - // case observations cause the error value to increase without bound. - VivaldiErrorMax float64 - - // VivaldiCE is a tuning factor that controls the maximum impact an - // observation can have on a node's confidence. See [1] for more details. - VivaldiCE float64 - - // VivaldiCC is a tuning factor that controls the maximum impact an - // observation can have on a node's coordinate. See [1] for more details. - VivaldiCC float64 - - // AdjustmentWindowSize is a tuning factor that determines how many samples - // we retain to calculate the adjustment factor as discussed in [3]. Setting - // this to zero disables this feature. - AdjustmentWindowSize uint - - // HeightMin is the minimum value of the height parameter. Since this - // always must be positive, it will introduce a small amount error, so - // the chosen value should be relatively small compared to "normal" - // coordinates. - HeightMin float64 - - // LatencyFilterSamples is the maximum number of samples that are retained - // per node, in order to compute a median. The intent is to ride out blips - // but still keep the delay low, since our time to probe any given node is - // pretty infrequent. See [2] for more details. - LatencyFilterSize uint - - // GravityRho is a tuning factor that sets how much gravity has an effect - // to try to re-center coordinates. See [2] for more details. - GravityRho float64 - - // metricLabels is the slice of labels to put on all emitted metrics - MetricLabels []metrics.Label -} - -// DefaultConfig returns a Config that has some default values suitable for -// basic testing of the algorithm, but not tuned to any particular type of cluster. -func DefaultConfig() *Config { - return &Config{ - Dimensionality: 8, - VivaldiErrorMax: 1.5, - VivaldiCE: 0.25, - VivaldiCC: 0.25, - AdjustmentWindowSize: 20, - HeightMin: 10.0e-6, - LatencyFilterSize: 3, - GravityRho: 150.0, - } -} diff --git a/vendor/github.com/hashicorp/serf/coordinate/coordinate.go b/vendor/github.com/hashicorp/serf/coordinate/coordinate.go deleted file mode 100644 index fbe792c90d446..0000000000000 --- a/vendor/github.com/hashicorp/serf/coordinate/coordinate.go +++ /dev/null @@ -1,203 +0,0 @@ -package coordinate - -import ( - "math" - "math/rand" - "time" -) - -// Coordinate is a specialized structure for holding network coordinates for the -// Vivaldi-based coordinate mapping algorithm. All of the fields should be public -// to enable this to be serialized. All values in here are in units of seconds. -type Coordinate struct { - // Vec is the Euclidean portion of the coordinate. This is used along - // with the other fields to provide an overall distance estimate. The - // units here are seconds. - Vec []float64 - - // Err reflects the confidence in the given coordinate and is updated - // dynamically by the Vivaldi Client. This is dimensionless. - Error float64 - - // Adjustment is a distance offset computed based on a calculation over - // observations from all other nodes over a fixed window and is updated - // dynamically by the Vivaldi Client. The units here are seconds. - Adjustment float64 - - // Height is a distance offset that accounts for non-Euclidean effects - // which model the access links from nodes to the core Internet. The access - // links are usually set by bandwidth and congestion, and the core links - // usually follow distance based on geography. - Height float64 -} - -const ( - // secondsToNanoseconds is used to convert float seconds to nanoseconds. - secondsToNanoseconds = 1.0e9 - - // zeroThreshold is used to decide if two coordinates are on top of each - // other. - zeroThreshold = 1.0e-6 -) - -// ErrDimensionalityConflict will be panic-d if you try to perform operations -// with incompatible dimensions. -type DimensionalityConflictError struct{} - -// Adds the error interface. -func (e DimensionalityConflictError) Error() string { - return "coordinate dimensionality does not match" -} - -// NewCoordinate creates a new coordinate at the origin, using the given config -// to supply key initial values. -func NewCoordinate(config *Config) *Coordinate { - return &Coordinate{ - Vec: make([]float64, config.Dimensionality), - Error: config.VivaldiErrorMax, - Adjustment: 0.0, - Height: config.HeightMin, - } -} - -// Clone creates an independent copy of this coordinate. -func (c *Coordinate) Clone() *Coordinate { - vec := make([]float64, len(c.Vec)) - copy(vec, c.Vec) - return &Coordinate{ - Vec: vec, - Error: c.Error, - Adjustment: c.Adjustment, - Height: c.Height, - } -} - -// componentIsValid returns false if a floating point value is a NaN or an -// infinity. -func componentIsValid(f float64) bool { - return !math.IsInf(f, 0) && !math.IsNaN(f) -} - -// IsValid returns false if any component of a coordinate isn't valid, per the -// componentIsValid() helper above. -func (c *Coordinate) IsValid() bool { - for i := range c.Vec { - if !componentIsValid(c.Vec[i]) { - return false - } - } - - return componentIsValid(c.Error) && - componentIsValid(c.Adjustment) && - componentIsValid(c.Height) -} - -// IsCompatibleWith checks to see if the two coordinates are compatible -// dimensionally. If this returns true then you are guaranteed to not get -// any runtime errors operating on them. -func (c *Coordinate) IsCompatibleWith(other *Coordinate) bool { - return len(c.Vec) == len(other.Vec) -} - -// ApplyForce returns the result of applying the force from the direction of the -// other coordinate. -func (c *Coordinate) ApplyForce(config *Config, force float64, other *Coordinate) *Coordinate { - if !c.IsCompatibleWith(other) { - panic(DimensionalityConflictError{}) - } - - ret := c.Clone() - unit, mag := unitVectorAt(c.Vec, other.Vec) - ret.Vec = add(ret.Vec, mul(unit, force)) - if mag > zeroThreshold { - ret.Height = (ret.Height+other.Height)*force/mag + ret.Height - ret.Height = math.Max(ret.Height, config.HeightMin) - } - return ret -} - -// DistanceTo returns the distance between this coordinate and the other -// coordinate, including adjustments. -func (c *Coordinate) DistanceTo(other *Coordinate) time.Duration { - if !c.IsCompatibleWith(other) { - panic(DimensionalityConflictError{}) - } - - dist := c.rawDistanceTo(other) - adjustedDist := dist + c.Adjustment + other.Adjustment - if adjustedDist > 0.0 { - dist = adjustedDist - } - return time.Duration(dist * secondsToNanoseconds) -} - -// rawDistanceTo returns the Vivaldi distance between this coordinate and the -// other coordinate in seconds, not including adjustments. This assumes the -// dimensions have already been checked to be compatible. -func (c *Coordinate) rawDistanceTo(other *Coordinate) float64 { - return magnitude(diff(c.Vec, other.Vec)) + c.Height + other.Height -} - -// add returns the sum of vec1 and vec2. This assumes the dimensions have -// already been checked to be compatible. -func add(vec1 []float64, vec2 []float64) []float64 { - ret := make([]float64, len(vec1)) - for i := range ret { - ret[i] = vec1[i] + vec2[i] - } - return ret -} - -// diff returns the difference between the vec1 and vec2. This assumes the -// dimensions have already been checked to be compatible. -func diff(vec1 []float64, vec2 []float64) []float64 { - ret := make([]float64, len(vec1)) - for i := range ret { - ret[i] = vec1[i] - vec2[i] - } - return ret -} - -// mul returns vec multiplied by a scalar factor. -func mul(vec []float64, factor float64) []float64 { - ret := make([]float64, len(vec)) - for i := range vec { - ret[i] = vec[i] * factor - } - return ret -} - -// magnitude computes the magnitude of the vec. -func magnitude(vec []float64) float64 { - sum := 0.0 - for i := range vec { - sum += vec[i] * vec[i] - } - return math.Sqrt(sum) -} - -// unitVectorAt returns a unit vector pointing at vec1 from vec2. If the two -// positions are the same then a random unit vector is returned. We also return -// the distance between the points for use in the later height calculation. -func unitVectorAt(vec1 []float64, vec2 []float64) ([]float64, float64) { - ret := diff(vec1, vec2) - - // If the coordinates aren't on top of each other we can normalize. - if mag := magnitude(ret); mag > zeroThreshold { - return mul(ret, 1.0/mag), mag - } - - // Otherwise, just return a random unit vector. - for i := range ret { - ret[i] = rand.Float64() - 0.5 - } - if mag := magnitude(ret); mag > zeroThreshold { - return mul(ret, 1.0/mag), 0.0 - } - - // And finally just give up and make a unit vector along the first - // dimension. This should be exceedingly rare. - ret = make([]float64, len(ret)) - ret[0] = 1.0 - return ret, 0.0 -} diff --git a/vendor/github.com/hashicorp/serf/coordinate/phantom.go b/vendor/github.com/hashicorp/serf/coordinate/phantom.go deleted file mode 100644 index 66da4e2e92e33..0000000000000 --- a/vendor/github.com/hashicorp/serf/coordinate/phantom.go +++ /dev/null @@ -1,187 +0,0 @@ -package coordinate - -import ( - "fmt" - "math" - "math/rand" - "time" -) - -// GenerateClients returns a slice with nodes number of clients, all with the -// given config. -func GenerateClients(nodes int, config *Config) ([]*Client, error) { - clients := make([]*Client, nodes) - for i := range clients { - client, err := NewClient(config) - if err != nil { - return nil, err - } - - clients[i] = client - } - return clients, nil -} - -// GenerateLine returns a truth matrix as if all the nodes are in a straight linke -// with the given spacing between them. -func GenerateLine(nodes int, spacing time.Duration) [][]time.Duration { - truth := make([][]time.Duration, nodes) - for i := range truth { - truth[i] = make([]time.Duration, nodes) - } - - for i := 0; i < nodes; i++ { - for j := i + 1; j < nodes; j++ { - rtt := time.Duration(j-i) * spacing - truth[i][j], truth[j][i] = rtt, rtt - } - } - return truth -} - -// GenerateGrid returns a truth matrix as if all the nodes are in a two dimensional -// grid with the given spacing between them. -func GenerateGrid(nodes int, spacing time.Duration) [][]time.Duration { - truth := make([][]time.Duration, nodes) - for i := range truth { - truth[i] = make([]time.Duration, nodes) - } - - n := int(math.Sqrt(float64(nodes))) - for i := 0; i < nodes; i++ { - for j := i + 1; j < nodes; j++ { - x1, y1 := float64(i%n), float64(i/n) - x2, y2 := float64(j%n), float64(j/n) - dx, dy := x2-x1, y2-y1 - dist := math.Sqrt(dx*dx + dy*dy) - rtt := time.Duration(dist * float64(spacing)) - truth[i][j], truth[j][i] = rtt, rtt - } - } - return truth -} - -// GenerateSplit returns a truth matrix as if half the nodes are close together in -// one location and half the nodes are close together in another. The lan factor -// is used to separate the nodes locally and the wan factor represents the split -// between the two sides. -func GenerateSplit(nodes int, lan time.Duration, wan time.Duration) [][]time.Duration { - truth := make([][]time.Duration, nodes) - for i := range truth { - truth[i] = make([]time.Duration, nodes) - } - - split := nodes / 2 - for i := 0; i < nodes; i++ { - for j := i + 1; j < nodes; j++ { - rtt := lan - if (i <= split && j > split) || (i > split && j <= split) { - rtt += wan - } - truth[i][j], truth[j][i] = rtt, rtt - } - } - return truth -} - -// GenerateCircle returns a truth matrix for a set of nodes, evenly distributed -// around a circle with the given radius. The first node is at the "center" of the -// circle because it's equidistant from all the other nodes, but we place it at -// double the radius, so it should show up above all the other nodes in height. -func GenerateCircle(nodes int, radius time.Duration) [][]time.Duration { - truth := make([][]time.Duration, nodes) - for i := range truth { - truth[i] = make([]time.Duration, nodes) - } - - for i := 0; i < nodes; i++ { - for j := i + 1; j < nodes; j++ { - var rtt time.Duration - if i == 0 { - rtt = 2 * radius - } else { - t1 := 2.0 * math.Pi * float64(i) / float64(nodes) - x1, y1 := math.Cos(t1), math.Sin(t1) - t2 := 2.0 * math.Pi * float64(j) / float64(nodes) - x2, y2 := math.Cos(t2), math.Sin(t2) - dx, dy := x2-x1, y2-y1 - dist := math.Sqrt(dx*dx + dy*dy) - rtt = time.Duration(dist * float64(radius)) - } - truth[i][j], truth[j][i] = rtt, rtt - } - } - return truth -} - -// GenerateRandom returns a truth matrix for a set of nodes with normally -// distributed delays, with the given mean and deviation. The RNG is re-seeded -// so you always get the same matrix for a given size. -func GenerateRandom(nodes int, mean time.Duration, deviation time.Duration) [][]time.Duration { - rand.Seed(1) - - truth := make([][]time.Duration, nodes) - for i := range truth { - truth[i] = make([]time.Duration, nodes) - } - - for i := 0; i < nodes; i++ { - for j := i + 1; j < nodes; j++ { - rttSeconds := rand.NormFloat64()*deviation.Seconds() + mean.Seconds() - rtt := time.Duration(rttSeconds * secondsToNanoseconds) - truth[i][j], truth[j][i] = rtt, rtt - } - } - return truth -} - -// Simulate runs the given number of cycles using the given list of clients and -// truth matrix. On each cycle, each client will pick a random node and observe -// the truth RTT, updating its coordinate estimate. The RNG is re-seeded for -// each simulation run to get deterministic results (for this algorithm and the -// underlying algorithm which will use random numbers for position vectors when -// starting out with everything at the origin). -func Simulate(clients []*Client, truth [][]time.Duration, cycles int) { - rand.Seed(1) - - nodes := len(clients) - for cycle := 0; cycle < cycles; cycle++ { - for i := range clients { - if j := rand.Intn(nodes); j != i { - c := clients[j].GetCoordinate() - rtt := truth[i][j] - node := fmt.Sprintf("node_%d", j) - clients[i].Update(node, c, rtt) - } - } - } -} - -// Stats is returned from the Evaluate function with a summary of the algorithm -// performance. -type Stats struct { - ErrorMax float64 - ErrorAvg float64 -} - -// Evaluate uses the coordinates of the given clients to calculate estimated -// distances and compares them with the given truth matrix, returning summary -// stats. -func Evaluate(clients []*Client, truth [][]time.Duration) (stats Stats) { - nodes := len(clients) - count := 0 - for i := 0; i < nodes; i++ { - for j := i + 1; j < nodes; j++ { - est := clients[i].DistanceTo(clients[j].GetCoordinate()).Seconds() - actual := truth[i][j].Seconds() - error := math.Abs(est-actual) / actual - stats.ErrorMax = math.Max(stats.ErrorMax, error) - stats.ErrorAvg += error - count += 1 - } - } - - stats.ErrorAvg /= float64(count) - fmt.Printf("Error avg=%9.6f max=%9.6f\n", stats.ErrorAvg, stats.ErrorMax) - return -} diff --git a/vendor/modules.txt b/vendor/modules.txt index da9be3b87d7ac..5e72b2918b03c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -93,9 +93,6 @@ github.com/aliyun/alibaba-cloud-sdk-go/services/vpc # github.com/antlr4-go/antlr/v4 v4.13.0 ## explicit; go 1.20 github.com/antlr4-go/antlr/v4 -# github.com/armon/go-metrics v0.4.1 -## explicit; go 1.12 -github.com/armon/go-metrics # github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 ## explicit; go 1.13 github.com/asaskevich/govalidator @@ -973,39 +970,18 @@ github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/timeout # github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 ## explicit github.com/grpc-ecosystem/go-grpc-prometheus -# github.com/hashicorp/consul/api v1.29.2 -## explicit; go 1.19 -github.com/hashicorp/consul/api # github.com/hashicorp/errwrap v1.1.0 ## explicit github.com/hashicorp/errwrap -# github.com/hashicorp/go-cleanhttp v0.5.2 -## explicit; go 1.13 -github.com/hashicorp/go-cleanhttp # github.com/hashicorp/go-hclog v1.6.3 ## explicit; go 1.13 github.com/hashicorp/go-hclog -# github.com/hashicorp/go-immutable-radix v1.3.1 -## explicit -github.com/hashicorp/go-immutable-radix # github.com/hashicorp/go-immutable-radix/v2 v2.1.0 ## explicit; go 1.18 github.com/hashicorp/go-immutable-radix/v2 -# github.com/hashicorp/go-msgpack v1.1.5 -## explicit; go 1.13 # github.com/hashicorp/go-multierror v1.1.1 ## explicit; go 1.13 github.com/hashicorp/go-multierror -# github.com/hashicorp/go-rootcerts v1.0.2 -## explicit; go 1.12 -github.com/hashicorp/go-rootcerts -# github.com/hashicorp/go-sockaddr v1.0.5 -## explicit; go 1.19 -# github.com/hashicorp/go-version v1.6.0 -## explicit -# github.com/hashicorp/golang-lru v0.5.4 -## explicit; go 1.12 -github.com/hashicorp/golang-lru/simplelru # github.com/hashicorp/golang-lru/v2 v2.0.7 ## explicit; go 1.18 github.com/hashicorp/golang-lru/v2 @@ -1023,9 +999,6 @@ github.com/hashicorp/hcl/hcl/token github.com/hashicorp/hcl/json/parser github.com/hashicorp/hcl/json/scanner github.com/hashicorp/hcl/json/token -# github.com/hashicorp/serf v0.10.1 -## explicit; go 1.12 -github.com/hashicorp/serf/coordinate # github.com/huandu/xstrings v1.4.0 ## explicit; go 1.12 github.com/huandu/xstrings