From 0f565b372bab05b7cb58c3bf1ea8e3b385dffdae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:39:41 -0600 Subject: [PATCH] Bump github.com/hashicorp/consul/api from 1.20.0 to 1.26.1 (#199) Bumps [github.com/hashicorp/consul/api](https://github.com/hashicorp/consul) from 1.20.0 to 1.26.1. - [Release notes](https://github.com/hashicorp/consul/releases) - [Changelog](https://github.com/hashicorp/consul/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/consul/compare/api/v1.20.0...api/v1.26.1) --- updated-dependencies: - dependency-name: github.com/hashicorp/consul/api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 10 +- go.sum | 31 +- vendor/github.com/fatih/color/README.md | 14 +- vendor/github.com/fatih/color/color.go | 46 +- vendor/github.com/fatih/color/doc.go | 137 +++-- .../hashicorp/consul/api/.copywrite.hcl | 8 + .../github.com/hashicorp/consul/api/LICENSE | 303 +++++------ vendor/github.com/hashicorp/consul/api/acl.go | 161 ++++++ .../github.com/hashicorp/consul/api/agent.go | 59 ++- vendor/github.com/hashicorp/consul/api/api.go | 29 + .../hashicorp/consul/api/catalog.go | 12 +- .../hashicorp/consul/api/config_entry.go | 124 ++++- .../consul/api/config_entry_discoverychain.go | 52 +- .../consul/api/config_entry_exports.go | 6 + .../consul/api/config_entry_gateways.go | 43 ++ .../api/config_entry_inline_certificate.go | 3 + .../consul/api/config_entry_intentions.go | 51 +- .../consul/api/config_entry_jwt_provider.go | 310 +++++++++++ .../hashicorp/consul/api/config_entry_mesh.go | 7 + .../consul/api/config_entry_rate_limit_ip.go | 91 ++++ .../consul/api/config_entry_routes.go | 43 +- .../consul/api/config_entry_sameness_group.go | 29 + .../consul/api/config_entry_status.go | 303 ++++++++++- .../hashicorp/consul/api/connect.go | 6 + .../hashicorp/consul/api/connect_ca.go | 3 + .../hashicorp/consul/api/connect_intention.go | 7 + .../hashicorp/consul/api/coordinate.go | 3 + .../github.com/hashicorp/consul/api/debug.go | 3 + .../hashicorp/consul/api/discovery_chain.go | 4 + .../github.com/hashicorp/consul/api/event.go | 3 + .../github.com/hashicorp/consul/api/health.go | 4 + .../hashicorp/consul/api/internal.go | 67 +++ vendor/github.com/hashicorp/consul/api/kv.go | 3 + .../github.com/hashicorp/consul/api/lock.go | 3 + .../hashicorp/consul/api/namespace.go | 3 + .../hashicorp/consul/api/operator.go | 3 + .../hashicorp/consul/api/operator_area.go | 3 + .../hashicorp/consul/api/operator_audit.go | 40 ++ .../consul/api/operator_autopilot.go | 3 + .../hashicorp/consul/api/operator_keyring.go | 3 + .../hashicorp/consul/api/operator_license.go | 3 + .../hashicorp/consul/api/operator_raft.go | 13 +- .../hashicorp/consul/api/operator_segment.go | 3 + .../hashicorp/consul/api/operator_usage.go | 4 + .../hashicorp/consul/api/partition.go | 3 + .../hashicorp/consul/api/peering.go | 13 + .../hashicorp/consul/api/prepared_query.go | 21 +- vendor/github.com/hashicorp/consul/api/raw.go | 3 + .../hashicorp/consul/api/semaphore.go | 3 + .../hashicorp/consul/api/session.go | 3 + .../hashicorp/consul/api/snapshot.go | 3 + .../github.com/hashicorp/consul/api/status.go | 3 + vendor/github.com/hashicorp/consul/api/txn.go | 3 + vendor/github.com/hashicorp/go-hclog/LICENSE | 4 +- .../hashicorp/go-hclog/colorize_unix.go | 35 +- .../hashicorp/go-hclog/colorize_windows.go | 43 +- .../github.com/hashicorp/go-hclog/context.go | 3 + .../github.com/hashicorp/go-hclog/exclude.go | 3 + .../github.com/hashicorp/go-hclog/global.go | 3 + .../hashicorp/go-hclog/interceptlogger.go | 3 + .../hashicorp/go-hclog/intlogger.go | 126 ++++- .../github.com/hashicorp/go-hclog/logger.go | 20 + .../hashicorp/go-hclog/nulllogger.go | 5 + .../github.com/hashicorp/go-hclog/stdlog.go | 3 + .../github.com/hashicorp/go-hclog/writer.go | 3 + .../github.com/mattn/go-isatty/isatty_bsd.go | 4 +- vendor/golang.org/x/exp/LICENSE | 27 + vendor/golang.org/x/exp/PATENTS | 22 + .../x/exp/constraints/constraints.go | 50 ++ vendor/golang.org/x/exp/slices/cmp.go | 44 ++ vendor/golang.org/x/exp/slices/slices.go | 499 ++++++++++++++++++ vendor/golang.org/x/exp/slices/sort.go | 195 +++++++ .../golang.org/x/exp/slices/zsortanyfunc.go | 479 +++++++++++++++++ .../golang.org/x/exp/slices/zsortordered.go | 481 +++++++++++++++++ vendor/modules.txt | 16 +- 75 files changed, 3811 insertions(+), 368 deletions(-) create mode 100644 vendor/github.com/hashicorp/consul/api/.copywrite.hcl create mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_jwt_provider.go create mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_rate_limit_ip.go create mode 100644 vendor/github.com/hashicorp/consul/api/config_entry_sameness_group.go create mode 100644 vendor/github.com/hashicorp/consul/api/internal.go create mode 100644 vendor/github.com/hashicorp/consul/api/operator_audit.go create mode 100644 vendor/golang.org/x/exp/LICENSE create mode 100644 vendor/golang.org/x/exp/PATENTS create mode 100644 vendor/golang.org/x/exp/constraints/constraints.go create mode 100644 vendor/golang.org/x/exp/slices/cmp.go create mode 100644 vendor/golang.org/x/exp/slices/slices.go create mode 100644 vendor/golang.org/x/exp/slices/sort.go create mode 100644 vendor/golang.org/x/exp/slices/zsortanyfunc.go create mode 100644 vendor/golang.org/x/exp/slices/zsortordered.go diff --git a/go.mod b/go.mod index 06ea169ad..065c3fb66 100644 --- a/go.mod +++ b/go.mod @@ -7,11 +7,11 @@ require ( github.com/armon/go-metrics v0.4.1 // indirect github.com/aws/aws-sdk-go v1.44.266 github.com/coreos/go-semver v0.3.0 // indirect - github.com/fatih/color v1.13.0 // indirect + github.com/fatih/color v1.14.1 // indirect github.com/fsnotify/fsnotify v1.7.0 github.com/go-zookeeper/zk v1.0.3 github.com/gomodule/redigo v1.8.9 - github.com/hashicorp/consul/api v1.20.0 + github.com/hashicorp/consul/api v1.26.1 github.com/hashicorp/vault/api v1.9.1 github.com/kelseyhightower/memkv v0.1.1 github.com/sirupsen/logrus v1.9.3 @@ -26,7 +26,7 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-hclog v1.3.0 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.1 // indirect @@ -34,14 +34,13 @@ require ( github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect - github.com/hashicorp/go-uuid v1.0.3 // 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.0 // indirect github.com/hashicorp/serf v0.10.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect @@ -51,6 +50,7 @@ require ( go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.23.0 // indirect golang.org/x/crypto v0.14.0 // indirect + golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect diff --git a/go.sum b/go.sum index a3242e00a..015a4222b 100644 --- a/go.sum +++ b/go.sum @@ -28,12 +28,13 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= 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 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= +github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -56,16 +57,16 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws= github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/consul/api v1.20.0 h1:9IHTjNVSZ7MIwjlW3N3a7iGiykCMDpxZu8jsxFJh0yc= -github.com/hashicorp/consul/api v1.20.0/go.mod h1:nR64eD44KQ59Of/ECwt2vUmIK2DKsDzAwTmwmLl8Wpo= -github.com/hashicorp/consul/sdk v0.13.1 h1:EygWVWWMczTzXGpO93awkHFzfUka6hLYJ0qhETd+6lY= +github.com/hashicorp/consul/api v1.26.1 h1:5oSXOO5fboPZeW5SN+TdGFP/BILDgBm19OrPZ/pICIM= +github.com/hashicorp/consul/api v1.26.1/go.mod h1:B4sQTeaSO16NtynqrAdwOlahJ7IUDZM9cj2420xYL8A= +github.com/hashicorp/consul/sdk v0.15.0 h1:2qK9nDrr4tiJKRoxPGhm6B7xJjLVIQqkjiab2M4aKjU= 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= @@ -74,13 +75,13 @@ github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng 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 v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v1.3.0 h1:G0ACM8Z2WilWgPv3Vdzwm3V0BQu/kSmrkVtpe1fy9do= -github.com/hashicorp/go-hclog v1.3.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/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-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= 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= @@ -102,7 +103,6 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv 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= @@ -131,8 +131,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -148,8 +148,9 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd 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 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= @@ -175,8 +176,8 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE 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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -201,8 +202,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -235,6 +236,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= diff --git a/vendor/github.com/fatih/color/README.md b/vendor/github.com/fatih/color/README.md index 5152bf59b..be82827ca 100644 --- a/vendor/github.com/fatih/color/README.md +++ b/vendor/github.com/fatih/color/README.md @@ -7,7 +7,6 @@ suits you. ![Color](https://user-images.githubusercontent.com/438920/96832689-03b3e000-13f4-11eb-9803-46f4c4de3406.jpg) - ## Install ```bash @@ -124,17 +123,17 @@ fmt.Println("All text will now be bold magenta.") ``` ### Disable/Enable color - + There might be a case where you want to explicitly disable/enable color output. the `go-isatty` package will automatically disable color output for non-tty output streams (for example if the output were piped directly to `less`). The `color` package also disables color output if the [`NO_COLOR`](https://no-color.org) environment -variable is set (regardless of its value). +variable is set to a non-empty string. -`Color` has support to disable/enable colors programatically both globally and +`Color` has support to disable/enable colors programmatically both globally and for single color definitions. For example suppose you have a CLI app and a -`--no-color` bool flag. You can easily disable the color output with: +`-no-color` bool flag. You can easily disable the color output with: ```go var flagNoColor = flag.Bool("no-color", false, "Disable color output") @@ -167,11 +166,10 @@ To output color in GitHub Actions (or other CI systems that support ANSI colors) * Save/Return previous values * Evaluate fmt.Formatter interface - ## Credits - * [Fatih Arslan](https://github.com/fatih) - * Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable) +* [Fatih Arslan](https://github.com/fatih) +* Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable) ## License diff --git a/vendor/github.com/fatih/color/color.go b/vendor/github.com/fatih/color/color.go index 98a60f3c8..889f9e77b 100644 --- a/vendor/github.com/fatih/color/color.go +++ b/vendor/github.com/fatih/color/color.go @@ -19,10 +19,10 @@ var ( // set (regardless of its value). This is a global option and affects all // colors. For more control over each color block use the methods // DisableColor() individually. - NoColor = noColorExists() || os.Getenv("TERM") == "dumb" || + NoColor = noColorIsSet() || os.Getenv("TERM") == "dumb" || (!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd())) - // Output defines the standard output of the print functions. By default + // Output defines the standard output of the print functions. By default, // os.Stdout is used. Output = colorable.NewColorableStdout() @@ -35,10 +35,9 @@ var ( colorsCacheMu sync.Mutex // protects colorsCache ) -// noColorExists returns true if the environment variable NO_COLOR exists. -func noColorExists() bool { - _, exists := os.LookupEnv("NO_COLOR") - return exists +// noColorIsSet returns true if the environment variable NO_COLOR is set to a non-empty string. +func noColorIsSet() bool { + return os.Getenv("NO_COLOR") != "" } // Color defines a custom color object which is defined by SGR parameters. @@ -120,7 +119,7 @@ func New(value ...Attribute) *Color { params: make([]Attribute, 0), } - if noColorExists() { + if noColorIsSet() { c.noColor = boolPtr(true) } @@ -152,7 +151,7 @@ func (c *Color) Set() *Color { return c } - fmt.Fprintf(Output, c.format()) + fmt.Fprint(Output, c.format()) return c } @@ -164,16 +163,21 @@ func (c *Color) unset() { Unset() } -func (c *Color) setWriter(w io.Writer) *Color { +// SetWriter is used to set the SGR sequence with the given io.Writer. This is +// a low-level function, and users should use the higher-level functions, such +// as color.Fprint, color.Print, etc. +func (c *Color) SetWriter(w io.Writer) *Color { if c.isNoColorSet() { return c } - fmt.Fprintf(w, c.format()) + fmt.Fprint(w, c.format()) return c } -func (c *Color) unsetWriter(w io.Writer) { +// UnsetWriter resets all escape attributes and clears the output with the give +// io.Writer. Usually should be called after SetWriter(). +func (c *Color) UnsetWriter(w io.Writer) { if c.isNoColorSet() { return } @@ -192,20 +196,14 @@ func (c *Color) Add(value ...Attribute) *Color { return c } -func (c *Color) prepend(value Attribute) { - c.params = append(c.params, 0) - copy(c.params[1:], c.params[0:]) - c.params[0] = value -} - // Fprint formats using the default formats for its operands and writes to w. // Spaces are added between operands when neither is a string. // It returns the number of bytes written and any write error encountered. // On Windows, users should wrap w with colorable.NewColorable() if w is of // type *os.File. func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) { - c.setWriter(w) - defer c.unsetWriter(w) + c.SetWriter(w) + defer c.UnsetWriter(w) return fmt.Fprint(w, a...) } @@ -227,8 +225,8 @@ func (c *Color) Print(a ...interface{}) (n int, err error) { // On Windows, users should wrap w with colorable.NewColorable() if w is of // type *os.File. func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - c.setWriter(w) - defer c.unsetWriter(w) + c.SetWriter(w) + defer c.UnsetWriter(w) return fmt.Fprintf(w, format, a...) } @@ -248,8 +246,8 @@ func (c *Color) Printf(format string, a ...interface{}) (n int, err error) { // On Windows, users should wrap w with colorable.NewColorable() if w is of // type *os.File. func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - c.setWriter(w) - defer c.unsetWriter(w) + c.SetWriter(w) + defer c.UnsetWriter(w) return fmt.Fprintln(w, a...) } @@ -396,7 +394,7 @@ func (c *Color) DisableColor() { } // EnableColor enables the color output. Use it in conjunction with -// DisableColor(). Otherwise this method has no side effects. +// DisableColor(). Otherwise, this method has no side effects. func (c *Color) EnableColor() { c.noColor = boolPtr(false) } diff --git a/vendor/github.com/fatih/color/doc.go b/vendor/github.com/fatih/color/doc.go index 04541de78..9491ad541 100644 --- a/vendor/github.com/fatih/color/doc.go +++ b/vendor/github.com/fatih/color/doc.go @@ -5,106 +5,105 @@ that suits you. Use simple and default helper functions with predefined foreground colors: - color.Cyan("Prints text in cyan.") + color.Cyan("Prints text in cyan.") - // a newline will be appended automatically - color.Blue("Prints %s in blue.", "text") + // a newline will be appended automatically + color.Blue("Prints %s in blue.", "text") - // More default foreground colors.. - color.Red("We have red") - color.Yellow("Yellow color too!") - color.Magenta("And many others ..") + // More default foreground colors.. + color.Red("We have red") + color.Yellow("Yellow color too!") + color.Magenta("And many others ..") - // Hi-intensity colors - color.HiGreen("Bright green color.") - color.HiBlack("Bright black means gray..") - color.HiWhite("Shiny white color!") + // Hi-intensity colors + color.HiGreen("Bright green color.") + color.HiBlack("Bright black means gray..") + color.HiWhite("Shiny white color!") -However there are times where custom color mixes are required. Below are some +However, there are times when custom color mixes are required. Below are some examples to create custom color objects and use the print functions of each separate color object. - // Create a new color object - c := color.New(color.FgCyan).Add(color.Underline) - c.Println("Prints cyan text with an underline.") + // Create a new color object + c := color.New(color.FgCyan).Add(color.Underline) + c.Println("Prints cyan text with an underline.") - // Or just add them to New() - d := color.New(color.FgCyan, color.Bold) - d.Printf("This prints bold cyan %s\n", "too!.") + // Or just add them to New() + d := color.New(color.FgCyan, color.Bold) + d.Printf("This prints bold cyan %s\n", "too!.") - // Mix up foreground and background colors, create new mixes! - red := color.New(color.FgRed) + // Mix up foreground and background colors, create new mixes! + red := color.New(color.FgRed) - boldRed := red.Add(color.Bold) - boldRed.Println("This will print text in bold red.") + boldRed := red.Add(color.Bold) + boldRed.Println("This will print text in bold red.") - whiteBackground := red.Add(color.BgWhite) - whiteBackground.Println("Red text with White background.") + whiteBackground := red.Add(color.BgWhite) + whiteBackground.Println("Red text with White background.") - // Use your own io.Writer output - color.New(color.FgBlue).Fprintln(myWriter, "blue color!") + // Use your own io.Writer output + color.New(color.FgBlue).Fprintln(myWriter, "blue color!") - blue := color.New(color.FgBlue) - blue.Fprint(myWriter, "This will print text in blue.") + blue := color.New(color.FgBlue) + blue.Fprint(myWriter, "This will print text in blue.") You can create PrintXxx functions to simplify even more: - // Create a custom print function for convenient - red := color.New(color.FgRed).PrintfFunc() - red("warning") - red("error: %s", err) + // Create a custom print function for convenient + red := color.New(color.FgRed).PrintfFunc() + red("warning") + red("error: %s", err) - // Mix up multiple attributes - notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() - notice("don't forget this...") + // Mix up multiple attributes + notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() + notice("don't forget this...") You can also FprintXxx functions to pass your own io.Writer: - blue := color.New(FgBlue).FprintfFunc() - blue(myWriter, "important notice: %s", stars) - - // Mix up with multiple attributes - success := color.New(color.Bold, color.FgGreen).FprintlnFunc() - success(myWriter, don't forget this...") + blue := color.New(FgBlue).FprintfFunc() + blue(myWriter, "important notice: %s", stars) + // Mix up with multiple attributes + success := color.New(color.Bold, color.FgGreen).FprintlnFunc() + success(myWriter, don't forget this...") Or create SprintXxx functions to mix strings with other non-colorized strings: - yellow := New(FgYellow).SprintFunc() - red := New(FgRed).SprintFunc() + yellow := New(FgYellow).SprintFunc() + red := New(FgRed).SprintFunc() - fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error")) + fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error")) - info := New(FgWhite, BgGreen).SprintFunc() - fmt.Printf("this %s rocks!\n", info("package")) + info := New(FgWhite, BgGreen).SprintFunc() + fmt.Printf("this %s rocks!\n", info("package")) Windows support is enabled by default. All Print functions work as intended. -However only for color.SprintXXX functions, user should use fmt.FprintXXX and +However, only for color.SprintXXX functions, user should use fmt.FprintXXX and set the output to color.Output: - fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) + fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) - info := New(FgWhite, BgGreen).SprintFunc() - fmt.Fprintf(color.Output, "this %s rocks!\n", info("package")) + info := New(FgWhite, BgGreen).SprintFunc() + fmt.Fprintf(color.Output, "this %s rocks!\n", info("package")) Using with existing code is possible. Just use the Set() method to set the standard output to the given parameters. That way a rewrite of an existing code is not required. - // Use handy standard colors. - color.Set(color.FgYellow) + // Use handy standard colors. + color.Set(color.FgYellow) - fmt.Println("Existing text will be now in Yellow") - fmt.Printf("This one %s\n", "too") + fmt.Println("Existing text will be now in Yellow") + fmt.Printf("This one %s\n", "too") - color.Unset() // don't forget to unset + color.Unset() // don't forget to unset - // You can mix up parameters - color.Set(color.FgMagenta, color.Bold) - defer color.Unset() // use it in your function + // You can mix up parameters + color.Set(color.FgMagenta, color.Bold) + defer color.Unset() // use it in your function - fmt.Println("All text will be now bold magenta.") + fmt.Println("All text will be now bold magenta.") There might be a case where you want to disable color output (for example to pipe the standard output of your app to somewhere else). `Color` has support to @@ -112,24 +111,24 @@ disable colors both globally and for single color definition. For example suppose you have a CLI app and a `--no-color` bool flag. You can easily disable the color output with: - var flagNoColor = flag.Bool("no-color", false, "Disable color output") + var flagNoColor = flag.Bool("no-color", false, "Disable color output") - if *flagNoColor { - color.NoColor = true // disables colorized output - } + if *flagNoColor { + color.NoColor = true // disables colorized output + } You can also disable the color by setting the NO_COLOR environment variable to any value. It also has support for single color definitions (local). You can disable/enable color output on the fly: - c := color.New(color.FgCyan) - c.Println("Prints cyan text") + c := color.New(color.FgCyan) + c.Println("Prints cyan text") - c.DisableColor() - c.Println("This is printed without any color") + c.DisableColor() + c.Println("This is printed without any color") - c.EnableColor() - c.Println("This prints again cyan...") + c.EnableColor() + c.Println("This prints again cyan...") */ package color diff --git a/vendor/github.com/hashicorp/consul/api/.copywrite.hcl b/vendor/github.com/hashicorp/consul/api/.copywrite.hcl new file mode 100644 index 000000000..34d99ba25 --- /dev/null +++ b/vendor/github.com/hashicorp/consul/api/.copywrite.hcl @@ -0,0 +1,8 @@ +schema_version = 1 + +project { + license = "MPL-2.0" + copyright_year = 2023 + + header_ignore = [] +} diff --git a/vendor/github.com/hashicorp/consul/api/LICENSE b/vendor/github.com/hashicorp/consul/api/LICENSE index c72625e4c..7c5baa45e 100644 --- a/vendor/github.com/hashicorp/consul/api/LICENSE +++ b/vendor/github.com/hashicorp/consul/api/LICENSE @@ -1,92 +1,92 @@ -Copyright (c) 2013 HashiCorp, Inc. +Copyright (c) 2020 HashiCorp, Inc. Mozilla Public License, version 2.0 1. Definitions -1.1. “Contributor” +1.1. "Contributor" means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. -1.2. “Contributor Version” +1.2. "Contributor Version" means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor’s Contribution. + Contributor and that particular Contributor's Contribution. -1.3. “Contribution” +1.3. "Contribution" means Covered Software of a particular Contributor. -1.4. “Covered Software” +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” +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. + 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” +1.6. "Executable Form" means any form of the work other than Source Code Form. -1.7. “Larger Work” +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. + means a work that combines Covered Software with other material, in a + separate file or files, that is not Covered Software. -1.8. “License” +1.8. "License" means this document. -1.9. “Licensable” +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. + 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” +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 + 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 +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. + 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” +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” +1.13. "Source Code Form" means the form of the work preferred for making modifications. -1.14. “You” (or “Your”) +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 + 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 + 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. @@ -102,57 +102,59 @@ Mozilla Public License, version 2.0 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 + 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. + 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. + 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: + 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 + 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. + 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). + 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). + 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. + 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. + 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 @@ -165,11 +167,12 @@ Mozilla Public License, version 2.0 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. + 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 @@ -181,39 +184,40 @@ Mozilla Public License, version 2.0 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. + 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). + 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. + 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 + 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 @@ -222,14 +226,14 @@ Mozilla Public License, version 2.0 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. + 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 @@ -237,21 +241,22 @@ Mozilla Public License, version 2.0 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. + 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. + 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 @@ -260,16 +265,16 @@ Mozilla Public License, version 2.0 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. + 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 @@ -281,27 +286,29 @@ Mozilla Public License, version 2.0 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. + 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. + 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. + 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 @@ -315,23 +322,24 @@ Mozilla Public License, version 2.0 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 + 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). + 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. +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 @@ -342,15 +350,16 @@ Exhibit A - Source Code Form License Notice 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. +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 +Exhibit B - "Incompatible With Secondary Licenses" Notice - This Source Code Form is “Incompatible - With Secondary Licenses”, as defined by + 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/acl.go b/vendor/github.com/hashicorp/consul/api/acl.go index 3e13ccc88..47b38eb6c 100644 --- a/vendor/github.com/hashicorp/consul/api/acl.go +++ b/vendor/github.com/hashicorp/consul/api/acl.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( @@ -16,6 +19,13 @@ const ( // 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" ) type ACLLink struct { @@ -37,6 +47,7 @@ type ACLToken struct { 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"` @@ -85,6 +96,7 @@ type ACLTokenListEntry struct { 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"` @@ -145,6 +157,27 @@ type ACLNodeIdentity struct { 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 +} + +type ACLTemplatedPolicyVariables struct { + Name string +} + // ACLPolicy represents an ACL Policy. type ACLPolicy struct { ID string @@ -193,6 +226,7 @@ type ACLRole struct { Policies []*ACLRolePolicyLink `json:",omitempty"` ServiceIdentities []*ACLServiceIdentity `json:",omitempty"` NodeIdentities []*ACLNodeIdentity `json:",omitempty"` + TemplatedPolicies []*ACLTemplatedPolicy `json:",omitempty"` Hash []byte CreateIndex uint64 ModifyIndex uint64 @@ -215,6 +249,12 @@ const ( // 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" + + // BindingRuleBindTypeTemplatedPolicy binds to a templated policy with given template name and variables. + BindingRuleBindTypeTemplatedPolicy BindingRuleBindType = "templated-policy" ) type ACLBindingRule struct { @@ -224,6 +264,7 @@ type ACLBindingRule struct { Selector string BindType BindingRuleBindType BindName string + BindVars *ACLTemplatedPolicyVariables `json:",omitempty"` CreateIndex uint64 ModifyIndex uint64 @@ -269,6 +310,13 @@ type ACLAuthMethod struct { 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 { @@ -892,6 +940,44 @@ func (a *ACL) TokenList(q *QueryOptions) ([]*ACLTokenListEntry, *QueryMeta, erro 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) { @@ -1575,3 +1661,78 @@ func (a *ACL) OIDCCallback(auth *ACLOIDCCallbackParams, q *WriteOptions) (*ACLTo } 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 index 7904e7b71..24e2c50d6 100644 --- a/vendor/github.com/hashicorp/consul/api/agent.go +++ b/vendor/github.com/hashicorp/consul/api/agent.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( @@ -104,7 +107,8 @@ type AgentService struct { 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"` + Datacenter string `json:",omitempty" bexpr:"-" hash:"ignore"` + Locality *Locality `json:",omitempty" bexpr:"-" hash:"ignore"` } // AgentServiceChecksInfo returns information about a Service and its checks @@ -270,6 +274,8 @@ type MembersOpts struct { // 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 @@ -291,6 +297,7 @@ type AgentServiceRegistration struct { 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. @@ -300,6 +307,10 @@ type ServiceRegisterOpts struct { // 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 @@ -338,6 +349,7 @@ type AgentServiceCheck struct { 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"` @@ -498,6 +510,24 @@ func (a *Agent) Host() (map[string]interface{}, error) { 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) { @@ -767,6 +797,10 @@ func (a *Agent) MembersOpts(opts MembersOpts) ([]*AgentMember, error) { 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 @@ -805,6 +839,9 @@ func (a *Agent) serviceRegister(service *AgentServiceRegistration, opts ServiceR 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 @@ -961,7 +998,14 @@ func (a *Agent) UpdateTTLOpts(checkID, output, status string, q *QueryOptions) e // 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 { @@ -1050,8 +1094,17 @@ func (a *Agent) ForceLeavePrune(node string) error { // 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") } @@ -1340,6 +1393,10 @@ func (a *Agent) UpdateConfigFileRegistrationToken(token string, q *WriteOptions) 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. diff --git a/vendor/github.com/hashicorp/consul/api/api.go b/vendor/github.com/hashicorp/consul/api/api.go index 772f8693b..f62c0c5a1 100644 --- a/vendor/github.com/hashicorp/consul/api/api.go +++ b/vendor/github.com/hashicorp/consul/api/api.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( @@ -833,12 +836,21 @@ func (r *request) setQueryOptions(q *QueryOptions) { 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.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 != "" { @@ -946,12 +958,16 @@ 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) } @@ -984,6 +1000,19 @@ func (r *request) toHTTP() (*http.Request, error) { 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 diff --git a/vendor/github.com/hashicorp/consul/api/catalog.go b/vendor/github.com/hashicorp/consul/api/catalog.go index 84a2bdbc6..0040ca6e7 100644 --- a/vendor/github.com/hashicorp/consul/api/catalog.go +++ b/vendor/github.com/hashicorp/consul/api/catalog.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( @@ -19,8 +22,9 @@ type Node struct { Meta map[string]string CreateIndex uint64 ModifyIndex uint64 - Partition string `json:",omitempty"` - PeerName string `json:",omitempty"` + Partition string `json:",omitempty"` + PeerName string `json:",omitempty"` + Locality *Locality `json:",omitempty"` } type ServiceAddress struct { @@ -45,6 +49,7 @@ type CatalogService struct { ServiceWeights Weights ServiceEnableTagOverride bool ServiceProxy *AgentServiceConnectProxyConfig + ServiceLocality *Locality `json:",omitempty"` CreateIndex uint64 Checks HealthChecks ModifyIndex uint64 @@ -73,7 +78,8 @@ type CatalogRegistration struct { Check *AgentCheck Checks HealthChecks SkipNodeUpdate bool - Partition string `json:",omitempty"` + Partition string `json:",omitempty"` + Locality *Locality `json:",omitempty"` } type CatalogDeregistration struct { diff --git a/vendor/github.com/hashicorp/consul/api/config_entry.go b/vendor/github.com/hashicorp/consul/api/config_entry.go index 4e9682ee6..b59c20fd3 100644 --- a/vendor/github.com/hashicorp/consul/api/config_entry.go +++ b/vendor/github.com/hashicorp/consul/api/config_entry.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( @@ -23,6 +26,8 @@ const ( 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" @@ -30,11 +35,20 @@ const ( TCPRoute string = "tcp-route" InlineCertificate string = "inline-certificate" HTTPRoute string = "http-route" + JWTProvider string = "jwt-provider" ) const ( - BuiltinAWSLambdaExtension string = "builtin/aws/lambda" - BuiltinLuaExtension string = "builtin/lua" + 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 { @@ -102,6 +116,21 @@ type TransparentProxyConfig struct { 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 { @@ -115,9 +144,11 @@ type ExposeConfig struct { // EnvoyExtension has configuration for an extension that patches Envoy resources. type EnvoyExtension struct { - Name string - Required bool - Arguments map[string]interface{} `bexpr:"-"` + Name string + Required bool + Arguments map[string]interface{} `bexpr:"-"` + ConsulVersion string + EnvoyVersion string } type ExposePath struct { @@ -254,6 +285,15 @@ type PassiveHealthCheck struct { // 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 @@ -275,6 +315,47 @@ type UpstreamLimits struct { 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. + // 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 @@ -283,6 +364,7 @@ type ServiceConfigEntry struct { 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"` @@ -292,6 +374,7 @@ type ServiceConfigEntry struct { 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 @@ -307,17 +390,20 @@ 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"` - 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"` + 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 @@ -354,6 +440,8 @@ func makeConfigEntry(kind, name string) (ConfigEntry, error) { 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: @@ -362,6 +450,10 @@ func makeConfigEntry(kind, name string) (ConfigEntry, error) { 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) } diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_discoverychain.go b/vendor/github.com/hashicorp/consul/api/config_entry_discoverychain.go index acc05e13e..eeb3a1074 100644 --- a/vendor/github.com/hashicorp/consul/api/config_entry_discoverychain.go +++ b/vendor/github.com/hashicorp/consul/api/config_entry_discoverychain.go @@ -1,8 +1,13 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( "encoding/json" "time" + + "github.com/hashicorp/go-multierror" ) type ServiceRouterConfigEntry struct { @@ -169,6 +174,10 @@ type ServiceResolverConfigEntry struct { 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"` @@ -182,14 +191,19 @@ 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) } @@ -198,20 +212,27 @@ func (e *ServiceResolverConfigEntry) UnmarshalJSON(data []byte) error { type Alias ServiceResolverConfigEntry aux := &struct { ConnectTimeout string + RequestTimeout string *Alias }{ Alias: (*Alias)(e), } - if err := json.Unmarshal(data, &aux); err != nil { + var err error + if err = json.Unmarshal(data, &aux); err != nil { return err } - var err error + var merr *multierror.Error if aux.ConnectTimeout != "" { if e.ConnectTimeout, err = time.ParseDuration(aux.ConnectTimeout); err != nil { - return err + merr = multierror.Append(merr, err) } } - return nil + 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 } @@ -234,15 +255,18 @@ type ServiceResolverRedirect struct { 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"` + 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 { @@ -254,6 +278,20 @@ type ServiceResolverFailoverTarget struct { 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 { diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_exports.go b/vendor/github.com/hashicorp/consul/api/config_entry_exports.go index 52b0491f7..97920e40d 100644 --- a/vendor/github.com/hashicorp/consul/api/config_entry_exports.go +++ b/vendor/github.com/hashicorp/consul/api/config_entry_exports.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import "encoding/json" @@ -51,6 +54,9 @@ type ServiceConsumer struct { // 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 } diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_gateways.go b/vendor/github.com/hashicorp/consul/api/config_entry_gateways.go index 05e43832c..baf274e2d 100644 --- a/vendor/github.com/hashicorp/consul/api/config_entry_gateways.go +++ b/vendor/github.com/hashicorp/consul/api/config_entry_gateways.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api // IngressGatewayConfigEntry manages the configuration for an ingress service @@ -281,6 +284,10 @@ type APIGatewayListener struct { 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 @@ -299,3 +306,39 @@ type APIGatewayTLSConfiguration struct { // 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 index bbf12ccaa..47a1ead05 100644 --- a/vendor/github.com/hashicorp/consul/api/config_entry_inline_certificate.go +++ b/vendor/github.com/hashicorp/consul/api/config_entry_inline_certificate.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api // InlineCertificateConfigEntry -- TODO stub diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_intentions.go b/vendor/github.com/hashicorp/consul/api/config_entry_intentions.go index 0bff5e8e3..3f03b0875 100644 --- a/vendor/github.com/hashicorp/consul/api/config_entry_intentions.go +++ b/vendor/github.com/hashicorp/consul/api/config_entry_intentions.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import "time" @@ -9,6 +12,7 @@ type ServiceIntentionsConfigEntry struct { Namespace string `json:",omitempty"` Sources []*SourceIntention + JWT *IntentionJWTRequirement `json:",omitempty"` Meta map[string]string `json:",omitempty"` @@ -17,15 +21,16 @@ type ServiceIntentionsConfigEntry struct { } type SourceIntention struct { - Name string - Peer string `json:",omitempty"` - Partition string `json:",omitempty"` - Namespace string `json:",omitempty"` - Action IntentionAction `json:",omitempty"` - Permissions []*IntentionPermission `json:",omitempty"` - Precedence int - Type IntentionSourceType - Description string `json:",omitempty"` + 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"` @@ -44,6 +49,7 @@ func (e *ServiceIntentionsConfigEntry) GetModifyIndex() uint64 { return e.Mo type IntentionPermission struct { Action IntentionAction HTTP *IntentionHTTPPermission `json:",omitempty"` + JWT *IntentionJWTRequirement `json:",omitempty"` } type IntentionHTTPPermission struct { @@ -65,3 +71,30 @@ type IntentionHTTPHeaderPermission struct { 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 new file mode 100644 index 000000000..270f0d564 --- /dev/null +++ b/vendor/github.com/hashicorp/consul/api/config_entry_jwt_provider.go @@ -0,0 +1,310 @@ +// 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 index 98b882247..1a1ebb8b5 100644 --- a/vendor/github.com/hashicorp/consul/api/config_entry_mesh.go +++ b/vendor/github.com/hashicorp/consul/api/config_entry_mesh.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( @@ -19,6 +22,10 @@ type MeshConfigEntry struct { // 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"` 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 new file mode 100644 index 000000000..7af2a2658 --- /dev/null +++ b/vendor/github.com/hashicorp/consul/api/config_entry_rate_limit_ip.go @@ -0,0 +1,91 @@ +// 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 index 2edf9b23a..bbaa032d5 100644 --- a/vendor/github.com/hashicorp/consul/api/config_entry_routes.go +++ b/vendor/github.com/hashicorp/consul/api/config_entry_routes.go @@ -1,5 +1,10 @@ +// 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. @@ -192,8 +197,17 @@ type HTTPQueryMatch struct { // 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 + 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. @@ -207,12 +221,32 @@ 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. @@ -228,10 +262,15 @@ type HTTPService struct { // 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"` 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 new file mode 100644 index 000000000..1217efe7d --- /dev/null +++ b/vendor/github.com/hashicorp/consul/api/config_entry_sameness_group.go @@ -0,0 +1,29 @@ +// 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 index 83523643b..997066f24 100644 --- a/vendor/github.com/hashicorp/consul/api/config_entry_status.go +++ b/vendor/github.com/hashicorp/consul/api/config_entry_status.go @@ -1,7 +1,13 @@ +// 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 @@ -43,7 +49,7 @@ 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 string + 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 @@ -55,3 +61,298 @@ type Condition struct { // 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 index a40d1e232..77be00034 100644 --- a/vendor/github.com/hashicorp/consul/api/connect.go +++ b/vendor/github.com/hashicorp/consul/api/connect.go @@ -1,5 +1,11 @@ +// 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 { diff --git a/vendor/github.com/hashicorp/consul/api/connect_ca.go b/vendor/github.com/hashicorp/consul/api/connect_ca.go index 69c652dac..8a5c9f870 100644 --- a/vendor/github.com/hashicorp/consul/api/connect_ca.go +++ b/vendor/github.com/hashicorp/consul/api/connect_ca.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/vendor/github.com/hashicorp/consul/api/connect_intention.go b/vendor/github.com/hashicorp/consul/api/connect_intention.go index 0c2500fd0..e91c03e8b 100644 --- a/vendor/github.com/hashicorp/consul/api/connect_intention.go +++ b/vendor/github.com/hashicorp/consul/api/connect_intention.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( @@ -40,6 +43,10 @@ type Intention struct { // 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 diff --git a/vendor/github.com/hashicorp/consul/api/coordinate.go b/vendor/github.com/hashicorp/consul/api/coordinate.go index 7ef6ce274..b0269adae 100644 --- a/vendor/github.com/hashicorp/consul/api/coordinate.go +++ b/vendor/github.com/hashicorp/consul/api/coordinate.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/vendor/github.com/hashicorp/consul/api/debug.go b/vendor/github.com/hashicorp/consul/api/debug.go index b7e80b88d..e6b5dc52d 100644 --- a/vendor/github.com/hashicorp/consul/api/debug.go +++ b/vendor/github.com/hashicorp/consul/api/debug.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/vendor/github.com/hashicorp/consul/api/discovery_chain.go b/vendor/github.com/hashicorp/consul/api/discovery_chain.go index 4217603cf..4b6260cf3 100644 --- a/vendor/github.com/hashicorp/consul/api/discovery_chain.go +++ b/vendor/github.com/hashicorp/consul/api/discovery_chain.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( @@ -221,6 +224,7 @@ func (r *DiscoveryResolver) UnmarshalJSON(data []byte) error { // compiled form of ServiceResolverFailover type DiscoveryFailover struct { Targets []string + Policy ServiceResolverFailoverPolicy `json:",omitempty"` } // DiscoveryTarget represents all of the inputs necessary to use a resolver diff --git a/vendor/github.com/hashicorp/consul/api/event.go b/vendor/github.com/hashicorp/consul/api/event.go index ceded6598..efba89d3b 100644 --- a/vendor/github.com/hashicorp/consul/api/event.go +++ b/vendor/github.com/hashicorp/consul/api/event.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/vendor/github.com/hashicorp/consul/api/health.go b/vendor/github.com/hashicorp/consul/api/health.go index a89b4b727..a02300204 100644 --- a/vendor/github.com/hashicorp/consul/api/health.go +++ b/vendor/github.com/hashicorp/consul/api/health.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( @@ -64,6 +67,7 @@ type HealthCheckDefinition struct { TLSServerName string TLSSkipVerify bool TCP string + TCPUseTLS bool UDP string GRPC string OSService string diff --git a/vendor/github.com/hashicorp/consul/api/internal.go b/vendor/github.com/hashicorp/consul/api/internal.go new file mode 100644 index 000000000..b5f400f4b --- /dev/null +++ b/vendor/github.com/hashicorp/consul/api/internal.go @@ -0,0 +1,67 @@ +// 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 index 85a9d7750..b9d330a6f 100644 --- a/vendor/github.com/hashicorp/consul/api/kv.go +++ b/vendor/github.com/hashicorp/consul/api/kv.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/vendor/github.com/hashicorp/consul/api/lock.go b/vendor/github.com/hashicorp/consul/api/lock.go index 221a7add3..e9529f7bd 100644 --- a/vendor/github.com/hashicorp/consul/api/lock.go +++ b/vendor/github.com/hashicorp/consul/api/lock.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/vendor/github.com/hashicorp/consul/api/namespace.go b/vendor/github.com/hashicorp/consul/api/namespace.go index 65cc6f3f3..98afd2299 100644 --- a/vendor/github.com/hashicorp/consul/api/namespace.go +++ b/vendor/github.com/hashicorp/consul/api/namespace.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/vendor/github.com/hashicorp/consul/api/operator.go b/vendor/github.com/hashicorp/consul/api/operator.go index 079e22486..667dcd872 100644 --- a/vendor/github.com/hashicorp/consul/api/operator.go +++ b/vendor/github.com/hashicorp/consul/api/operator.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api // Operator can be used to perform low-level operator tasks for Consul. diff --git a/vendor/github.com/hashicorp/consul/api/operator_area.go b/vendor/github.com/hashicorp/consul/api/operator_area.go index f9fa1339e..9228d89b4 100644 --- a/vendor/github.com/hashicorp/consul/api/operator_area.go +++ b/vendor/github.com/hashicorp/consul/api/operator_area.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api // The /v1/operator/area endpoints are available only in Consul Enterprise and diff --git a/vendor/github.com/hashicorp/consul/api/operator_audit.go b/vendor/github.com/hashicorp/consul/api/operator_audit.go new file mode 100644 index 000000000..5240d38a7 --- /dev/null +++ b/vendor/github.com/hashicorp/consul/api/operator_audit.go @@ -0,0 +1,40 @@ +// 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 index 6ab576970..7628bf6f2 100644 --- a/vendor/github.com/hashicorp/consul/api/operator_autopilot.go +++ b/vendor/github.com/hashicorp/consul/api/operator_autopilot.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/vendor/github.com/hashicorp/consul/api/operator_keyring.go b/vendor/github.com/hashicorp/consul/api/operator_keyring.go index 6db31a252..aefec9e27 100644 --- a/vendor/github.com/hashicorp/consul/api/operator_keyring.go +++ b/vendor/github.com/hashicorp/consul/api/operator_keyring.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api // keyringRequest is used for performing Keyring operations diff --git a/vendor/github.com/hashicorp/consul/api/operator_license.go b/vendor/github.com/hashicorp/consul/api/operator_license.go index 74eed3baa..1e3496da0 100644 --- a/vendor/github.com/hashicorp/consul/api/operator_license.go +++ b/vendor/github.com/hashicorp/consul/api/operator_license.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/vendor/github.com/hashicorp/consul/api/operator_raft.go b/vendor/github.com/hashicorp/consul/api/operator_raft.go index 1da20e899..f0f5794aa 100644 --- a/vendor/github.com/hashicorp/consul/api/operator_raft.go +++ b/vendor/github.com/hashicorp/consul/api/operator_raft.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api // RaftServer has information about a server in the Raft configuration. @@ -25,6 +28,9 @@ type RaftServer struct { // 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. @@ -62,9 +68,14 @@ func (op *Operator) RaftGetConfiguration(q *QueryOptions) (*RaftConfiguration, e } // RaftLeaderTransfer is used to transfer the current raft leader to another node -func (op *Operator) RaftLeaderTransfer(q *QueryOptions) (*TransferLeaderResponse, error) { +// 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 diff --git a/vendor/github.com/hashicorp/consul/api/operator_segment.go b/vendor/github.com/hashicorp/consul/api/operator_segment.go index 92b05d3c0..6115a7ab4 100644 --- a/vendor/github.com/hashicorp/consul/api/operator_segment.go +++ b/vendor/github.com/hashicorp/consul/api/operator_segment.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api // SegmentList returns all the available LAN segments. diff --git a/vendor/github.com/hashicorp/consul/api/operator_usage.go b/vendor/github.com/hashicorp/consul/api/operator_usage.go index d07e774d8..8977449dd 100644 --- a/vendor/github.com/hashicorp/consul/api/operator_usage.go +++ b/vendor/github.com/hashicorp/consul/api/operator_usage.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api type Usage struct { @@ -7,6 +10,7 @@ type Usage struct { // 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 diff --git a/vendor/github.com/hashicorp/consul/api/partition.go b/vendor/github.com/hashicorp/consul/api/partition.go index 88edfb7b0..8467c3118 100644 --- a/vendor/github.com/hashicorp/consul/api/partition.go +++ b/vendor/github.com/hashicorp/consul/api/partition.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/vendor/github.com/hashicorp/consul/api/peering.go b/vendor/github.com/hashicorp/consul/api/peering.go index 34602c878..dd7780f63 100644 --- a/vendor/github.com/hashicorp/consul/api/peering.go +++ b/vendor/github.com/hashicorp/consul/api/peering.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( @@ -44,6 +47,16 @@ type PeeringRemoteInfo struct { 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 { diff --git a/vendor/github.com/hashicorp/consul/api/prepared_query.go b/vendor/github.com/hashicorp/consul/api/prepared_query.go index f47a58373..8ebc852f3 100644 --- a/vendor/github.com/hashicorp/consul/api/prepared_query.go +++ b/vendor/github.com/hashicorp/consul/api/prepared_query.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api // QueryFailoverOptions sets options about how we fail over if there are no @@ -26,6 +29,14 @@ type QueryFailoverTarget struct { // 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. @@ -40,9 +51,17 @@ 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. @@ -50,7 +69,7 @@ type ServiceQuery struct { // Failover controls what we do if there are no healthy nodes in the // local datacenter. - Failover QueryFailoverOptions + 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 diff --git a/vendor/github.com/hashicorp/consul/api/raw.go b/vendor/github.com/hashicorp/consul/api/raw.go index 745a208c9..639513d29 100644 --- a/vendor/github.com/hashicorp/consul/api/raw.go +++ b/vendor/github.com/hashicorp/consul/api/raw.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api // Raw can be used to do raw queries against custom endpoints diff --git a/vendor/github.com/hashicorp/consul/api/semaphore.go b/vendor/github.com/hashicorp/consul/api/semaphore.go index 066ce33a9..9d98ff5c2 100644 --- a/vendor/github.com/hashicorp/consul/api/semaphore.go +++ b/vendor/github.com/hashicorp/consul/api/semaphore.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/vendor/github.com/hashicorp/consul/api/session.go b/vendor/github.com/hashicorp/consul/api/session.go index 3f61acfbb..69fd77d27 100644 --- a/vendor/github.com/hashicorp/consul/api/session.go +++ b/vendor/github.com/hashicorp/consul/api/session.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/vendor/github.com/hashicorp/consul/api/snapshot.go b/vendor/github.com/hashicorp/consul/api/snapshot.go index b526b79c3..bcc80e5b3 100644 --- a/vendor/github.com/hashicorp/consul/api/snapshot.go +++ b/vendor/github.com/hashicorp/consul/api/snapshot.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/vendor/github.com/hashicorp/consul/api/status.go b/vendor/github.com/hashicorp/consul/api/status.go index 86f943bc7..8c52eb222 100644 --- a/vendor/github.com/hashicorp/consul/api/status.go +++ b/vendor/github.com/hashicorp/consul/api/status.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api // Status can be used to query the Status endpoints diff --git a/vendor/github.com/hashicorp/consul/api/txn.go b/vendor/github.com/hashicorp/consul/api/txn.go index 4aa06d9f5..59adafdac 100644 --- a/vendor/github.com/hashicorp/consul/api/txn.go +++ b/vendor/github.com/hashicorp/consul/api/txn.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/vendor/github.com/hashicorp/go-hclog/LICENSE b/vendor/github.com/hashicorp/go-hclog/LICENSE index abaf1e45f..9938fb50e 100644 --- a/vendor/github.com/hashicorp/go-hclog/LICENSE +++ b/vendor/github.com/hashicorp/go-hclog/LICENSE @@ -1,6 +1,4 @@ -MIT License - -Copyright (c) 2017 HashiCorp +Copyright (c) 2017 HashiCorp, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/hashicorp/go-hclog/colorize_unix.go b/vendor/github.com/hashicorp/go-hclog/colorize_unix.go index 99cc176a4..d00816b38 100644 --- a/vendor/github.com/hashicorp/go-hclog/colorize_unix.go +++ b/vendor/github.com/hashicorp/go-hclog/colorize_unix.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MIT + //go:build !windows // +build !windows @@ -7,23 +10,35 @@ import ( "github.com/mattn/go-isatty" ) +// hasFD is used to check if the writer has an Fd value to check +// if it's a terminal. +type hasFD interface { + Fd() uintptr +} + // setColorization will mutate the values of this logger // to appropriately configure colorization options. It provides // a wrapper to the output stream on Windows systems. func (l *intLogger) setColorization(opts *LoggerOptions) { - switch opts.Color { - case ColorOff: - fallthrough - case ForceColor: + if opts.Color != AutoColor { return - case AutoColor: - fi := l.checkWriterIsFile() - isUnixTerm := isatty.IsTerminal(fi.Fd()) - isCygwinTerm := isatty.IsCygwinTerminal(fi.Fd()) - isTerm := isUnixTerm || isCygwinTerm - if !isTerm { + } + + if sc, ok := l.writer.w.(SupportsColor); ok { + if !sc.SupportsColor() { l.headerColor = ColorOff l.writer.color = ColorOff } + return + } + + fi, ok := l.writer.w.(hasFD) + if !ok { + return + } + + if !isatty.IsTerminal(fi.Fd()) { + l.headerColor = ColorOff + l.writer.color = ColorOff } } diff --git a/vendor/github.com/hashicorp/go-hclog/colorize_windows.go b/vendor/github.com/hashicorp/go-hclog/colorize_windows.go index 26f8cef8d..2c3fb9ea6 100644 --- a/vendor/github.com/hashicorp/go-hclog/colorize_windows.go +++ b/vendor/github.com/hashicorp/go-hclog/colorize_windows.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MIT + //go:build windows // +build windows @@ -7,32 +10,32 @@ import ( "os" colorable "github.com/mattn/go-colorable" - "github.com/mattn/go-isatty" ) // setColorization will mutate the values of this logger // to appropriately configure colorization options. It provides // a wrapper to the output stream on Windows systems. func (l *intLogger) setColorization(opts *LoggerOptions) { - switch opts.Color { - case ColorOff: + if opts.Color == ColorOff { + return + } + + fi, ok := l.writer.w.(*os.File) + if !ok { + l.writer.color = ColorOff + l.headerColor = ColorOff return - case ForceColor: - fi := l.checkWriterIsFile() - l.writer.w = colorable.NewColorable(fi) - case AutoColor: - fi := l.checkWriterIsFile() - isUnixTerm := isatty.IsTerminal(os.Stdout.Fd()) - isCygwinTerm := isatty.IsCygwinTerminal(os.Stdout.Fd()) - isTerm := isUnixTerm || isCygwinTerm - if !isTerm { - l.writer.color = ColorOff - l.headerColor = ColorOff - return - } - - if l.headerColor == ColorOff { - l.writer.w = colorable.NewColorable(fi) - } + } + + cfi := colorable.NewColorable(fi) + + // NewColorable detects if color is possible and if it's not, then it + // returns the original value. So we can test if we got the original + // value back to know if color is possible. + if cfi == fi { + l.writer.color = ColorOff + l.headerColor = ColorOff + } else { + l.writer.w = cfi } } diff --git a/vendor/github.com/hashicorp/go-hclog/context.go b/vendor/github.com/hashicorp/go-hclog/context.go index 7815f5019..eb5aba556 100644 --- a/vendor/github.com/hashicorp/go-hclog/context.go +++ b/vendor/github.com/hashicorp/go-hclog/context.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MIT + package hclog import ( diff --git a/vendor/github.com/hashicorp/go-hclog/exclude.go b/vendor/github.com/hashicorp/go-hclog/exclude.go index cfd4307a8..4b73ba553 100644 --- a/vendor/github.com/hashicorp/go-hclog/exclude.go +++ b/vendor/github.com/hashicorp/go-hclog/exclude.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MIT + package hclog import ( diff --git a/vendor/github.com/hashicorp/go-hclog/global.go b/vendor/github.com/hashicorp/go-hclog/global.go index 48ff1f3a4..a7403f593 100644 --- a/vendor/github.com/hashicorp/go-hclog/global.go +++ b/vendor/github.com/hashicorp/go-hclog/global.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MIT + package hclog import ( diff --git a/vendor/github.com/hashicorp/go-hclog/interceptlogger.go b/vendor/github.com/hashicorp/go-hclog/interceptlogger.go index ff42f1bfc..e9b1c1885 100644 --- a/vendor/github.com/hashicorp/go-hclog/interceptlogger.go +++ b/vendor/github.com/hashicorp/go-hclog/interceptlogger.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MIT + package hclog import ( diff --git a/vendor/github.com/hashicorp/go-hclog/intlogger.go b/vendor/github.com/hashicorp/go-hclog/intlogger.go index 9312f3c0c..b45064acf 100644 --- a/vendor/github.com/hashicorp/go-hclog/intlogger.go +++ b/vendor/github.com/hashicorp/go-hclog/intlogger.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MIT + package hclog import ( @@ -8,7 +11,6 @@ import ( "fmt" "io" "log" - "os" "reflect" "runtime" "sort" @@ -17,6 +19,8 @@ import ( "sync" "sync/atomic" "time" + "unicode" + "unicode/utf8" "github.com/fatih/color" ) @@ -84,6 +88,8 @@ type intLogger struct { // create subloggers with their own level setting independentLevels bool + + subloggerHook func(sub Logger) Logger } // New returns a configured logger. @@ -150,6 +156,7 @@ func newLogger(opts *LoggerOptions) *intLogger { independentLevels: opts.IndependentLevels, headerColor: headerColor, fieldColor: fieldColor, + subloggerHook: opts.SubloggerHook, } if opts.IncludeLocation { l.callerOffset = offsetIntLogger + opts.AdditionalLocationOffset @@ -165,6 +172,10 @@ func newLogger(opts *LoggerOptions) *intLogger { l.timeFormat = opts.TimeFormat } + if l.subloggerHook == nil { + l.subloggerHook = identityHook + } + l.setColorization(opts) atomic.StoreInt32(l.level, int32(level)) @@ -172,6 +183,10 @@ func newLogger(opts *LoggerOptions) *intLogger { return l } +func identityHook(logger Logger) Logger { + return logger +} + // offsetIntLogger is the stack frame offset in the call stack for the caller to // one of the Warn, Info, Log, etc methods. const offsetIntLogger = 3 @@ -259,7 +274,6 @@ func needsQuoting(str string) bool { // 2. Color the whole log line, based on the level. // 3. Color only the header (level) part of the log line. // 4. Color both the header and fields of the log line. -// func (l *intLogger) logPlain(t time.Time, name string, level Level, msg string, args ...interface{}) { if !l.disableTime { @@ -420,7 +434,9 @@ func (l *intLogger) logPlain(t time.Time, name string, level Level, msg string, } else { l.writer.WriteByte('=') } - l.writer.WriteString(strconv.Quote(val)) + l.writer.WriteByte('"') + writeEscapedForOutput(l.writer, val, true) + l.writer.WriteByte('"') } else { l.writer.WriteByte(' ') l.writer.WriteString(key) @@ -448,19 +464,98 @@ func writeIndent(w *writer, str string, indent string) { if nl == -1 { if str != "" { w.WriteString(indent) - w.WriteString(str) + writeEscapedForOutput(w, str, false) w.WriteString("\n") } return } w.WriteString(indent) - w.WriteString(str[:nl]) + writeEscapedForOutput(w, str[:nl], false) w.WriteString("\n") str = str[nl+1:] } } +func needsEscaping(str string) bool { + for _, b := range str { + if !unicode.IsPrint(b) || b == '"' { + return true + } + } + + return false +} + +const ( + lowerhex = "0123456789abcdef" +) + +var bufPool = sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, +} + +func writeEscapedForOutput(w io.Writer, str string, escapeQuotes bool) { + if !needsEscaping(str) { + w.Write([]byte(str)) + return + } + + bb := bufPool.Get().(*bytes.Buffer) + bb.Reset() + + defer bufPool.Put(bb) + + for _, r := range str { + if escapeQuotes && r == '"' { + bb.WriteString(`\"`) + } else if unicode.IsPrint(r) { + bb.WriteRune(r) + } else { + switch r { + case '\a': + bb.WriteString(`\a`) + case '\b': + bb.WriteString(`\b`) + case '\f': + bb.WriteString(`\f`) + case '\n': + bb.WriteString(`\n`) + case '\r': + bb.WriteString(`\r`) + case '\t': + bb.WriteString(`\t`) + case '\v': + bb.WriteString(`\v`) + default: + switch { + case r < ' ': + bb.WriteString(`\x`) + bb.WriteByte(lowerhex[byte(r)>>4]) + bb.WriteByte(lowerhex[byte(r)&0xF]) + case !utf8.ValidRune(r): + r = 0xFFFD + fallthrough + case r < 0x10000: + bb.WriteString(`\u`) + for s := 12; s >= 0; s -= 4 { + bb.WriteByte(lowerhex[r>>uint(s)&0xF]) + } + default: + bb.WriteString(`\U`) + for s := 28; s >= 0; s -= 4 { + bb.WriteByte(lowerhex[r>>uint(s)&0xF]) + } + } + } + } + } + + w.Write(bb.Bytes()) +} + func (l *intLogger) renderSlice(v reflect.Value) string { var buf bytes.Buffer @@ -693,7 +788,7 @@ func (l *intLogger) With(args ...interface{}) Logger { sl.implied = append(sl.implied, MissingKey, extra) } - return sl + return l.subloggerHook(sl) } // Create a new sub-Logger that a name decending from the current name. @@ -707,7 +802,7 @@ func (l *intLogger) Named(name string) Logger { sl.name = name } - return sl + return l.subloggerHook(sl) } // Create a new sub-Logger with an explicit name. This ignores the current @@ -718,7 +813,7 @@ func (l *intLogger) ResetNamed(name string) Logger { sl.name = name - return sl + return l.subloggerHook(sl) } func (l *intLogger) ResetOutput(opts *LoggerOptions) error { @@ -762,6 +857,11 @@ func (l *intLogger) SetLevel(level Level) { atomic.StoreInt32(l.level, int32(level)) } +// Returns the current level +func (l *intLogger) GetLevel() Level { + return Level(atomic.LoadInt32(l.level)) +} + // Create a *log.Logger that will send it's data through this Logger. This // allows packages that expect to be using the standard library log to actually // use this logger. @@ -789,16 +889,6 @@ func (l *intLogger) StandardWriter(opts *StandardLoggerOptions) io.Writer { } } -// checks if the underlying io.Writer is a file, and -// panics if not. For use by colorization. -func (l *intLogger) checkWriterIsFile() *os.File { - fi, ok := l.writer.w.(*os.File) - if !ok { - panic("Cannot enable coloring of non-file Writers") - } - return fi -} - // Accept implements the SinkAdapter interface func (i *intLogger) Accept(name string, level Level, msg string, args ...interface{}) { i.log(name, level, msg, args...) diff --git a/vendor/github.com/hashicorp/go-hclog/logger.go b/vendor/github.com/hashicorp/go-hclog/logger.go index 50dee8220..947ac0c9a 100644 --- a/vendor/github.com/hashicorp/go-hclog/logger.go +++ b/vendor/github.com/hashicorp/go-hclog/logger.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MIT + package hclog import ( @@ -89,6 +92,13 @@ const ( ForceColor ) +// SupportsColor is an optional interface that can be implemented by the output +// value. If implemented and SupportsColor() returns true, then AutoColor will +// enable colorization. +type SupportsColor interface { + SupportsColor() bool +} + // LevelFromString returns a Level type for the named log level, or "NoLevel" if // the level string is invalid. This facilitates setting the log level via // config or environment variable by name in a predictable way. @@ -198,6 +208,9 @@ type Logger interface { // implementation cannot update the level on the fly, it should no-op. SetLevel(level Level) + // Returns the current level + GetLevel() Level + // Return a value that conforms to the stdlib log.Logger interface StandardLogger(opts *StandardLoggerOptions) *log.Logger @@ -289,6 +302,13 @@ type LoggerOptions struct { // logger will not affect any subloggers, and SetLevel on any subloggers // will not affect the parent or sibling loggers. IndependentLevels bool + + // SubloggerHook registers a function that is called when a sublogger via + // Named, With, or ResetNamed is created. If defined, the function is passed + // the newly created Logger and the returned Logger is returned from the + // original function. This option allows customization via interception and + // wrapping of Logger instances. + SubloggerHook func(sub Logger) Logger } // InterceptLogger describes the interface for using a logger diff --git a/vendor/github.com/hashicorp/go-hclog/nulllogger.go b/vendor/github.com/hashicorp/go-hclog/nulllogger.go index bc14f7708..d43da809e 100644 --- a/vendor/github.com/hashicorp/go-hclog/nulllogger.go +++ b/vendor/github.com/hashicorp/go-hclog/nulllogger.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MIT + package hclog import ( @@ -49,6 +52,8 @@ func (l *nullLogger) ResetNamed(name string) Logger { return l } func (l *nullLogger) SetLevel(level Level) {} +func (l *nullLogger) GetLevel() Level { return NoLevel } + func (l *nullLogger) StandardLogger(opts *StandardLoggerOptions) *log.Logger { return log.New(l.StandardWriter(opts), "", log.LstdFlags) } diff --git a/vendor/github.com/hashicorp/go-hclog/stdlog.go b/vendor/github.com/hashicorp/go-hclog/stdlog.go index 641f20ccb..03739b61f 100644 --- a/vendor/github.com/hashicorp/go-hclog/stdlog.go +++ b/vendor/github.com/hashicorp/go-hclog/stdlog.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MIT + package hclog import ( diff --git a/vendor/github.com/hashicorp/go-hclog/writer.go b/vendor/github.com/hashicorp/go-hclog/writer.go index 421a1f06c..4ee219bf0 100644 --- a/vendor/github.com/hashicorp/go-hclog/writer.go +++ b/vendor/github.com/hashicorp/go-hclog/writer.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MIT + package hclog import ( diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go index 39bbcf00f..d569c0c94 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_bsd.go +++ b/vendor/github.com/mattn/go-isatty/isatty_bsd.go @@ -1,5 +1,5 @@ -//go:build (darwin || freebsd || openbsd || netbsd || dragonfly) && !appengine -// +build darwin freebsd openbsd netbsd dragonfly +//go:build (darwin || freebsd || openbsd || netbsd || dragonfly || hurd) && !appengine +// +build darwin freebsd openbsd netbsd dragonfly hurd // +build !appengine package isatty diff --git a/vendor/golang.org/x/exp/LICENSE b/vendor/golang.org/x/exp/LICENSE new file mode 100644 index 000000000..6a66aea5e --- /dev/null +++ b/vendor/golang.org/x/exp/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/exp/PATENTS b/vendor/golang.org/x/exp/PATENTS new file mode 100644 index 000000000..733099041 --- /dev/null +++ b/vendor/golang.org/x/exp/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/exp/constraints/constraints.go b/vendor/golang.org/x/exp/constraints/constraints.go new file mode 100644 index 000000000..2c033dff4 --- /dev/null +++ b/vendor/golang.org/x/exp/constraints/constraints.go @@ -0,0 +1,50 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package constraints defines a set of useful constraints to be used +// with type parameters. +package constraints + +// Signed is a constraint that permits any signed integer type. +// If future releases of Go add new predeclared signed integer types, +// this constraint will be modified to include them. +type Signed interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 +} + +// Unsigned is a constraint that permits any unsigned integer type. +// If future releases of Go add new predeclared unsigned integer types, +// this constraint will be modified to include them. +type Unsigned interface { + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr +} + +// Integer is a constraint that permits any integer type. +// If future releases of Go add new predeclared integer types, +// this constraint will be modified to include them. +type Integer interface { + Signed | Unsigned +} + +// Float is a constraint that permits any floating-point type. +// If future releases of Go add new predeclared floating-point types, +// this constraint will be modified to include them. +type Float interface { + ~float32 | ~float64 +} + +// Complex is a constraint that permits any complex numeric type. +// If future releases of Go add new predeclared complex numeric types, +// this constraint will be modified to include them. +type Complex interface { + ~complex64 | ~complex128 +} + +// Ordered is a constraint that permits any ordered type: any type +// that supports the operators < <= >= >. +// If future releases of Go add new ordered types, +// this constraint will be modified to include them. +type Ordered interface { + Integer | Float | ~string +} diff --git a/vendor/golang.org/x/exp/slices/cmp.go b/vendor/golang.org/x/exp/slices/cmp.go new file mode 100644 index 000000000..fbf1934a0 --- /dev/null +++ b/vendor/golang.org/x/exp/slices/cmp.go @@ -0,0 +1,44 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package slices + +import "golang.org/x/exp/constraints" + +// min is a version of the predeclared function from the Go 1.21 release. +func min[T constraints.Ordered](a, b T) T { + if a < b || isNaN(a) { + return a + } + return b +} + +// max is a version of the predeclared function from the Go 1.21 release. +func max[T constraints.Ordered](a, b T) T { + if a > b || isNaN(a) { + return a + } + return b +} + +// cmpLess is a copy of cmp.Less from the Go 1.21 release. +func cmpLess[T constraints.Ordered](x, y T) bool { + return (isNaN(x) && !isNaN(y)) || x < y +} + +// cmpCompare is a copy of cmp.Compare from the Go 1.21 release. +func cmpCompare[T constraints.Ordered](x, y T) int { + xNaN := isNaN(x) + yNaN := isNaN(y) + if xNaN && yNaN { + return 0 + } + if xNaN || x < y { + return -1 + } + if yNaN || x > y { + return +1 + } + return 0 +} diff --git a/vendor/golang.org/x/exp/slices/slices.go b/vendor/golang.org/x/exp/slices/slices.go new file mode 100644 index 000000000..5e8158bba --- /dev/null +++ b/vendor/golang.org/x/exp/slices/slices.go @@ -0,0 +1,499 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package slices defines various functions useful with slices of any type. +package slices + +import ( + "unsafe" + + "golang.org/x/exp/constraints" +) + +// Equal reports whether two slices are equal: the same length and all +// elements equal. If the lengths are different, Equal returns false. +// Otherwise, the elements are compared in increasing index order, and the +// comparison stops at the first unequal pair. +// Floating point NaNs are not considered equal. +func Equal[S ~[]E, E comparable](s1, s2 S) bool { + if len(s1) != len(s2) { + return false + } + for i := range s1 { + if s1[i] != s2[i] { + return false + } + } + return true +} + +// EqualFunc reports whether two slices are equal using an equality +// function on each pair of elements. If the lengths are different, +// EqualFunc returns false. Otherwise, the elements are compared in +// increasing index order, and the comparison stops at the first index +// for which eq returns false. +func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool { + if len(s1) != len(s2) { + return false + } + for i, v1 := range s1 { + v2 := s2[i] + if !eq(v1, v2) { + return false + } + } + return true +} + +// Compare compares the elements of s1 and s2, using [cmp.Compare] on each pair +// of elements. The elements are compared sequentially, starting at index 0, +// until one element is not equal to the other. +// The result of comparing the first non-matching elements is returned. +// If both slices are equal until one of them ends, the shorter slice is +// considered less than the longer one. +// The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2. +func Compare[S ~[]E, E constraints.Ordered](s1, s2 S) int { + for i, v1 := range s1 { + if i >= len(s2) { + return +1 + } + v2 := s2[i] + if c := cmpCompare(v1, v2); c != 0 { + return c + } + } + if len(s1) < len(s2) { + return -1 + } + return 0 +} + +// CompareFunc is like [Compare] but uses a custom comparison function on each +// pair of elements. +// The result is the first non-zero result of cmp; if cmp always +// returns 0 the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2), +// and +1 if len(s1) > len(s2). +func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int { + for i, v1 := range s1 { + if i >= len(s2) { + return +1 + } + v2 := s2[i] + if c := cmp(v1, v2); c != 0 { + return c + } + } + if len(s1) < len(s2) { + return -1 + } + return 0 +} + +// Index returns the index of the first occurrence of v in s, +// or -1 if not present. +func Index[S ~[]E, E comparable](s S, v E) int { + for i := range s { + if v == s[i] { + return i + } + } + return -1 +} + +// IndexFunc returns the first index i satisfying f(s[i]), +// or -1 if none do. +func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int { + for i := range s { + if f(s[i]) { + return i + } + } + return -1 +} + +// Contains reports whether v is present in s. +func Contains[S ~[]E, E comparable](s S, v E) bool { + return Index(s, v) >= 0 +} + +// ContainsFunc reports whether at least one +// element e of s satisfies f(e). +func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool { + return IndexFunc(s, f) >= 0 +} + +// Insert inserts the values v... into s at index i, +// returning the modified slice. +// The elements at s[i:] are shifted up to make room. +// In the returned slice r, r[i] == v[0], +// and r[i+len(v)] == value originally at r[i]. +// Insert panics if i is out of range. +// This function is O(len(s) + len(v)). +func Insert[S ~[]E, E any](s S, i int, v ...E) S { + m := len(v) + if m == 0 { + return s + } + n := len(s) + if i == n { + return append(s, v...) + } + if n+m > cap(s) { + // Use append rather than make so that we bump the size of + // the slice up to the next storage class. + // This is what Grow does but we don't call Grow because + // that might copy the values twice. + s2 := append(s[:i], make(S, n+m-i)...) + copy(s2[i:], v) + copy(s2[i+m:], s[i:]) + return s2 + } + s = s[:n+m] + + // before: + // s: aaaaaaaabbbbccccccccdddd + // ^ ^ ^ ^ + // i i+m n n+m + // after: + // s: aaaaaaaavvvvbbbbcccccccc + // ^ ^ ^ ^ + // i i+m n n+m + // + // a are the values that don't move in s. + // v are the values copied in from v. + // b and c are the values from s that are shifted up in index. + // d are the values that get overwritten, never to be seen again. + + if !overlaps(v, s[i+m:]) { + // Easy case - v does not overlap either the c or d regions. + // (It might be in some of a or b, or elsewhere entirely.) + // The data we copy up doesn't write to v at all, so just do it. + + copy(s[i+m:], s[i:]) + + // Now we have + // s: aaaaaaaabbbbbbbbcccccccc + // ^ ^ ^ ^ + // i i+m n n+m + // Note the b values are duplicated. + + copy(s[i:], v) + + // Now we have + // s: aaaaaaaavvvvbbbbcccccccc + // ^ ^ ^ ^ + // i i+m n n+m + // That's the result we want. + return s + } + + // The hard case - v overlaps c or d. We can't just shift up + // the data because we'd move or clobber the values we're trying + // to insert. + // So instead, write v on top of d, then rotate. + copy(s[n:], v) + + // Now we have + // s: aaaaaaaabbbbccccccccvvvv + // ^ ^ ^ ^ + // i i+m n n+m + + rotateRight(s[i:], m) + + // Now we have + // s: aaaaaaaavvvvbbbbcccccccc + // ^ ^ ^ ^ + // i i+m n n+m + // That's the result we want. + return s +} + +// Delete removes the elements s[i:j] from s, returning the modified slice. +// Delete panics if s[i:j] is not a valid slice of s. +// Delete is O(len(s)-j), so if many items must be deleted, it is better to +// make a single call deleting them all together than to delete one at a time. +// Delete might not modify the elements s[len(s)-(j-i):len(s)]. If those +// elements contain pointers you might consider zeroing those elements so that +// objects they reference can be garbage collected. +func Delete[S ~[]E, E any](s S, i, j int) S { + _ = s[i:j] // bounds check + + return append(s[:i], s[j:]...) +} + +// DeleteFunc removes any elements from s for which del returns true, +// returning the modified slice. +// When DeleteFunc removes m elements, it might not modify the elements +// s[len(s)-m:len(s)]. If those elements contain pointers you might consider +// zeroing those elements so that objects they reference can be garbage +// collected. +func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S { + i := IndexFunc(s, del) + if i == -1 { + return s + } + // Don't start copying elements until we find one to delete. + for j := i + 1; j < len(s); j++ { + if v := s[j]; !del(v) { + s[i] = v + i++ + } + } + return s[:i] +} + +// Replace replaces the elements s[i:j] by the given v, and returns the +// modified slice. Replace panics if s[i:j] is not a valid slice of s. +func Replace[S ~[]E, E any](s S, i, j int, v ...E) S { + _ = s[i:j] // verify that i:j is a valid subslice + + if i == j { + return Insert(s, i, v...) + } + if j == len(s) { + return append(s[:i], v...) + } + + tot := len(s[:i]) + len(v) + len(s[j:]) + if tot > cap(s) { + // Too big to fit, allocate and copy over. + s2 := append(s[:i], make(S, tot-i)...) // See Insert + copy(s2[i:], v) + copy(s2[i+len(v):], s[j:]) + return s2 + } + + r := s[:tot] + + if i+len(v) <= j { + // Easy, as v fits in the deleted portion. + copy(r[i:], v) + if i+len(v) != j { + copy(r[i+len(v):], s[j:]) + } + return r + } + + // We are expanding (v is bigger than j-i). + // The situation is something like this: + // (example has i=4,j=8,len(s)=16,len(v)=6) + // s: aaaaxxxxbbbbbbbbyy + // ^ ^ ^ ^ + // i j len(s) tot + // a: prefix of s + // x: deleted range + // b: more of s + // y: area to expand into + + if !overlaps(r[i+len(v):], v) { + // Easy, as v is not clobbered by the first copy. + copy(r[i+len(v):], s[j:]) + copy(r[i:], v) + return r + } + + // This is a situation where we don't have a single place to which + // we can copy v. Parts of it need to go to two different places. + // We want to copy the prefix of v into y and the suffix into x, then + // rotate |y| spots to the right. + // + // v[2:] v[:2] + // | | + // s: aaaavvvvbbbbbbbbvv + // ^ ^ ^ ^ + // i j len(s) tot + // + // If either of those two destinations don't alias v, then we're good. + y := len(v) - (j - i) // length of y portion + + if !overlaps(r[i:j], v) { + copy(r[i:j], v[y:]) + copy(r[len(s):], v[:y]) + rotateRight(r[i:], y) + return r + } + if !overlaps(r[len(s):], v) { + copy(r[len(s):], v[:y]) + copy(r[i:j], v[y:]) + rotateRight(r[i:], y) + return r + } + + // Now we know that v overlaps both x and y. + // That means that the entirety of b is *inside* v. + // So we don't need to preserve b at all; instead we + // can copy v first, then copy the b part of v out of + // v to the right destination. + k := startIdx(v, s[j:]) + copy(r[i:], v) + copy(r[i+len(v):], r[i+k:]) + return r +} + +// Clone returns a copy of the slice. +// The elements are copied using assignment, so this is a shallow clone. +func Clone[S ~[]E, E any](s S) S { + // Preserve nil in case it matters. + if s == nil { + return nil + } + return append(S([]E{}), s...) +} + +// Compact replaces consecutive runs of equal elements with a single copy. +// This is like the uniq command found on Unix. +// Compact modifies the contents of the slice s and returns the modified slice, +// which may have a smaller length. +// When Compact discards m elements in total, it might not modify the elements +// s[len(s)-m:len(s)]. If those elements contain pointers you might consider +// zeroing those elements so that objects they reference can be garbage collected. +func Compact[S ~[]E, E comparable](s S) S { + if len(s) < 2 { + return s + } + i := 1 + for k := 1; k < len(s); k++ { + if s[k] != s[k-1] { + if i != k { + s[i] = s[k] + } + i++ + } + } + return s[:i] +} + +// CompactFunc is like [Compact] but uses an equality function to compare elements. +// For runs of elements that compare equal, CompactFunc keeps the first one. +func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S { + if len(s) < 2 { + return s + } + i := 1 + for k := 1; k < len(s); k++ { + if !eq(s[k], s[k-1]) { + if i != k { + s[i] = s[k] + } + i++ + } + } + return s[:i] +} + +// Grow increases the slice's capacity, if necessary, to guarantee space for +// another n elements. After Grow(n), at least n elements can be appended +// to the slice without another allocation. If n is negative or too large to +// allocate the memory, Grow panics. +func Grow[S ~[]E, E any](s S, n int) S { + if n < 0 { + panic("cannot be negative") + } + if n -= cap(s) - len(s); n > 0 { + // TODO(https://go.dev/issue/53888): Make using []E instead of S + // to workaround a compiler bug where the runtime.growslice optimization + // does not take effect. Revert when the compiler is fixed. + s = append([]E(s)[:cap(s)], make([]E, n)...)[:len(s)] + } + return s +} + +// Clip removes unused capacity from the slice, returning s[:len(s):len(s)]. +func Clip[S ~[]E, E any](s S) S { + return s[:len(s):len(s)] +} + +// Rotation algorithm explanation: +// +// rotate left by 2 +// start with +// 0123456789 +// split up like this +// 01 234567 89 +// swap first 2 and last 2 +// 89 234567 01 +// join first parts +// 89234567 01 +// recursively rotate first left part by 2 +// 23456789 01 +// join at the end +// 2345678901 +// +// rotate left by 8 +// start with +// 0123456789 +// split up like this +// 01 234567 89 +// swap first 2 and last 2 +// 89 234567 01 +// join last parts +// 89 23456701 +// recursively rotate second part left by 6 +// 89 01234567 +// join at the end +// 8901234567 + +// TODO: There are other rotate algorithms. +// This algorithm has the desirable property that it moves each element exactly twice. +// The triple-reverse algorithm is simpler and more cache friendly, but takes more writes. +// The follow-cycles algorithm can be 1-write but it is not very cache friendly. + +// rotateLeft rotates b left by n spaces. +// s_final[i] = s_orig[i+r], wrapping around. +func rotateLeft[E any](s []E, r int) { + for r != 0 && r != len(s) { + if r*2 <= len(s) { + swap(s[:r], s[len(s)-r:]) + s = s[:len(s)-r] + } else { + swap(s[:len(s)-r], s[r:]) + s, r = s[len(s)-r:], r*2-len(s) + } + } +} +func rotateRight[E any](s []E, r int) { + rotateLeft(s, len(s)-r) +} + +// swap swaps the contents of x and y. x and y must be equal length and disjoint. +func swap[E any](x, y []E) { + for i := 0; i < len(x); i++ { + x[i], y[i] = y[i], x[i] + } +} + +// overlaps reports whether the memory ranges a[0:len(a)] and b[0:len(b)] overlap. +func overlaps[E any](a, b []E) bool { + if len(a) == 0 || len(b) == 0 { + return false + } + elemSize := unsafe.Sizeof(a[0]) + if elemSize == 0 { + return false + } + // TODO: use a runtime/unsafe facility once one becomes available. See issue 12445. + // Also see crypto/internal/alias/alias.go:AnyOverlap + return uintptr(unsafe.Pointer(&a[0])) <= uintptr(unsafe.Pointer(&b[len(b)-1]))+(elemSize-1) && + uintptr(unsafe.Pointer(&b[0])) <= uintptr(unsafe.Pointer(&a[len(a)-1]))+(elemSize-1) +} + +// startIdx returns the index in haystack where the needle starts. +// prerequisite: the needle must be aliased entirely inside the haystack. +func startIdx[E any](haystack, needle []E) int { + p := &needle[0] + for i := range haystack { + if p == &haystack[i] { + return i + } + } + // TODO: what if the overlap is by a non-integral number of Es? + panic("needle not found") +} + +// Reverse reverses the elements of the slice in place. +func Reverse[S ~[]E, E any](s S) { + for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } +} diff --git a/vendor/golang.org/x/exp/slices/sort.go b/vendor/golang.org/x/exp/slices/sort.go new file mode 100644 index 000000000..b67897f76 --- /dev/null +++ b/vendor/golang.org/x/exp/slices/sort.go @@ -0,0 +1,195 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate go run $GOROOT/src/sort/gen_sort_variants.go -exp + +package slices + +import ( + "math/bits" + + "golang.org/x/exp/constraints" +) + +// Sort sorts a slice of any ordered type in ascending order. +// When sorting floating-point numbers, NaNs are ordered before other values. +func Sort[S ~[]E, E constraints.Ordered](x S) { + n := len(x) + pdqsortOrdered(x, 0, n, bits.Len(uint(n))) +} + +// SortFunc sorts the slice x in ascending order as determined by the cmp +// function. This sort is not guaranteed to be stable. +// cmp(a, b) should return a negative number when a < b, a positive number when +// a > b and zero when a == b. +// +// SortFunc requires that cmp is a strict weak ordering. +// See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings. +func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int) { + n := len(x) + pdqsortCmpFunc(x, 0, n, bits.Len(uint(n)), cmp) +} + +// SortStableFunc sorts the slice x while keeping the original order of equal +// elements, using cmp to compare elements in the same way as [SortFunc]. +func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int) { + stableCmpFunc(x, len(x), cmp) +} + +// IsSorted reports whether x is sorted in ascending order. +func IsSorted[S ~[]E, E constraints.Ordered](x S) bool { + for i := len(x) - 1; i > 0; i-- { + if cmpLess(x[i], x[i-1]) { + return false + } + } + return true +} + +// IsSortedFunc reports whether x is sorted in ascending order, with cmp as the +// comparison function as defined by [SortFunc]. +func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool { + for i := len(x) - 1; i > 0; i-- { + if cmp(x[i], x[i-1]) < 0 { + return false + } + } + return true +} + +// Min returns the minimal value in x. It panics if x is empty. +// For floating-point numbers, Min propagates NaNs (any NaN value in x +// forces the output to be NaN). +func Min[S ~[]E, E constraints.Ordered](x S) E { + if len(x) < 1 { + panic("slices.Min: empty list") + } + m := x[0] + for i := 1; i < len(x); i++ { + m = min(m, x[i]) + } + return m +} + +// MinFunc returns the minimal value in x, using cmp to compare elements. +// It panics if x is empty. If there is more than one minimal element +// according to the cmp function, MinFunc returns the first one. +func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E { + if len(x) < 1 { + panic("slices.MinFunc: empty list") + } + m := x[0] + for i := 1; i < len(x); i++ { + if cmp(x[i], m) < 0 { + m = x[i] + } + } + return m +} + +// Max returns the maximal value in x. It panics if x is empty. +// For floating-point E, Max propagates NaNs (any NaN value in x +// forces the output to be NaN). +func Max[S ~[]E, E constraints.Ordered](x S) E { + if len(x) < 1 { + panic("slices.Max: empty list") + } + m := x[0] + for i := 1; i < len(x); i++ { + m = max(m, x[i]) + } + return m +} + +// MaxFunc returns the maximal value in x, using cmp to compare elements. +// It panics if x is empty. If there is more than one maximal element +// according to the cmp function, MaxFunc returns the first one. +func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E { + if len(x) < 1 { + panic("slices.MaxFunc: empty list") + } + m := x[0] + for i := 1; i < len(x); i++ { + if cmp(x[i], m) > 0 { + m = x[i] + } + } + return m +} + +// BinarySearch searches for target in a sorted slice and returns the position +// where target is found, or the position where target would appear in the +// sort order; it also returns a bool saying whether the target is really found +// in the slice. The slice must be sorted in increasing order. +func BinarySearch[S ~[]E, E constraints.Ordered](x S, target E) (int, bool) { + // Inlining is faster than calling BinarySearchFunc with a lambda. + n := len(x) + // Define x[-1] < target and x[n] >= target. + // Invariant: x[i-1] < target, x[j] >= target. + i, j := 0, n + for i < j { + h := int(uint(i+j) >> 1) // avoid overflow when computing h + // i ≤ h < j + if cmpLess(x[h], target) { + i = h + 1 // preserves x[i-1] < target + } else { + j = h // preserves x[j] >= target + } + } + // i == j, x[i-1] < target, and x[j] (= x[i]) >= target => answer is i. + return i, i < n && (x[i] == target || (isNaN(x[i]) && isNaN(target))) +} + +// BinarySearchFunc works like [BinarySearch], but uses a custom comparison +// function. The slice must be sorted in increasing order, where "increasing" +// is defined by cmp. cmp should return 0 if the slice element matches +// the target, a negative number if the slice element precedes the target, +// or a positive number if the slice element follows the target. +// cmp must implement the same ordering as the slice, such that if +// cmp(a, t) < 0 and cmp(b, t) >= 0, then a must precede b in the slice. +func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool) { + n := len(x) + // Define cmp(x[-1], target) < 0 and cmp(x[n], target) >= 0 . + // Invariant: cmp(x[i - 1], target) < 0, cmp(x[j], target) >= 0. + i, j := 0, n + for i < j { + h := int(uint(i+j) >> 1) // avoid overflow when computing h + // i ≤ h < j + if cmp(x[h], target) < 0 { + i = h + 1 // preserves cmp(x[i - 1], target) < 0 + } else { + j = h // preserves cmp(x[j], target) >= 0 + } + } + // i == j, cmp(x[i-1], target) < 0, and cmp(x[j], target) (= cmp(x[i], target)) >= 0 => answer is i. + return i, i < n && cmp(x[i], target) == 0 +} + +type sortedHint int // hint for pdqsort when choosing the pivot + +const ( + unknownHint sortedHint = iota + increasingHint + decreasingHint +) + +// xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf +type xorshift uint64 + +func (r *xorshift) Next() uint64 { + *r ^= *r << 13 + *r ^= *r >> 17 + *r ^= *r << 5 + return uint64(*r) +} + +func nextPowerOfTwo(length int) uint { + return 1 << bits.Len(uint(length)) +} + +// isNaN reports whether x is a NaN without requiring the math package. +// This will always return false if T is not floating-point. +func isNaN[T constraints.Ordered](x T) bool { + return x != x +} diff --git a/vendor/golang.org/x/exp/slices/zsortanyfunc.go b/vendor/golang.org/x/exp/slices/zsortanyfunc.go new file mode 100644 index 000000000..06f2c7a24 --- /dev/null +++ b/vendor/golang.org/x/exp/slices/zsortanyfunc.go @@ -0,0 +1,479 @@ +// Code generated by gen_sort_variants.go; DO NOT EDIT. + +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package slices + +// insertionSortCmpFunc sorts data[a:b] using insertion sort. +func insertionSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) { + for i := a + 1; i < b; i++ { + for j := i; j > a && (cmp(data[j], data[j-1]) < 0); j-- { + data[j], data[j-1] = data[j-1], data[j] + } + } +} + +// siftDownCmpFunc implements the heap property on data[lo:hi]. +// first is an offset into the array where the root of the heap lies. +func siftDownCmpFunc[E any](data []E, lo, hi, first int, cmp func(a, b E) int) { + root := lo + for { + child := 2*root + 1 + if child >= hi { + break + } + if child+1 < hi && (cmp(data[first+child], data[first+child+1]) < 0) { + child++ + } + if !(cmp(data[first+root], data[first+child]) < 0) { + return + } + data[first+root], data[first+child] = data[first+child], data[first+root] + root = child + } +} + +func heapSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) { + first := a + lo := 0 + hi := b - a + + // Build heap with greatest element at top. + for i := (hi - 1) / 2; i >= 0; i-- { + siftDownCmpFunc(data, i, hi, first, cmp) + } + + // Pop elements, largest first, into end of data. + for i := hi - 1; i >= 0; i-- { + data[first], data[first+i] = data[first+i], data[first] + siftDownCmpFunc(data, lo, i, first, cmp) + } +} + +// pdqsortCmpFunc sorts data[a:b]. +// The algorithm based on pattern-defeating quicksort(pdqsort), but without the optimizations from BlockQuicksort. +// pdqsort paper: https://arxiv.org/pdf/2106.05123.pdf +// C++ implementation: https://github.com/orlp/pdqsort +// Rust implementation: https://docs.rs/pdqsort/latest/pdqsort/ +// limit is the number of allowed bad (very unbalanced) pivots before falling back to heapsort. +func pdqsortCmpFunc[E any](data []E, a, b, limit int, cmp func(a, b E) int) { + const maxInsertion = 12 + + var ( + wasBalanced = true // whether the last partitioning was reasonably balanced + wasPartitioned = true // whether the slice was already partitioned + ) + + for { + length := b - a + + if length <= maxInsertion { + insertionSortCmpFunc(data, a, b, cmp) + return + } + + // Fall back to heapsort if too many bad choices were made. + if limit == 0 { + heapSortCmpFunc(data, a, b, cmp) + return + } + + // If the last partitioning was imbalanced, we need to breaking patterns. + if !wasBalanced { + breakPatternsCmpFunc(data, a, b, cmp) + limit-- + } + + pivot, hint := choosePivotCmpFunc(data, a, b, cmp) + if hint == decreasingHint { + reverseRangeCmpFunc(data, a, b, cmp) + // The chosen pivot was pivot-a elements after the start of the array. + // After reversing it is pivot-a elements before the end of the array. + // The idea came from Rust's implementation. + pivot = (b - 1) - (pivot - a) + hint = increasingHint + } + + // The slice is likely already sorted. + if wasBalanced && wasPartitioned && hint == increasingHint { + if partialInsertionSortCmpFunc(data, a, b, cmp) { + return + } + } + + // Probably the slice contains many duplicate elements, partition the slice into + // elements equal to and elements greater than the pivot. + if a > 0 && !(cmp(data[a-1], data[pivot]) < 0) { + mid := partitionEqualCmpFunc(data, a, b, pivot, cmp) + a = mid + continue + } + + mid, alreadyPartitioned := partitionCmpFunc(data, a, b, pivot, cmp) + wasPartitioned = alreadyPartitioned + + leftLen, rightLen := mid-a, b-mid + balanceThreshold := length / 8 + if leftLen < rightLen { + wasBalanced = leftLen >= balanceThreshold + pdqsortCmpFunc(data, a, mid, limit, cmp) + a = mid + 1 + } else { + wasBalanced = rightLen >= balanceThreshold + pdqsortCmpFunc(data, mid+1, b, limit, cmp) + b = mid + } + } +} + +// partitionCmpFunc does one quicksort partition. +// Let p = data[pivot] +// Moves elements in data[a:b] around, so that data[i]

=p for inewpivot. +// On return, data[newpivot] = p +func partitionCmpFunc[E any](data []E, a, b, pivot int, cmp func(a, b E) int) (newpivot int, alreadyPartitioned bool) { + data[a], data[pivot] = data[pivot], data[a] + i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned + + for i <= j && (cmp(data[i], data[a]) < 0) { + i++ + } + for i <= j && !(cmp(data[j], data[a]) < 0) { + j-- + } + if i > j { + data[j], data[a] = data[a], data[j] + return j, true + } + data[i], data[j] = data[j], data[i] + i++ + j-- + + for { + for i <= j && (cmp(data[i], data[a]) < 0) { + i++ + } + for i <= j && !(cmp(data[j], data[a]) < 0) { + j-- + } + if i > j { + break + } + data[i], data[j] = data[j], data[i] + i++ + j-- + } + data[j], data[a] = data[a], data[j] + return j, false +} + +// partitionEqualCmpFunc partitions data[a:b] into elements equal to data[pivot] followed by elements greater than data[pivot]. +// It assumed that data[a:b] does not contain elements smaller than the data[pivot]. +func partitionEqualCmpFunc[E any](data []E, a, b, pivot int, cmp func(a, b E) int) (newpivot int) { + data[a], data[pivot] = data[pivot], data[a] + i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned + + for { + for i <= j && !(cmp(data[a], data[i]) < 0) { + i++ + } + for i <= j && (cmp(data[a], data[j]) < 0) { + j-- + } + if i > j { + break + } + data[i], data[j] = data[j], data[i] + i++ + j-- + } + return i +} + +// partialInsertionSortCmpFunc partially sorts a slice, returns true if the slice is sorted at the end. +func partialInsertionSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) bool { + const ( + maxSteps = 5 // maximum number of adjacent out-of-order pairs that will get shifted + shortestShifting = 50 // don't shift any elements on short arrays + ) + i := a + 1 + for j := 0; j < maxSteps; j++ { + for i < b && !(cmp(data[i], data[i-1]) < 0) { + i++ + } + + if i == b { + return true + } + + if b-a < shortestShifting { + return false + } + + data[i], data[i-1] = data[i-1], data[i] + + // Shift the smaller one to the left. + if i-a >= 2 { + for j := i - 1; j >= 1; j-- { + if !(cmp(data[j], data[j-1]) < 0) { + break + } + data[j], data[j-1] = data[j-1], data[j] + } + } + // Shift the greater one to the right. + if b-i >= 2 { + for j := i + 1; j < b; j++ { + if !(cmp(data[j], data[j-1]) < 0) { + break + } + data[j], data[j-1] = data[j-1], data[j] + } + } + } + return false +} + +// breakPatternsCmpFunc scatters some elements around in an attempt to break some patterns +// that might cause imbalanced partitions in quicksort. +func breakPatternsCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) { + length := b - a + if length >= 8 { + random := xorshift(length) + modulus := nextPowerOfTwo(length) + + for idx := a + (length/4)*2 - 1; idx <= a+(length/4)*2+1; idx++ { + other := int(uint(random.Next()) & (modulus - 1)) + if other >= length { + other -= length + } + data[idx], data[a+other] = data[a+other], data[idx] + } + } +} + +// choosePivotCmpFunc chooses a pivot in data[a:b]. +// +// [0,8): chooses a static pivot. +// [8,shortestNinther): uses the simple median-of-three method. +// [shortestNinther,∞): uses the Tukey ninther method. +func choosePivotCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) (pivot int, hint sortedHint) { + const ( + shortestNinther = 50 + maxSwaps = 4 * 3 + ) + + l := b - a + + var ( + swaps int + i = a + l/4*1 + j = a + l/4*2 + k = a + l/4*3 + ) + + if l >= 8 { + if l >= shortestNinther { + // Tukey ninther method, the idea came from Rust's implementation. + i = medianAdjacentCmpFunc(data, i, &swaps, cmp) + j = medianAdjacentCmpFunc(data, j, &swaps, cmp) + k = medianAdjacentCmpFunc(data, k, &swaps, cmp) + } + // Find the median among i, j, k and stores it into j. + j = medianCmpFunc(data, i, j, k, &swaps, cmp) + } + + switch swaps { + case 0: + return j, increasingHint + case maxSwaps: + return j, decreasingHint + default: + return j, unknownHint + } +} + +// order2CmpFunc returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a. +func order2CmpFunc[E any](data []E, a, b int, swaps *int, cmp func(a, b E) int) (int, int) { + if cmp(data[b], data[a]) < 0 { + *swaps++ + return b, a + } + return a, b +} + +// medianCmpFunc returns x where data[x] is the median of data[a],data[b],data[c], where x is a, b, or c. +func medianCmpFunc[E any](data []E, a, b, c int, swaps *int, cmp func(a, b E) int) int { + a, b = order2CmpFunc(data, a, b, swaps, cmp) + b, c = order2CmpFunc(data, b, c, swaps, cmp) + a, b = order2CmpFunc(data, a, b, swaps, cmp) + return b +} + +// medianAdjacentCmpFunc finds the median of data[a - 1], data[a], data[a + 1] and stores the index into a. +func medianAdjacentCmpFunc[E any](data []E, a int, swaps *int, cmp func(a, b E) int) int { + return medianCmpFunc(data, a-1, a, a+1, swaps, cmp) +} + +func reverseRangeCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) { + i := a + j := b - 1 + for i < j { + data[i], data[j] = data[j], data[i] + i++ + j-- + } +} + +func swapRangeCmpFunc[E any](data []E, a, b, n int, cmp func(a, b E) int) { + for i := 0; i < n; i++ { + data[a+i], data[b+i] = data[b+i], data[a+i] + } +} + +func stableCmpFunc[E any](data []E, n int, cmp func(a, b E) int) { + blockSize := 20 // must be > 0 + a, b := 0, blockSize + for b <= n { + insertionSortCmpFunc(data, a, b, cmp) + a = b + b += blockSize + } + insertionSortCmpFunc(data, a, n, cmp) + + for blockSize < n { + a, b = 0, 2*blockSize + for b <= n { + symMergeCmpFunc(data, a, a+blockSize, b, cmp) + a = b + b += 2 * blockSize + } + if m := a + blockSize; m < n { + symMergeCmpFunc(data, a, m, n, cmp) + } + blockSize *= 2 + } +} + +// symMergeCmpFunc merges the two sorted subsequences data[a:m] and data[m:b] using +// the SymMerge algorithm from Pok-Son Kim and Arne Kutzner, "Stable Minimum +// Storage Merging by Symmetric Comparisons", in Susanne Albers and Tomasz +// Radzik, editors, Algorithms - ESA 2004, volume 3221 of Lecture Notes in +// Computer Science, pages 714-723. Springer, 2004. +// +// Let M = m-a and N = b-n. Wolog M < N. +// The recursion depth is bound by ceil(log(N+M)). +// The algorithm needs O(M*log(N/M + 1)) calls to data.Less. +// The algorithm needs O((M+N)*log(M)) calls to data.Swap. +// +// The paper gives O((M+N)*log(M)) as the number of assignments assuming a +// rotation algorithm which uses O(M+N+gcd(M+N)) assignments. The argumentation +// in the paper carries through for Swap operations, especially as the block +// swapping rotate uses only O(M+N) Swaps. +// +// symMerge assumes non-degenerate arguments: a < m && m < b. +// Having the caller check this condition eliminates many leaf recursion calls, +// which improves performance. +func symMergeCmpFunc[E any](data []E, a, m, b int, cmp func(a, b E) int) { + // Avoid unnecessary recursions of symMerge + // by direct insertion of data[a] into data[m:b] + // if data[a:m] only contains one element. + if m-a == 1 { + // Use binary search to find the lowest index i + // such that data[i] >= data[a] for m <= i < b. + // Exit the search loop with i == b in case no such index exists. + i := m + j := b + for i < j { + h := int(uint(i+j) >> 1) + if cmp(data[h], data[a]) < 0 { + i = h + 1 + } else { + j = h + } + } + // Swap values until data[a] reaches the position before i. + for k := a; k < i-1; k++ { + data[k], data[k+1] = data[k+1], data[k] + } + return + } + + // Avoid unnecessary recursions of symMerge + // by direct insertion of data[m] into data[a:m] + // if data[m:b] only contains one element. + if b-m == 1 { + // Use binary search to find the lowest index i + // such that data[i] > data[m] for a <= i < m. + // Exit the search loop with i == m in case no such index exists. + i := a + j := m + for i < j { + h := int(uint(i+j) >> 1) + if !(cmp(data[m], data[h]) < 0) { + i = h + 1 + } else { + j = h + } + } + // Swap values until data[m] reaches the position i. + for k := m; k > i; k-- { + data[k], data[k-1] = data[k-1], data[k] + } + return + } + + mid := int(uint(a+b) >> 1) + n := mid + m + var start, r int + if m > mid { + start = n - b + r = mid + } else { + start = a + r = m + } + p := n - 1 + + for start < r { + c := int(uint(start+r) >> 1) + if !(cmp(data[p-c], data[c]) < 0) { + start = c + 1 + } else { + r = c + } + } + + end := n - start + if start < m && m < end { + rotateCmpFunc(data, start, m, end, cmp) + } + if a < start && start < mid { + symMergeCmpFunc(data, a, start, mid, cmp) + } + if mid < end && end < b { + symMergeCmpFunc(data, mid, end, b, cmp) + } +} + +// rotateCmpFunc rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data: +// Data of the form 'x u v y' is changed to 'x v u y'. +// rotate performs at most b-a many calls to data.Swap, +// and it assumes non-degenerate arguments: a < m && m < b. +func rotateCmpFunc[E any](data []E, a, m, b int, cmp func(a, b E) int) { + i := m - a + j := b - m + + for i != j { + if i > j { + swapRangeCmpFunc(data, m-i, m, j, cmp) + i -= j + } else { + swapRangeCmpFunc(data, m-i, m+j-i, i, cmp) + j -= i + } + } + // i == j + swapRangeCmpFunc(data, m-i, m, i, cmp) +} diff --git a/vendor/golang.org/x/exp/slices/zsortordered.go b/vendor/golang.org/x/exp/slices/zsortordered.go new file mode 100644 index 000000000..99b47c398 --- /dev/null +++ b/vendor/golang.org/x/exp/slices/zsortordered.go @@ -0,0 +1,481 @@ +// Code generated by gen_sort_variants.go; DO NOT EDIT. + +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package slices + +import "golang.org/x/exp/constraints" + +// insertionSortOrdered sorts data[a:b] using insertion sort. +func insertionSortOrdered[E constraints.Ordered](data []E, a, b int) { + for i := a + 1; i < b; i++ { + for j := i; j > a && cmpLess(data[j], data[j-1]); j-- { + data[j], data[j-1] = data[j-1], data[j] + } + } +} + +// siftDownOrdered implements the heap property on data[lo:hi]. +// first is an offset into the array where the root of the heap lies. +func siftDownOrdered[E constraints.Ordered](data []E, lo, hi, first int) { + root := lo + for { + child := 2*root + 1 + if child >= hi { + break + } + if child+1 < hi && cmpLess(data[first+child], data[first+child+1]) { + child++ + } + if !cmpLess(data[first+root], data[first+child]) { + return + } + data[first+root], data[first+child] = data[first+child], data[first+root] + root = child + } +} + +func heapSortOrdered[E constraints.Ordered](data []E, a, b int) { + first := a + lo := 0 + hi := b - a + + // Build heap with greatest element at top. + for i := (hi - 1) / 2; i >= 0; i-- { + siftDownOrdered(data, i, hi, first) + } + + // Pop elements, largest first, into end of data. + for i := hi - 1; i >= 0; i-- { + data[first], data[first+i] = data[first+i], data[first] + siftDownOrdered(data, lo, i, first) + } +} + +// pdqsortOrdered sorts data[a:b]. +// The algorithm based on pattern-defeating quicksort(pdqsort), but without the optimizations from BlockQuicksort. +// pdqsort paper: https://arxiv.org/pdf/2106.05123.pdf +// C++ implementation: https://github.com/orlp/pdqsort +// Rust implementation: https://docs.rs/pdqsort/latest/pdqsort/ +// limit is the number of allowed bad (very unbalanced) pivots before falling back to heapsort. +func pdqsortOrdered[E constraints.Ordered](data []E, a, b, limit int) { + const maxInsertion = 12 + + var ( + wasBalanced = true // whether the last partitioning was reasonably balanced + wasPartitioned = true // whether the slice was already partitioned + ) + + for { + length := b - a + + if length <= maxInsertion { + insertionSortOrdered(data, a, b) + return + } + + // Fall back to heapsort if too many bad choices were made. + if limit == 0 { + heapSortOrdered(data, a, b) + return + } + + // If the last partitioning was imbalanced, we need to breaking patterns. + if !wasBalanced { + breakPatternsOrdered(data, a, b) + limit-- + } + + pivot, hint := choosePivotOrdered(data, a, b) + if hint == decreasingHint { + reverseRangeOrdered(data, a, b) + // The chosen pivot was pivot-a elements after the start of the array. + // After reversing it is pivot-a elements before the end of the array. + // The idea came from Rust's implementation. + pivot = (b - 1) - (pivot - a) + hint = increasingHint + } + + // The slice is likely already sorted. + if wasBalanced && wasPartitioned && hint == increasingHint { + if partialInsertionSortOrdered(data, a, b) { + return + } + } + + // Probably the slice contains many duplicate elements, partition the slice into + // elements equal to and elements greater than the pivot. + if a > 0 && !cmpLess(data[a-1], data[pivot]) { + mid := partitionEqualOrdered(data, a, b, pivot) + a = mid + continue + } + + mid, alreadyPartitioned := partitionOrdered(data, a, b, pivot) + wasPartitioned = alreadyPartitioned + + leftLen, rightLen := mid-a, b-mid + balanceThreshold := length / 8 + if leftLen < rightLen { + wasBalanced = leftLen >= balanceThreshold + pdqsortOrdered(data, a, mid, limit) + a = mid + 1 + } else { + wasBalanced = rightLen >= balanceThreshold + pdqsortOrdered(data, mid+1, b, limit) + b = mid + } + } +} + +// partitionOrdered does one quicksort partition. +// Let p = data[pivot] +// Moves elements in data[a:b] around, so that data[i]

=p for inewpivot. +// On return, data[newpivot] = p +func partitionOrdered[E constraints.Ordered](data []E, a, b, pivot int) (newpivot int, alreadyPartitioned bool) { + data[a], data[pivot] = data[pivot], data[a] + i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned + + for i <= j && cmpLess(data[i], data[a]) { + i++ + } + for i <= j && !cmpLess(data[j], data[a]) { + j-- + } + if i > j { + data[j], data[a] = data[a], data[j] + return j, true + } + data[i], data[j] = data[j], data[i] + i++ + j-- + + for { + for i <= j && cmpLess(data[i], data[a]) { + i++ + } + for i <= j && !cmpLess(data[j], data[a]) { + j-- + } + if i > j { + break + } + data[i], data[j] = data[j], data[i] + i++ + j-- + } + data[j], data[a] = data[a], data[j] + return j, false +} + +// partitionEqualOrdered partitions data[a:b] into elements equal to data[pivot] followed by elements greater than data[pivot]. +// It assumed that data[a:b] does not contain elements smaller than the data[pivot]. +func partitionEqualOrdered[E constraints.Ordered](data []E, a, b, pivot int) (newpivot int) { + data[a], data[pivot] = data[pivot], data[a] + i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned + + for { + for i <= j && !cmpLess(data[a], data[i]) { + i++ + } + for i <= j && cmpLess(data[a], data[j]) { + j-- + } + if i > j { + break + } + data[i], data[j] = data[j], data[i] + i++ + j-- + } + return i +} + +// partialInsertionSortOrdered partially sorts a slice, returns true if the slice is sorted at the end. +func partialInsertionSortOrdered[E constraints.Ordered](data []E, a, b int) bool { + const ( + maxSteps = 5 // maximum number of adjacent out-of-order pairs that will get shifted + shortestShifting = 50 // don't shift any elements on short arrays + ) + i := a + 1 + for j := 0; j < maxSteps; j++ { + for i < b && !cmpLess(data[i], data[i-1]) { + i++ + } + + if i == b { + return true + } + + if b-a < shortestShifting { + return false + } + + data[i], data[i-1] = data[i-1], data[i] + + // Shift the smaller one to the left. + if i-a >= 2 { + for j := i - 1; j >= 1; j-- { + if !cmpLess(data[j], data[j-1]) { + break + } + data[j], data[j-1] = data[j-1], data[j] + } + } + // Shift the greater one to the right. + if b-i >= 2 { + for j := i + 1; j < b; j++ { + if !cmpLess(data[j], data[j-1]) { + break + } + data[j], data[j-1] = data[j-1], data[j] + } + } + } + return false +} + +// breakPatternsOrdered scatters some elements around in an attempt to break some patterns +// that might cause imbalanced partitions in quicksort. +func breakPatternsOrdered[E constraints.Ordered](data []E, a, b int) { + length := b - a + if length >= 8 { + random := xorshift(length) + modulus := nextPowerOfTwo(length) + + for idx := a + (length/4)*2 - 1; idx <= a+(length/4)*2+1; idx++ { + other := int(uint(random.Next()) & (modulus - 1)) + if other >= length { + other -= length + } + data[idx], data[a+other] = data[a+other], data[idx] + } + } +} + +// choosePivotOrdered chooses a pivot in data[a:b]. +// +// [0,8): chooses a static pivot. +// [8,shortestNinther): uses the simple median-of-three method. +// [shortestNinther,∞): uses the Tukey ninther method. +func choosePivotOrdered[E constraints.Ordered](data []E, a, b int) (pivot int, hint sortedHint) { + const ( + shortestNinther = 50 + maxSwaps = 4 * 3 + ) + + l := b - a + + var ( + swaps int + i = a + l/4*1 + j = a + l/4*2 + k = a + l/4*3 + ) + + if l >= 8 { + if l >= shortestNinther { + // Tukey ninther method, the idea came from Rust's implementation. + i = medianAdjacentOrdered(data, i, &swaps) + j = medianAdjacentOrdered(data, j, &swaps) + k = medianAdjacentOrdered(data, k, &swaps) + } + // Find the median among i, j, k and stores it into j. + j = medianOrdered(data, i, j, k, &swaps) + } + + switch swaps { + case 0: + return j, increasingHint + case maxSwaps: + return j, decreasingHint + default: + return j, unknownHint + } +} + +// order2Ordered returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a. +func order2Ordered[E constraints.Ordered](data []E, a, b int, swaps *int) (int, int) { + if cmpLess(data[b], data[a]) { + *swaps++ + return b, a + } + return a, b +} + +// medianOrdered returns x where data[x] is the median of data[a],data[b],data[c], where x is a, b, or c. +func medianOrdered[E constraints.Ordered](data []E, a, b, c int, swaps *int) int { + a, b = order2Ordered(data, a, b, swaps) + b, c = order2Ordered(data, b, c, swaps) + a, b = order2Ordered(data, a, b, swaps) + return b +} + +// medianAdjacentOrdered finds the median of data[a - 1], data[a], data[a + 1] and stores the index into a. +func medianAdjacentOrdered[E constraints.Ordered](data []E, a int, swaps *int) int { + return medianOrdered(data, a-1, a, a+1, swaps) +} + +func reverseRangeOrdered[E constraints.Ordered](data []E, a, b int) { + i := a + j := b - 1 + for i < j { + data[i], data[j] = data[j], data[i] + i++ + j-- + } +} + +func swapRangeOrdered[E constraints.Ordered](data []E, a, b, n int) { + for i := 0; i < n; i++ { + data[a+i], data[b+i] = data[b+i], data[a+i] + } +} + +func stableOrdered[E constraints.Ordered](data []E, n int) { + blockSize := 20 // must be > 0 + a, b := 0, blockSize + for b <= n { + insertionSortOrdered(data, a, b) + a = b + b += blockSize + } + insertionSortOrdered(data, a, n) + + for blockSize < n { + a, b = 0, 2*blockSize + for b <= n { + symMergeOrdered(data, a, a+blockSize, b) + a = b + b += 2 * blockSize + } + if m := a + blockSize; m < n { + symMergeOrdered(data, a, m, n) + } + blockSize *= 2 + } +} + +// symMergeOrdered merges the two sorted subsequences data[a:m] and data[m:b] using +// the SymMerge algorithm from Pok-Son Kim and Arne Kutzner, "Stable Minimum +// Storage Merging by Symmetric Comparisons", in Susanne Albers and Tomasz +// Radzik, editors, Algorithms - ESA 2004, volume 3221 of Lecture Notes in +// Computer Science, pages 714-723. Springer, 2004. +// +// Let M = m-a and N = b-n. Wolog M < N. +// The recursion depth is bound by ceil(log(N+M)). +// The algorithm needs O(M*log(N/M + 1)) calls to data.Less. +// The algorithm needs O((M+N)*log(M)) calls to data.Swap. +// +// The paper gives O((M+N)*log(M)) as the number of assignments assuming a +// rotation algorithm which uses O(M+N+gcd(M+N)) assignments. The argumentation +// in the paper carries through for Swap operations, especially as the block +// swapping rotate uses only O(M+N) Swaps. +// +// symMerge assumes non-degenerate arguments: a < m && m < b. +// Having the caller check this condition eliminates many leaf recursion calls, +// which improves performance. +func symMergeOrdered[E constraints.Ordered](data []E, a, m, b int) { + // Avoid unnecessary recursions of symMerge + // by direct insertion of data[a] into data[m:b] + // if data[a:m] only contains one element. + if m-a == 1 { + // Use binary search to find the lowest index i + // such that data[i] >= data[a] for m <= i < b. + // Exit the search loop with i == b in case no such index exists. + i := m + j := b + for i < j { + h := int(uint(i+j) >> 1) + if cmpLess(data[h], data[a]) { + i = h + 1 + } else { + j = h + } + } + // Swap values until data[a] reaches the position before i. + for k := a; k < i-1; k++ { + data[k], data[k+1] = data[k+1], data[k] + } + return + } + + // Avoid unnecessary recursions of symMerge + // by direct insertion of data[m] into data[a:m] + // if data[m:b] only contains one element. + if b-m == 1 { + // Use binary search to find the lowest index i + // such that data[i] > data[m] for a <= i < m. + // Exit the search loop with i == m in case no such index exists. + i := a + j := m + for i < j { + h := int(uint(i+j) >> 1) + if !cmpLess(data[m], data[h]) { + i = h + 1 + } else { + j = h + } + } + // Swap values until data[m] reaches the position i. + for k := m; k > i; k-- { + data[k], data[k-1] = data[k-1], data[k] + } + return + } + + mid := int(uint(a+b) >> 1) + n := mid + m + var start, r int + if m > mid { + start = n - b + r = mid + } else { + start = a + r = m + } + p := n - 1 + + for start < r { + c := int(uint(start+r) >> 1) + if !cmpLess(data[p-c], data[c]) { + start = c + 1 + } else { + r = c + } + } + + end := n - start + if start < m && m < end { + rotateOrdered(data, start, m, end) + } + if a < start && start < mid { + symMergeOrdered(data, a, start, mid) + } + if mid < end && end < b { + symMergeOrdered(data, mid, end, b) + } +} + +// rotateOrdered rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data: +// Data of the form 'x u v y' is changed to 'x v u y'. +// rotate performs at most b-a many calls to data.Swap, +// and it assumes non-degenerate arguments: a < m && m < b. +func rotateOrdered[E constraints.Ordered](data []E, a, m, b int) { + i := m - a + j := b - m + + for i != j { + if i > j { + swapRangeOrdered(data, m-i, m, j) + i -= j + } else { + swapRangeOrdered(data, m-i, m+j-i, i) + j -= i + } + } + // i == j + swapRangeOrdered(data, m-i, m, i) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index a581ee3dd..162882f0e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -59,8 +59,8 @@ github.com/coreos/go-semver/semver # github.com/coreos/go-systemd/v22 v22.3.2 ## explicit; go 1.12 github.com/coreos/go-systemd/v22/journal -# github.com/fatih/color v1.13.0 -## explicit; go 1.13 +# github.com/fatih/color v1.14.1 +## explicit; go 1.17 github.com/fatih/color # github.com/fsnotify/fsnotify v1.7.0 ## explicit; go 1.17 @@ -84,7 +84,7 @@ github.com/golang/protobuf/ptypes/timestamp # github.com/gomodule/redigo v1.8.9 ## explicit; go 1.16 github.com/gomodule/redigo/redis -# github.com/hashicorp/consul/api v1.20.0 +# github.com/hashicorp/consul/api v1.26.1 ## explicit; go 1.19 github.com/hashicorp/consul/api # github.com/hashicorp/errwrap v1.1.0 @@ -93,7 +93,7 @@ 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.3.0 +# github.com/hashicorp/go-hclog v1.5.0 ## explicit; go 1.13 github.com/hashicorp/go-hclog # github.com/hashicorp/go-immutable-radix v1.3.1 @@ -117,8 +117,6 @@ github.com/hashicorp/go-secure-stdlib/strutil # github.com/hashicorp/go-sockaddr v1.0.2 ## explicit github.com/hashicorp/go-sockaddr -# github.com/hashicorp/go-uuid v1.0.3 -## explicit # github.com/hashicorp/go-version v1.6.0 ## explicit # github.com/hashicorp/golang-lru v0.5.4 @@ -150,7 +148,7 @@ github.com/kelseyhightower/memkv # github.com/mattn/go-colorable v0.1.13 ## explicit; go 1.15 github.com/mattn/go-colorable -# github.com/mattn/go-isatty v0.0.16 +# github.com/mattn/go-isatty v0.0.17 ## explicit; go 1.15 github.com/mattn/go-isatty # github.com/mitchellh/go-homedir v1.1.0 @@ -204,6 +202,10 @@ go.uber.org/zap/zapgrpc ## explicit; go 1.17 golang.org/x/crypto/ed25519 golang.org/x/crypto/pbkdf2 +# golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 +## explicit; go 1.20 +golang.org/x/exp/constraints +golang.org/x/exp/slices # golang.org/x/net v0.17.0 ## explicit; go 1.17 golang.org/x/net/http/httpguts