From 4c2045797169855c0afc0a9ee09e379a870ae3b4 Mon Sep 17 00:00:00 2001 From: Denis Mishin Date: Thu, 6 Mar 2025 19:19:35 -0500 Subject: [PATCH 1/2] add optional enum support, add route load balancing policy --- docs/data-sources/route.md | 1 + docs/data-sources/routes.md | 1 + docs/resources/route.md | 1 + example/main.tf | 6 +- go.mod | 28 +- go.sum | 270 +--------------- internal/provider/enum_optional.go | 83 +++++ internal/provider/enum_optional_test.go | 124 ++++++++ internal/provider/key_chain_model.go | 4 +- internal/provider/models.go | 4 +- internal/provider/policy_model.go | 2 +- internal/provider/route.go | 7 + internal/provider/route_data_source.go | 8 + internal/provider/route_model.go | 5 +- internal/provider/route_model_test.go | 213 +++++++++---- internal/provider/route_test.go | 406 ------------------------ internal/provider/settings_model.go | 2 +- 17 files changed, 397 insertions(+), 768 deletions(-) create mode 100644 internal/provider/enum_optional.go create mode 100644 internal/provider/enum_optional_test.go delete mode 100644 internal/provider/route_test.go diff --git a/docs/data-sources/route.md b/docs/data-sources/route.md index 67c59ca..4f56d31 100644 --- a/docs/data-sources/route.md +++ b/docs/data-sources/route.md @@ -23,6 +23,7 @@ Route data source - `jwt_groups_filter` (Attributes) JWT Groups Filter (see [below for nested schema](#nestedatt--jwt_groups_filter)) - `jwt_issuer_format` (String) Format for JWT issuer strings. Use 'IssuerHostOnly' for hostname without scheme or trailing slash, or 'IssuerURI' for complete URI including scheme and trailing slash. +- `load_balancing_policy` (String) Load balancing policy. ### Read-Only diff --git a/docs/data-sources/routes.md b/docs/data-sources/routes.md index 985482f..54feb1f 100644 --- a/docs/data-sources/routes.md +++ b/docs/data-sources/routes.md @@ -35,6 +35,7 @@ Optional: - `jwt_groups_filter` (Attributes) JWT Groups Filter (see [below for nested schema](#nestedatt--routes--jwt_groups_filter)) - `jwt_issuer_format` (String) Format for JWT issuer strings. Use 'IssuerHostOnly' for hostname without scheme or trailing slash, or 'IssuerURI' for complete URI including scheme and trailing slash. +- `load_balancing_policy` (String) Load balancing policy. Read-Only: diff --git a/docs/resources/route.md b/docs/resources/route.md index 8f0ba8f..50a5d86 100644 --- a/docs/resources/route.md +++ b/docs/resources/route.md @@ -41,6 +41,7 @@ Route for Pomerium. - `jwt_issuer_format` (String) Format for JWT issuer strings. Use 'IssuerHostOnly' for hostname without scheme or trailing slash, or 'IssuerURI' for complete URI including scheme and trailing slash. - `kubernetes_service_account_token` (String) Kubernetes service account token. - `kubernetes_service_account_token_file` (String) Path to the Kubernetes service account token file. +- `load_balancing_policy` (String) Load balancing policy. - `logo_url` (String) URL to the logo image. - `pass_identity_headers` (Boolean) If applied, passes X-Pomerium-Jwt-Assertion header and JWT Claims Headers to the upstream application. - `path` (String) Matches incoming requests with a path that is an exact match for the specified path. diff --git a/example/main.tf b/example/main.tf index 418c03b..1778bb6 100644 --- a/example/main.tf +++ b/example/main.tf @@ -2,7 +2,7 @@ terraform { required_providers { pomerium = { source = "pomerium/pomerium" - version = "0.0.8" + version = "0.0.11" } } } @@ -51,7 +51,9 @@ resource "pomerium_settings" "settings" { log_level = "info" proxy_log_level = "info" - timeout_idle = "5m" + timeout_idle = "10m" + + darkmode_primary_color = "#49AAA1" jwt_groups_filter = { groups = ["id1", "id2"] diff --git a/go.mod b/go.mod index b0f81a2..4d0a400 100644 --- a/go.mod +++ b/go.mod @@ -11,65 +11,41 @@ require ( github.com/hashicorp/terraform-plugin-go v0.25.0 github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/iancoleman/strcase v0.3.0 - github.com/pomerium/enterprise-client-go v0.28.1-0.20250218224016-12d6ab8fdeb1 + github.com/pomerium/enterprise-client-go v0.28.1-0.20250306195545-d8048381f24f github.com/pomerium/pomerium v0.28.1-0.20250218200206-b9fd926618e2 github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.10.0 google.golang.org/grpc v1.70.0 - google.golang.org/protobuf v1.36.3 + google.golang.org/protobuf v1.36.4 ) require ( github.com/OneOfOne/xxhash v1.2.8 // indirect - github.com/caddyserver/certmagic v0.21.4 // indirect - github.com/caddyserver/zerossl v0.1.3 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/envoyproxy/go-control-plane v0.13.1 // indirect github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect github.com/fatih/color v1.14.1 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.6.2 // indirect - github.com/hashicorp/go-set/v3 v3.0.0 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect - github.com/jxskiss/base62 v1.1.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.9 // indirect - github.com/libdns/libdns v0.2.2 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mholt/acmez/v2 v2.0.3 // indirect - github.com/miekg/dns v1.1.62 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/oklog/run v1.0.0 // indirect github.com/open-policy-agent/opa v1.0.0 // indirect - github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/pomerium/protoutil v0.0.0-20240813175624-47b7ac43ff46 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/zeebo/blake3 v0.2.4 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.32.0 // indirect - golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect - golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.34.0 // indirect - golang.org/x/sync v0.10.0 // indirect golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect - golang.org/x/tools v0.25.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/go.sum b/go.sum index 986eea4..bbea2c9 100644 --- a/go.sum +++ b/go.sum @@ -1,133 +1,39 @@ -cel.dev/expr v0.19.0 h1:lXuo+nDhpyJSpWxpPVi5cPUwzKb+dsdOiw6IreM5yt0= -cel.dev/expr v0.19.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= -contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg= -contrib.go.opencensus.io/exporter/prometheus v0.4.2/go.mod h1:dvEHbiKmgvbr5pjaF9fpw1KeYcjrnC1J8B+JKjsZyRQ= -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= -github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= -github.com/caddyserver/certmagic v0.21.4 h1:e7VobB8rffHv8ZZpSiZtEwnLDHUwLVYLWzWSa1FfKI0= -github.com/caddyserver/certmagic v0.21.4/go.mod h1:swUXjQ1T9ZtMv95qj7/InJvWLXURU85r+CfG0T+ZbDE= -github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= -github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= -github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys= -github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= -github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 h1:boJj011Hh+874zpIySeApCX4GeOjPl9qhRF3QuIZq+Q= -github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= -github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= -github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI= -github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA= -github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= -github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v27.4.1+incompatible h1:ZJvcY7gfwHn1JF48PfbyXg7Jyt9ZCWDW+GGXOIxEwp4= -github.com/docker/docker v27.4.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE= -github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw= github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= -github.com/exaring/otelpgx v0.8.0 h1:uqoDIW9qKkyz479z2cGrmJ8OJypydyEA+xwey4ukvNo= -github.com/exaring/otelpgx v0.8.0/go.mod h1:ANkRZDfgfmN6yJS1xKMkshbnsHO8at5sYwtVEYOX8hc= 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/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= -github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= -github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY= github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= -github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= -github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= -github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= -github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= -github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= -github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= -github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= -github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= -github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= -github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-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-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-plugin v1.6.2 h1:zdGAEd0V1lCaU0u+MxWQhtSDQmahpkwOun8U8EiRVog= github.com/hashicorp/go-plugin v1.6.2/go.mod h1:CkgLQ5CZqNmdL9U9JzM532t8ZiYQ35+pj3b1FD37R0Q= -github.com/hashicorp/go-set/v3 v3.0.0 h1:CaJBQvQCOWoftrBcDt7Nwgo0kdpmrKxar/x2o6pV9JA= -github.com/hashicorp/go-set/v3 v3.0.0/go.mod h1:IEghM2MpE5IaNvL+D7X480dfNtxjRXZ6VMpK3C8s2ok= 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/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= -github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/terraform-plugin-framework v1.13.0 h1:8OTG4+oZUfKgnfTdPTJwZ532Bh2BobF4H+yBiYJ/scw= github.com/hashicorp/terraform-plugin-framework v1.13.0/go.mod h1:j64rwMGpgM3NYXTKuxrCnyubQb/4VKldEKlcG8cvmjU= github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0 h1:v3DapR8gsp3EM8fKMh6up9cJUFQ2iRaFsYLP8UJnCco= @@ -146,32 +52,12 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= -github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI= -github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ= -github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= -github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= -github.com/jxskiss/base62 v1.1.0 h1:A5zbF8v8WXx2xixnAKD2w+abC+sIzYJX+nxmhA6HWFw= -github.com/jxskiss/base62 v1.1.0/go.mod h1:HhWAlUXvxKThfOlZbcuFzsqwtF5TcqS9ru3y5GfjWAc= -github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= -github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= -github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= -github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= -github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= -github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae h1:dIZY4ULFcto4tAFlj1FYZl8ztUZ13bdq+PLY+NOfbyI= -github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -182,164 +68,45 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mholt/acmez/v2 v2.0.3 h1:CgDBlEwg3QBp6s45tPQmFIBrkRIkBT4rW4orMM6p4sw= -github.com/mholt/acmez/v2 v2.0.3/go.mod h1:pQ1ysaDeGrIMvJ9dfJMk5kJNkn7L2sb3UhyrX6Q91cw= -github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= -github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= -github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= -github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.82 h1:tWfICLhmp2aFPXL8Tli0XDTHj2VB/fNf0PC1f/i1gRo= -github.com/minio/minio-go/v7 v7.0.82/go.mod h1:84gmIilaX4zcvAWWzJ5Z1WI5axN+hAbM5w25xf8xvC0= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= -github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= -github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= -github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c h1:cqn374mizHuIWj+OSJCajGr/phAmuMug9qIX3l9CflE= -github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= -github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= -github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= -github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= -github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= -github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= -github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= -github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= -github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/open-policy-agent/opa v1.0.0 h1:fZsEwxg1knpPvUn0YDJuJZBcbVg4G3zKpWa3+CnYK+I= github.com/open-policy-agent/opa v1.0.0/go.mod h1:+JyoH12I0+zqyC1iX7a2tmoQlipwAEGvOhVJMhmy+rM= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= -github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pomerium/csrf v1.7.0 h1:Qp4t6oyEod3svQtKfJZs589mdUTWKVf7q0PgCKYCshY= -github.com/pomerium/csrf v1.7.0/go.mod h1:hAPZV47mEj2T9xFs+ysbum4l7SF1IdrryYaY6PdoIqw= -github.com/pomerium/enterprise-client-go v0.28.1-0.20250218224016-12d6ab8fdeb1 h1:+QSJt/ZEM7mcBrvF1YpcSH2cyyH4n7u64YhnsDeh6NY= -github.com/pomerium/enterprise-client-go v0.28.1-0.20250218224016-12d6ab8fdeb1/go.mod h1:3zekvlkIRcr67wJCcrU6p0MlKfI7XXrcFJIzvaUP0Qk= +github.com/pomerium/enterprise-client-go v0.28.1-0.20250306195545-d8048381f24f h1:yaLu3zRz02Y0lPrIVeoVtYhqzHBcuRGZsiaKNPgOhBQ= +github.com/pomerium/enterprise-client-go v0.28.1-0.20250306195545-d8048381f24f/go.mod h1:36+cCZpNgJQb5B1+y4rCcyQ8CM865NBNmEAQFS+73DQ= github.com/pomerium/pomerium v0.28.1-0.20250218200206-b9fd926618e2 h1:UtyGKmmFs/DVuvhOUeFowruCv+xObqAbqNmPqhMZ88o= github.com/pomerium/pomerium v0.28.1-0.20250218200206-b9fd926618e2/go.mod h1:8Uf1ya/wSjJyeUo5X4TqctlrYxbc5iPfFG18x1t0Deo= -github.com/pomerium/protoutil v0.0.0-20240813175624-47b7ac43ff46 h1:NRTg8JOXCxcIA1lAgD74iYud0rbshbWOB3Ou4+Huil8= -github.com/pomerium/protoutil v0.0.0-20240813175624-47b7ac43ff46/go.mod h1:QqZmx6ZgPxz18va7kqoT4t/0yJtP7YFIDiT/W2n2fZ4= -github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= -github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= -github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ= -github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= -github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= -github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= -github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= -github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= -github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk= -github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= -github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= -github.com/shoenig/test v1.11.0 h1:NoPa5GIoBwuqzIviCrnUJa+t5Xb4xi5Z+zODJnIDsEQ= -github.com/shoenig/test v1.11.0/go.mod h1:UxJ6u/x2v/TNs/LoLxBNJRV9DiwBBKYxXSyczsBHFoI= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= -github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= -github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= -github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/testcontainers/testcontainers-go v0.34.0 h1:5fbgF0vIN5u+nD3IWabQwRybuB4GY8G2HHgCkbMzMHo= -github.com/testcontainers/testcontainers-go v0.34.0/go.mod h1:6P/kMkQe8yqPHfPWNulFGdFHTD8HB2vLq/231xY2iPQ= -github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= -github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= -github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= -github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/volatiletech/null/v9 v9.0.0 h1:JCdlHEiSRVxOi7/MABiEfdsqmuj9oTV20Ao7VvZ0JkE= -github.com/volatiletech/null/v9 v9.0.0/go.mod h1:zRFghPVahaiIMRXiUJrc6gsoG83Cm3ZoAfSTw7VHGQc= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= -github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/zeebo/assert v1.3.1 h1:vukIABvugfNMZMQO1ABsyQDJDTVQbn+LWSMy1ol1h6A= -github.com/zeebo/assert v1.3.1/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= -github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= -github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= -github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= -github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= -github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.57.0 h1:qtFISDHKolvIxzSs0gIaiPUPR0Cucb0F2coHC7ZLdps= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.57.0/go.mod h1:Y+Pop1Q6hCOnETWTW4NROK/q1hv50hM7yDaUTjG8lp8= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= -go.opentelemetry.io/contrib/propagators/autoprop v0.57.0 h1:bNPJOdT5154XxzeFmrh8R+PXnV4t3TZEczy8gHEpcpg= -go.opentelemetry.io/contrib/propagators/autoprop v0.57.0/go.mod h1:Tb0j0mK+QatKdCxCKPN7CSzc7kx/q34/KaohJx/N96s= -go.opentelemetry.io/contrib/propagators/aws v1.32.0 h1:NELzr8bW7a7aHVZj5gaep1PfkvoSCGx+1qNGZx/uhhU= -go.opentelemetry.io/contrib/propagators/aws v1.32.0/go.mod h1:XKMrzHNka3eOA+nGEcNKYVL9s77TAhkwQEynYuaRFnQ= -go.opentelemetry.io/contrib/propagators/b3 v1.32.0 h1:MazJBz2Zf6HTN/nK/s3Ru1qme+VhWU5hm83QxEP+dvw= -go.opentelemetry.io/contrib/propagators/b3 v1.32.0/go.mod h1:B0s70QHYPrJwPOwD1o3V/R8vETNOG9N3qZf4LDYvA30= -go.opentelemetry.io/contrib/propagators/jaeger v1.32.0 h1:K/fOyTMD6GELKTIJBaJ9k3ppF2Njt8MeUGBOwfaWXXA= -go.opentelemetry.io/contrib/propagators/jaeger v1.32.0/go.mod h1:ISE6hda//MTWvtngG7p4et3OCngsrTVfl7c6DjN17f8= -go.opentelemetry.io/contrib/propagators/ot v1.32.0 h1:Poy02A4wOZubHyd2hpHPDgZW+rn6EIq0vCwTZJ6Lmu8= -go.opentelemetry.io/contrib/propagators/ot v1.32.0/go.mod h1:cbhaURV+VR3NIMarzDYZU1RDEkXG1fNd1WMP1XCcGkY= go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 h1:cMyu9O88joYEaI47CnQkxO1XZdpoTF9fEnW2duIddhw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0/go.mod h1:6Am3rn7P9TVVeXYG+wtcGE7IE1tsQ+bP3AuWcKt/gOI= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= @@ -348,27 +115,13 @@ go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiy go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= -go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg= -go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= -go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -376,13 +129,9 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= -golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -418,29 +167,18 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk= -google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q= -google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08= google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= -google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= -google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= +google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -namespacelabs.dev/go-filenotify v0.0.0-20220511192020-53ea11be7eaa h1:jj2kjs0Hvufj40wuhMAzoZUOwrwMDFg1gHZ49RiIv9w= -namespacelabs.dev/go-filenotify v0.0.0-20220511192020-53ea11be7eaa/go.mod h1:e8NJRaInXRRm1+KPA6EkGEzdLJAgEvVSIKiLzpP97nI= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/internal/provider/enum_optional.go b/internal/provider/enum_optional.go new file mode 100644 index 0000000..22532a8 --- /dev/null +++ b/internal/provider/enum_optional.go @@ -0,0 +1,83 @@ +package provider + +import ( + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "google.golang.org/protobuf/reflect/protoreflect" +) + +// GetValidOptionalEnumValues is for an enum that is optional and can be null +// returns a list of valid string enum values for a given protobuf enum type, excluding the zero value +// also it trims the prefix of the enum values and lowercases them to match the Terraform customary naming +func GetValidEnumValuesCanonical[T protoreflect.Enum](prefix string) []string { + var values []string + var v T + descriptor := v.Descriptor() + for i := 0; i < descriptor.Values().Len(); i++ { + val := descriptor.Values().Get(i) + if val.Number() == 0 { + continue + } + txt := string(val.Name()) + if !strings.HasPrefix(txt, prefix+"_") { + panic(fmt.Sprintf("enum value %q does not start with prefix %q", txt, prefix)) + } + values = append(values, strings.ToLower(strings.TrimPrefix(txt, prefix+"_"))) + } + return values +} + +// EnumValueToPBWithDefault converts a string to a protobuf enum value. +func OptionalEnumValueToPB[T interface { + ~int32 + protoreflect.Enum +}]( + dst **T, + src types.String, + prefix string, + diagnostics *diag.Diagnostics, +) { + if src.IsNull() { + *dst = nil + return + } + + key := strings.ToUpper(prefix + "_" + src.ValueString()) + var v T + enumValue := v.Descriptor().Values().ByName(protoreflect.Name(key)) + if enumValue == nil { + diagnostics.AddError( + "InvalidEnumValue", + fmt.Sprintf("The provided %s enum value %q, representing %q is not valid.", v.Descriptor().FullName(), src.ValueString(), key), + ) + return + } + + v = T(enumValue.Number()) + *dst = &v +} + +func OptionalEnumValueFromPB[T interface { + ~int32 + protoreflect.Enum +}]( + src *T, + prefix string, +) types.String { + if src == nil { + return types.StringNull() + } + v := (*src).Descriptor().Values().ByNumber(protoreflect.EnumNumber(*src)) + if v == nil { + return types.StringNull() + } + + full := string(v.Name()) + if !strings.HasPrefix(full, prefix+"_") { + panic(fmt.Sprintf("enum value %q does not start with prefix %q", full, prefix)) + } + return types.StringValue(strings.ToLower(strings.TrimPrefix(full, prefix+"_"))) +} diff --git a/internal/provider/enum_optional_test.go b/internal/provider/enum_optional_test.go new file mode 100644 index 0000000..b6a1e69 --- /dev/null +++ b/internal/provider/enum_optional_test.go @@ -0,0 +1,124 @@ +package provider_test + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/pomerium/enterprise-client-go/pb" + "github.com/pomerium/enterprise-terraform-provider/internal/provider" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGetValidEnumValuesCanonical(t *testing.T) { + t.Parallel() + + values := provider.GetValidEnumValuesCanonical[pb.LoadBalancingPolicy]("LOAD_BALANCING_POLICY") + assert.Empty(t, cmp.Diff( + []string{"maglev", "random", "ring_hash", "round_robin", "least_request"}, + values, + cmpopts.SortSlices(func(a, b string) bool { return a < b }), + )) +} + +func TestOptionalEnumValueToPB(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + input types.String + prefix string + expectNil bool + expectValue pb.LoadBalancingPolicy + expectError bool + }{ + { + name: "valid value", + input: types.StringValue("round_robin"), + prefix: "LOAD_BALANCING_POLICY", + expectNil: false, + expectValue: pb.LoadBalancingPolicy_LOAD_BALANCING_POLICY_ROUND_ROBIN, + expectError: false, + }, + { + name: "another valid value", + input: types.StringValue("least_request"), + prefix: "LOAD_BALANCING_POLICY", + expectNil: false, + expectValue: pb.LoadBalancingPolicy_LOAD_BALANCING_POLICY_LEAST_REQUEST, + expectError: false, + }, + { + name: "null value", + input: types.StringNull(), + prefix: "LOAD_BALANCING_POLICY", + expectNil: true, + expectError: false, + }, + { + name: "invalid value", + input: types.StringValue("INVALID_VALUE"), + prefix: "LOAD_BALANCING_POLICY", + expectNil: false, + expectError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var got *pb.LoadBalancingPolicy + var diagnostics diag.Diagnostics + + provider.OptionalEnumValueToPB(&got, tt.input, tt.prefix, &diagnostics) + + if tt.expectError { + assert.True(t, diagnostics.HasError()) + } else { + require.False(t, diagnostics.HasError(), diagnostics.Errors()) + if tt.expectNil { + assert.Nil(t, got) + } else { + require.NotNil(t, got) + assert.Equal(t, tt.expectValue, *got) + } + } + }) + } +} + +func TestOptionalEnumValueFromPB(t *testing.T) { + t.Parallel() + + prefix := "LOAD_BALANCING_POLICY" + tests := []struct { + name string + input *pb.LoadBalancingPolicy + expectValue types.String + }{ + { + name: "valid value", + input: pb.LoadBalancingPolicy_LOAD_BALANCING_POLICY_ROUND_ROBIN.Enum(), + expectValue: types.StringValue("round_robin"), + }, + { + name: "another valid value", + input: pb.LoadBalancingPolicy_LOAD_BALANCING_POLICY_LEAST_REQUEST.Enum(), + expectValue: types.StringValue("least_request"), + }, + { + name: "nil value", + input: nil, + expectValue: types.StringNull(), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := provider.OptionalEnumValueFromPB(tt.input, prefix) + assert.Equal(t, tt.expectValue, got) + }) + } +} diff --git a/internal/provider/key_chain_model.go b/internal/provider/key_chain_model.go index 678160f..5d50c4d 100644 --- a/internal/provider/key_chain_model.go +++ b/internal/provider/key_chain_model.go @@ -16,7 +16,7 @@ type KeyPairModel struct { func ConvertKeyPairToCreatePB(src *KeyPairModel) *pb.CreateKeyPairRequest { dst := &pb.CreateKeyPairRequest{ - OriginatorId: originatorID, + OriginatorId: OriginatorID, NamespaceId: src.NamespaceID.ValueString(), Name: src.Name.ValueString(), Format: pb.Format_PEM, @@ -32,7 +32,7 @@ func ConvertKeyPairToCreatePB(src *KeyPairModel) *pb.CreateKeyPairRequest { func ConvertKeyPairToUpdatePB(src *KeyPairModel) *pb.UpdateKeyPairRequest { fmt := pb.Format_PEM dst := &pb.UpdateKeyPairRequest{ - OriginatorId: originatorID, + OriginatorId: OriginatorID, Id: src.ID.ValueString(), Name: src.Name.ValueStringPointer(), Format: &fmt, diff --git a/internal/provider/models.go b/internal/provider/models.go index 846edec..18ef7ab 100644 --- a/internal/provider/models.go +++ b/internal/provider/models.go @@ -11,7 +11,7 @@ import ( "github.com/pomerium/enterprise-client-go/pb" ) -const originatorID = "terraform" +const OriginatorID = "terraform" // ServiceAccountModel represents the shared model for service account resources and data sources type ServiceAccountModel struct { @@ -79,7 +79,7 @@ func ConvertNamespaceToPB(_ context.Context, src *NamespaceResourceModel) (*pb.N var diagnostics diag.Diagnostics pbNamespace := &pb.Namespace{ - OriginatorId: originatorID, + OriginatorId: OriginatorID, Id: src.ID.ValueString(), Name: src.Name.ValueString(), } diff --git a/internal/provider/policy_model.go b/internal/provider/policy_model.go index 124eccb..e5b657e 100644 --- a/internal/provider/policy_model.go +++ b/internal/provider/policy_model.go @@ -26,7 +26,7 @@ func ConvertPolicyToPB(ctx context.Context, src *PolicyResourceModel) (*pb.Polic var diagnostics diag.Diagnostics pbPolicy := &pb.Policy{ - OriginatorId: originatorID, + OriginatorId: OriginatorID, Id: src.ID.ValueString(), Name: src.Name.ValueString(), Description: src.Description.ValueString(), diff --git a/internal/provider/route.go b/internal/provider/route.go index d9bfcc5..e214c5c 100644 --- a/internal/provider/route.go +++ b/internal/provider/route.go @@ -210,6 +210,13 @@ func (r *RouteResource) Schema(_ context.Context, _ resource.SchemaRequest, resp stringvalidator.OneOf(GetValidEnumValues[pb.IssuerFormat]()...), }, }, + "load_balancing_policy": schema.StringAttribute{ + Description: "Load balancing policy.", + Optional: true, + Validators: []validator.String{ + stringvalidator.OneOf(GetValidEnumValuesCanonical[pb.LoadBalancingPolicy]("LOAD_BALANCING_POLICY")...), + }, + }, "rewrite_response_headers": schema.SetNestedAttribute{ Description: "Modifies response headers before they are returned to the client. 'Header' matches the HTTP header name; 'prefix' will be replaced with 'value'.", Optional: true, diff --git a/internal/provider/route_data_source.go b/internal/provider/route_data_source.go index 1f090fb..3c27d62 100644 --- a/internal/provider/route_data_source.go +++ b/internal/provider/route_data_source.go @@ -176,6 +176,14 @@ func getRouteDataSourceAttributes(idRequired bool) map[string]schema.Attribute { stringvalidator.OneOf(GetValidEnumValues[pb.IssuerFormat]()...), }, }, + "load_balancing_policy": schema.StringAttribute{ + Optional: true, + Computed: true, + Description: "Load balancing policy.", + Validators: []validator.String{ + stringvalidator.OneOf(GetValidEnumValuesCanonical[pb.LoadBalancingPolicy]("LOAD_BALANCING_POLICY")...), + }, + }, "rewrite_response_headers": schema.SetNestedAttribute{ Description: "Response header rewrite rules.", Computed: true, diff --git a/internal/provider/route_model.go b/internal/provider/route_model.go index 779bdd4..4eab368 100644 --- a/internal/provider/route_model.go +++ b/internal/provider/route_model.go @@ -33,6 +33,7 @@ type RouteModel struct { KubernetesServiceAccountToken types.String `tfsdk:"kubernetes_service_account_token"` KubernetesServiceAccountTokenFile types.String `tfsdk:"kubernetes_service_account_token_file"` LogoURL types.String `tfsdk:"logo_url"` + LoadBalancingPolicy types.String `tfsdk:"load_balancing_policy"` Name types.String `tfsdk:"name"` NamespaceID types.String `tfsdk:"namespace_id"` PassIdentityHeaders types.Bool `tfsdk:"pass_identity_headers"` @@ -181,7 +182,8 @@ func ConvertRouteToPB( pbRoute.RewriteResponseHeaders = rewriteHeadersToPB(src.RewriteResponseHeaders) pbRoute.BearerTokenFormat = ToBearerTokenFormat(src.BearerTokenFormat) ToRouteStringList(ctx, &pbRoute.IdpAccessTokenAllowedAudiences, src.IDPAccessTokenAllowedAudiences, &diagnostics) - pbRoute.OriginatorId = originatorID + pbRoute.OriginatorId = OriginatorID + OptionalEnumValueToPB(&pbRoute.LoadBalancingPolicy, src.LoadBalancingPolicy, "LOAD_BALANCING_POLICY", &diagnostics) return pbRoute, diagnostics } @@ -241,5 +243,6 @@ func ConvertRouteFromPB( dst.RewriteResponseHeaders = rewriteHeadersFromPB(src.RewriteResponseHeaders) dst.BearerTokenFormat = FromBearerTokenFormat(src.BearerTokenFormat) dst.IDPAccessTokenAllowedAudiences = FromStringList(src.IdpAccessTokenAllowedAudiences) + dst.LoadBalancingPolicy = OptionalEnumValueFromPB(src.LoadBalancingPolicy, "LOAD_BALANCING_POLICY") return diagnostics } diff --git a/internal/provider/route_model_test.go b/internal/provider/route_model_test.go index 7e26acb..8e9f3a6 100644 --- a/internal/provider/route_model_test.go +++ b/internal/provider/route_model_test.go @@ -3,84 +3,175 @@ package provider_test import ( "context" "testing" + "time" + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/testing/protocmp" + "google.golang.org/protobuf/types/known/durationpb" "github.com/pomerium/enterprise-client-go/pb" "github.com/pomerium/enterprise-terraform-provider/internal/provider" ) -func TestConvertRouteFromPB(t *testing.T) { - t.Run("jwt_issuer_format", func(t *testing.T) { - testCases := []struct { - name string - input pb.IssuerFormat - expected string - isNull bool - }{ +func TestConvertRoute(t *testing.T) { + t.Parallel() + + pbRoute := &pb.Route{ + Id: "route-123", + Name: "test-route", + From: "https://from.example.com", + To: []string{"https://to1.example.com", "https://to2.example.com"}, + NamespaceId: "namespace-123", + PolicyIds: []string{"policy-1", "policy-2"}, + StatName: "test-stat", + Prefix: ptr("/prefix"), + Path: ptr("/path"), + Regex: ptr("^/regex.*$"), + PrefixRewrite: ptr("/prefix-rewrite"), + RegexRewritePattern: ptr("^/old(.*)$"), + RegexRewriteSubstitution: ptr("/new$1"), + HostRewrite: ptr("rewritten-host"), + HostRewriteHeader: ptr("X-Host-Header"), + HostPathRegexRewritePattern: ptr("^/path-pattern(.*)$"), + HostPathRegexRewriteSubstitution: ptr("host-sub$1"), + RegexPriorityOrder: ptr(int64(10)), + Timeout: durationpb.New(30 * time.Second), + IdleTimeout: durationpb.New(5 * time.Minute), + AllowWebsockets: ptr(true), + AllowSpdy: ptr(true), + TlsSkipVerify: ptr(false), + TlsUpstreamServerName: ptr("upstream.example.com"), + TlsDownstreamServerName: ptr("downstream.example.com"), + TlsUpstreamAllowRenegotiation: ptr(true), + SetRequestHeaders: map[string]string{"X-Request-1": "value1", "X-Request-2": "value2"}, + RemoveRequestHeaders: []string{"X-Remove-1", "X-Remove-2"}, + SetResponseHeaders: map[string]string{"X-Response-1": "value1", "X-Response-2": "value2"}, + PreserveHostHeader: ptr(true), + PassIdentityHeaders: ptr(true), + KubernetesServiceAccountToken: ptr("k8s-token"), + IdpClientId: ptr("idp-client-id"), + IdpClientSecret: ptr("idp-client-secret"), + ShowErrorDetails: true, + TlsClientKeyPairId: ptr("client-key-pair-123"), + TlsCustomCaKeyPairId: ptr("ca-key-pair-123"), + Description: ptr("Route description"), + LogoUrl: ptr("https://logo.example.com/logo.png"), + EnableGoogleCloudServerlessAuthentication: true, + KubernetesServiceAccountTokenFile: ptr("/path/to/token"), + JwtIssuerFormat: pb.IssuerFormat_IssuerURI, + BearerTokenFormat: pb.BearerTokenFormat_BEARER_TOKEN_FORMAT_IDP_ACCESS_TOKEN.Enum(), + IdpAccessTokenAllowedAudiences: &pb.Route_StringList{Values: []string{"aud1", "aud2"}}, + LoadBalancingPolicy: pb.LoadBalancingPolicy_LOAD_BALANCING_POLICY_ROUND_ROBIN.Enum(), + RewriteResponseHeaders: []*pb.RouteRewriteHeader{ { - name: "host_only", - input: pb.IssuerFormat_IssuerHostOnly, - expected: "IssuerHostOnly", + Header: "X-Rewrite-Header", + Value: "new-value", + Matcher: &pb.RouteRewriteHeader_Prefix{Prefix: "old-prefix"}, }, - { - name: "uri", - input: pb.IssuerFormat_IssuerURI, - expected: "IssuerURI", + }, + JwtGroupsFilter: &pb.JwtGroupsFilter{ + Groups: []string{"group1", "group2"}, + InferFromPpl: ptr(true), + }, + OriginatorId: provider.OriginatorID, + } + + tfRoute := provider.RouteModel{ + ID: types.StringValue("route-123"), + Name: types.StringValue("test-route"), + From: types.StringValue("https://from.example.com"), + To: types.SetValueMust(types.StringType, []attr.Value{types.StringValue("https://to1.example.com"), types.StringValue("https://to2.example.com")}), + NamespaceID: types.StringValue("namespace-123"), + Policies: types.SetValueMust(types.StringType, []attr.Value{types.StringValue("policy-1"), types.StringValue("policy-2")}), + StatName: types.StringValue("test-stat"), + Prefix: types.StringValue("/prefix"), + Path: types.StringValue("/path"), + Regex: types.StringValue("^/regex.*$"), + PrefixRewrite: types.StringValue("/prefix-rewrite"), + RegexRewritePattern: types.StringValue("^/old(.*)$"), + RegexRewriteSubstitution: types.StringValue("/new$1"), + HostRewrite: types.StringValue("rewritten-host"), + HostRewriteHeader: types.StringValue("X-Host-Header"), + HostPathRegexRewritePattern: types.StringValue("^/path-pattern(.*)$"), + HostPathRegexRewriteSubstitution: types.StringValue("host-sub$1"), + RegexPriorityOrder: types.Int64Value(10), + Timeout: timetypes.NewGoDurationValue(30 * time.Second), + IdleTimeout: timetypes.NewGoDurationValue(5 * time.Minute), + AllowWebsockets: types.BoolValue(true), + AllowSPDY: types.BoolValue(true), + TLSSkipVerify: types.BoolValue(false), + TLSUpstreamServerName: types.StringValue("upstream.example.com"), + TLSDownstreamServerName: types.StringValue("downstream.example.com"), + TLSUpstreamAllowRenegotiation: types.BoolValue(true), + SetRequestHeaders: types.MapValueMust(types.StringType, map[string]attr.Value{ + "X-Request-1": types.StringValue("value1"), + "X-Request-2": types.StringValue("value2"), + }), + RemoveRequestHeaders: types.SetValueMust(types.StringType, []attr.Value{types.StringValue("X-Remove-1"), types.StringValue("X-Remove-2")}), + SetResponseHeaders: types.MapValueMust(types.StringType, map[string]attr.Value{ + "X-Response-1": types.StringValue("value1"), + "X-Response-2": types.StringValue("value2"), + }), + PreserveHostHeader: types.BoolValue(true), + PassIdentityHeaders: types.BoolValue(true), + KubernetesServiceAccountToken: types.StringValue("k8s-token"), + IDPClientID: types.StringValue("idp-client-id"), + IDPClientSecret: types.StringValue("idp-client-secret"), + ShowErrorDetails: types.BoolValue(true), + TLSClientKeyPairID: types.StringValue("client-key-pair-123"), + TLSCustomCAKeyPairID: types.StringValue("ca-key-pair-123"), + Description: types.StringValue("Route description"), + LogoURL: types.StringValue("https://logo.example.com/logo.png"), + EnableGoogleCloudServerlessAuthentication: types.BoolValue(true), + KubernetesServiceAccountTokenFile: types.StringValue("/path/to/token"), + JWTIssuerFormat: types.StringValue("IssuerURI"), + BearerTokenFormat: types.StringValue("idp_access_token"), + IDPAccessTokenAllowedAudiences: types.SetValueMust(types.StringType, []attr.Value{types.StringValue("aud1"), types.StringValue("aud2")}), + LoadBalancingPolicy: types.StringValue("round_robin"), + JWTGroupsFilter: types.ObjectValueMust( + map[string]attr.Type{ + "infer_from_ppl": types.BoolType, + "groups": types.SetType{ElemType: types.StringType}, }, - { - name: "invalid value", - input: pb.IssuerFormat(999), - isNull: true, + map[string]attr.Value{ + "infer_from_ppl": types.BoolValue(true), + "groups": types.SetValueMust(types.StringType, []attr.Value{types.StringValue("group1"), types.StringValue("group2")}), }, - } + ), + RewriteResponseHeaders: types.SetValueMust( + provider.RewriteHeaderObjectType(), + []attr.Value{types.ObjectValueMust( + provider.RewriteHeaderAttrTypes(), + map[string]attr.Value{ + "header": types.StringValue("X-Rewrite-Header"), + "value": types.StringValue("new-value"), + "prefix": types.StringValue("old-prefix"), + }, + )}, + ), + } + + t.Run("pb to tf", func(t *testing.T) { + var got provider.RouteModel + diags := provider.ConvertRouteFromPB(&got, pbRoute) + require.False(t, diags.HasError(), "ConvertRouteFromPB returned diagnostics errors") - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - m := &provider.RouteModel{} - r := &pb.Route{ - JwtIssuerFormat: tc.input, - } - diags := provider.ConvertRouteFromPB(m, r) - require.False(t, diags.HasError()) - if tc.isNull { - assert.True(t, m.JWTIssuerFormat.IsNull()) - } else { - assert.Equal(t, tc.expected, m.JWTIssuerFormat.ValueString()) - } - }) + if diff := cmp.Diff(tfRoute, got); diff != "" { + t.Errorf("ConvertRouteFromPB() mismatch (-want +got):\n%s", diff) } }) -} + t.Run("tf to pb", func(t *testing.T) { + ctx := context.Background() -func TestConvertRouteToPB(t *testing.T) { - t.Run("jwt_issuer_format", func(t *testing.T) { - testCases := []struct { - name string - input string - expected pb.IssuerFormat - expectError bool - }{ - {"host_only", "IssuerHostOnly", pb.IssuerFormat_IssuerHostOnly, false}, - {"uri", "IssuerURI", pb.IssuerFormat_IssuerURI, false}, - {"invalid_value", "invalid_value", -1, true}, - } + got, diags := provider.ConvertRouteToPB(ctx, &tfRoute) + require.False(t, diags.HasError(), "ConvertRouteToPB returned diagnostics errors") - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - m := &provider.RouteModel{ - JWTIssuerFormat: types.StringValue(tc.input), - } - r, diag := provider.ConvertRouteToPB(context.Background(), m) - if tc.expectError { - require.True(t, diag.HasError()) - } else { - require.False(t, diag.HasError()) - assert.Equal(t, tc.expected, r.JwtIssuerFormat) - } - }) + if diff := cmp.Diff(pbRoute, got, protocmp.Transform()); diff != "" { + t.Errorf("ConvertRouteToPB() mismatch (-want +got):\n%s", diff) } }) } diff --git a/internal/provider/route_test.go b/internal/provider/route_test.go deleted file mode 100644 index cec393e..0000000 --- a/internal/provider/route_test.go +++ /dev/null @@ -1,406 +0,0 @@ -package provider_test - -import ( - "context" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/testing/protocmp" - - "github.com/pomerium/enterprise-client-go/pb" - "github.com/pomerium/enterprise-terraform-provider/internal/provider" -) - -func TestConvertRoute(t *testing.T) { - t.Parallel() - - t.Run("pb to model", func(t *testing.T) { - t.Parallel() - - input := &pb.Route{ - Id: "route-id", - Name: "route-name", - From: "from", - To: []string{"to1", "to2"}, - Prefix: P("/api"), - Path: P("/v1"), - PassIdentityHeaders: P(true), - SetRequestHeaders: map[string]string{ - "X-Custom": "value", - }, - RemoveRequestHeaders: []string{"Remove-Me"}, - NamespaceId: "namespace-1", - StatName: "stats-name", - PolicyIds: []string{"policy-1", "policy-2"}, - RewriteResponseHeaders: []*pb.RouteRewriteHeader{ - { - Header: "header-1", - Matcher: &pb.RouteRewriteHeader_Prefix{Prefix: "prefix-1"}, - Value: "value-1", - }, - }, - SetResponseHeaders: map[string]string{ - "X-Response": "value", - }, - ShowErrorDetails: true, - Description: P("route description"), - LogoUrl: P("https://example.com/logo.png"), - EnableGoogleCloudServerlessAuthentication: true, - TlsCustomCaKeyPairId: P("custom-ca-1"), - KubernetesServiceAccountTokenFile: P("/path/to/token"), - JwtIssuerFormat: pb.IssuerFormat_IssuerURI, - BearerTokenFormat: pb.BearerTokenFormat_BEARER_TOKEN_FORMAT_IDP_ACCESS_TOKEN.Enum(), - IdpAccessTokenAllowedAudiences: &pb.Route_StringList{Values: []string{"a", "b", "c"}}, - } - - var actual provider.RouteResourceModel - diag := provider.ConvertRouteFromPB(&actual, input) - require.False(t, diag.HasError(), diag.Errors()) - - expected := provider.RouteResourceModel{ - ID: types.StringValue("route-id"), - Name: types.StringValue("route-name"), - From: types.StringValue("from"), - Prefix: types.StringValue("/api"), - Path: types.StringValue("/v1"), - PassIdentityHeaders: types.BoolValue(true), - To: types.SetValueMust(types.StringType, []attr.Value{ - types.StringValue("to1"), - types.StringValue("to2"), - }), - SetRequestHeaders: types.MapValueMust( - types.StringType, - map[string]attr.Value{ - "X-Custom": types.StringValue("value"), - }, - ), - RemoveRequestHeaders: types.SetValueMust( - types.StringType, - []attr.Value{types.StringValue("Remove-Me")}, - ), - NamespaceID: types.StringValue("namespace-1"), - StatName: types.StringValue("stats-name"), - Policies: types.SetValueMust(types.StringType, []attr.Value{ - types.StringValue("policy-1"), - types.StringValue("policy-2"), - }), - RewriteResponseHeaders: types.SetValueMust( - provider.RewriteHeaderObjectType(), - []attr.Value{ - types.ObjectValueMust( - provider.RewriteHeaderAttrTypes(), - map[string]attr.Value{ - "header": types.StringValue("header-1"), - "prefix": types.StringValue("prefix-1"), - "value": types.StringValue("value-1"), - }, - ), - }, - ), - SetResponseHeaders: types.MapValueMust( - types.StringType, - map[string]attr.Value{ - "X-Response": types.StringValue("value"), - }, - ), - ShowErrorDetails: types.BoolValue(true), - Description: types.StringValue("route description"), - LogoURL: types.StringValue("https://example.com/logo.png"), - EnableGoogleCloudServerlessAuthentication: types.BoolValue(true), - TLSCustomCAKeyPairID: types.StringValue("custom-ca-1"), - KubernetesServiceAccountTokenFile: types.StringValue("/path/to/token"), - JWTIssuerFormat: types.StringValue("IssuerURI"), - BearerTokenFormat: types.StringValue("idp_access_token"), - IDPAccessTokenAllowedAudiences: types.SetValueMust(types.StringType, []attr.Value{ - types.StringValue("a"), types.StringValue("b"), types.StringValue("c"), - }), - } - - if diff := cmp.Diff(expected, actual); diff != "" { - t.Errorf("unexpected difference: %s", diff) - } - }) - - t.Run("model to pb", func(t *testing.T) { - t.Parallel() - - input := provider.RouteResourceModel{ - ID: types.StringValue("route-id"), - Name: types.StringValue("route-name"), - From: types.StringValue("from"), - To: types.SetValueMust(types.StringType, []attr.Value{ - types.StringValue("to1"), - types.StringValue("to2"), - }), - Prefix: types.StringValue("/api"), - Path: types.StringValue("/v1"), - PassIdentityHeaders: types.BoolValue(true), - SetRequestHeaders: types.MapValueMust( - types.StringType, - map[string]attr.Value{ - "X-Custom": types.StringValue("value"), - }, - ), - RemoveRequestHeaders: types.SetValueMust( - types.StringType, - []attr.Value{types.StringValue("Remove-Me")}, - ), - NamespaceID: types.StringValue("namespace-1"), - StatName: types.StringValue("stats-name"), - Policies: types.SetValueMust(types.StringType, []attr.Value{ - types.StringValue("policy-1"), - types.StringValue("policy-2"), - }), - SetResponseHeaders: types.MapValueMust( - types.StringType, - map[string]attr.Value{ - "X-Response": types.StringValue("value"), - }, - ), - ShowErrorDetails: types.BoolValue(true), - Description: types.StringValue("route description"), - LogoURL: types.StringValue("https://example.com/logo.png"), - EnableGoogleCloudServerlessAuthentication: types.BoolValue(true), - TLSCustomCAKeyPairID: types.StringValue("custom-ca-1"), - KubernetesServiceAccountTokenFile: types.StringValue("/path/to/token"), - BearerTokenFormat: types.StringValue("idp_access_token"), - IDPAccessTokenAllowedAudiences: types.SetValueMust(types.StringType, []attr.Value{ - types.StringValue("X"), types.StringValue("Y"), types.StringValue("Z"), - }), - } - - actual, diag := provider.ConvertRouteToPB(context.Background(), &input) - require.False(t, diag.HasError(), diag.Errors()) - - expected := &pb.Route{ - OriginatorId: "terraform", - Id: "route-id", - Name: "route-name", - From: "from", - To: []string{"to1", "to2"}, - Prefix: P("/api"), - Path: P("/v1"), - PassIdentityHeaders: P(true), - SetRequestHeaders: map[string]string{"X-Custom": "value"}, - RemoveRequestHeaders: []string{"Remove-Me"}, - NamespaceId: "namespace-1", - StatName: "stats-name", - PolicyIds: []string{"policy-1", "policy-2"}, - SetResponseHeaders: map[string]string{"X-Response": "value"}, - ShowErrorDetails: true, - Description: P("route description"), - LogoUrl: P("https://example.com/logo.png"), - EnableGoogleCloudServerlessAuthentication: true, - TlsCustomCaKeyPairId: P("custom-ca-1"), - KubernetesServiceAccountTokenFile: P("/path/to/token"), - BearerTokenFormat: pb.BearerTokenFormat_BEARER_TOKEN_FORMAT_IDP_ACCESS_TOKEN.Enum(), - IdpAccessTokenAllowedAudiences: &pb.Route_StringList{ - Values: []string{"X", "Y", "Z"}, - }, - } - - if diff := cmp.Diff(expected, actual, protocmp.Transform()); diff != "" { - t.Errorf("unexpected difference: %s", diff) - } - }) - - t.Run("pb to model with rewrite headers", func(t *testing.T) { - t.Parallel() - - input := &pb.Route{ - Id: "route-id", - Name: "route-name", - From: "from", - To: []string{"to1", "to2"}, - Prefix: P("/api"), - Path: P("/v1"), - PassIdentityHeaders: P(true), - SetRequestHeaders: map[string]string{ - "X-Custom": "value", - }, - RemoveRequestHeaders: []string{"Remove-Me"}, - NamespaceId: "namespace-1", - StatName: "stats-name", - PolicyIds: []string{"policy-1", "policy-2"}, - RewriteResponseHeaders: []*pb.RouteRewriteHeader{ - { - Header: "header-1", - Matcher: &pb.RouteRewriteHeader_Prefix{Prefix: "prefix-1"}, - Value: "value-1", - }, - { - Header: "header-2", - Value: "value-2", - }, - }, - SetResponseHeaders: map[string]string{ - "X-Response": "value", - }, - ShowErrorDetails: true, - Description: P("route description"), - LogoUrl: P("https://example.com/logo.png"), - EnableGoogleCloudServerlessAuthentication: true, - TlsCustomCaKeyPairId: P("custom-ca-1"), - KubernetesServiceAccountTokenFile: P("/path/to/token"), - } - - var actual provider.RouteResourceModel - diag := provider.ConvertRouteFromPB(&actual, input) - require.False(t, diag.HasError(), diag.Errors()) - - expected := provider.RouteResourceModel{ - ID: types.StringValue("route-id"), - Name: types.StringValue("route-name"), - From: types.StringValue("from"), - Prefix: types.StringValue("/api"), - Path: types.StringValue("/v1"), - PassIdentityHeaders: types.BoolValue(true), - To: types.SetValueMust(types.StringType, []attr.Value{ - types.StringValue("to1"), - types.StringValue("to2"), - }), - SetRequestHeaders: types.MapValueMust( - types.StringType, - map[string]attr.Value{ - "X-Custom": types.StringValue("value"), - }, - ), - RemoveRequestHeaders: types.SetValueMust( - types.StringType, - []attr.Value{types.StringValue("Remove-Me")}, - ), - NamespaceID: types.StringValue("namespace-1"), - StatName: types.StringValue("stats-name"), - Policies: types.SetValueMust(types.StringType, []attr.Value{ - types.StringValue("policy-1"), - types.StringValue("policy-2"), - }), - RewriteResponseHeaders: types.SetValueMust( - provider.RewriteHeaderObjectType(), - []attr.Value{ - types.ObjectValueMust( - provider.RewriteHeaderAttrTypes(), - map[string]attr.Value{ - "header": types.StringValue("header-1"), - "prefix": types.StringValue("prefix-1"), - "value": types.StringValue("value-1"), - }, - ), - types.ObjectValueMust( - provider.RewriteHeaderAttrTypes(), - map[string]attr.Value{ - "header": types.StringValue("header-2"), - "prefix": types.StringNull(), - "value": types.StringValue("value-2"), - }, - ), - }, - ), - SetResponseHeaders: types.MapValueMust( - types.StringType, - map[string]attr.Value{ - "X-Response": types.StringValue("value"), - }, - ), - ShowErrorDetails: types.BoolValue(true), - Description: types.StringValue("route description"), - LogoURL: types.StringValue("https://example.com/logo.png"), - EnableGoogleCloudServerlessAuthentication: types.BoolValue(true), - TLSCustomCAKeyPairID: types.StringValue("custom-ca-1"), - KubernetesServiceAccountTokenFile: types.StringValue("/path/to/token"), - } - - if diff := cmp.Diff(expected.RewriteResponseHeaders, actual.RewriteResponseHeaders); diff != "" { - t.Errorf("unexpected difference in RewriteResponseHeaders: %s", diff) - } - }) - - t.Run("model to pb with rewrite headers", func(t *testing.T) { - t.Parallel() - - input := provider.RouteResourceModel{ - ID: types.StringValue("route-id"), - Name: types.StringValue("route-name"), - From: types.StringValue("from"), - To: types.SetValueMust(types.StringType, []attr.Value{ - types.StringValue("to1"), - types.StringValue("to2"), - }), - Prefix: types.StringValue("/api"), - Path: types.StringValue("/v1"), - PassIdentityHeaders: types.BoolValue(true), - SetRequestHeaders: types.MapValueMust( - types.StringType, - map[string]attr.Value{ - "X-Custom": types.StringValue("value"), - }, - ), - RemoveRequestHeaders: types.SetValueMust( - types.StringType, - []attr.Value{types.StringValue("Remove-Me")}, - ), - NamespaceID: types.StringValue("namespace-1"), - StatName: types.StringValue("stats-name"), - Policies: types.SetValueMust(types.StringType, []attr.Value{ - types.StringValue("policy-1"), - types.StringValue("policy-2"), - }), - RewriteResponseHeaders: types.SetValueMust( - provider.RewriteHeaderObjectType(), - []attr.Value{ - types.ObjectValueMust( - provider.RewriteHeaderAttrTypes(), - map[string]attr.Value{ - "header": types.StringValue("header-1"), - "prefix": types.StringValue("prefix-1"), - "value": types.StringValue("value-1"), - }, - ), - types.ObjectValueMust( - provider.RewriteHeaderAttrTypes(), - map[string]attr.Value{ - "header": types.StringValue("header-2"), - "prefix": types.StringNull(), - "value": types.StringValue("value-2"), - }, - ), - }, - ), - SetResponseHeaders: types.MapValueMust( - types.StringType, - map[string]attr.Value{ - "X-Response": types.StringValue("value"), - }, - ), - ShowErrorDetails: types.BoolValue(true), - Description: types.StringValue("route description"), - LogoURL: types.StringValue("https://example.com/logo.png"), - EnableGoogleCloudServerlessAuthentication: types.BoolValue(true), - TLSCustomCAKeyPairID: types.StringValue("custom-ca-1"), - KubernetesServiceAccountTokenFile: types.StringValue("/path/to/token"), - } - - actual, diag := provider.ConvertRouteToPB(context.Background(), &input) - require.False(t, diag.HasError(), diag.Errors()) - - expectedHeaders := []*pb.RouteRewriteHeader{ - { - Header: "header-1", - Matcher: &pb.RouteRewriteHeader_Prefix{Prefix: "prefix-1"}, - Value: "value-1", - }, - { - Header: "header-2", - Value: "value-2", - // no prefix matcher for null case - }, - } - - if diff := cmp.Diff(expectedHeaders, actual.RewriteResponseHeaders, protocmp.Transform()); diff != "" { - t.Errorf("unexpected difference in RewriteResponseHeaders: %s", diff) - } - }) -} diff --git a/internal/provider/settings_model.go b/internal/provider/settings_model.go index c5a67d8..c3d818a 100644 --- a/internal/provider/settings_model.go +++ b/internal/provider/settings_model.go @@ -161,7 +161,7 @@ func ConvertSettingsToPB( pbSettings.LogLevel = src.LogLevel.ValueStringPointer() pbSettings.LogoUrl = src.LogoURL.ValueStringPointer() pbSettings.MetricsAddress = src.MetricsAddress.ValueStringPointer() - pbSettings.OriginatorId = originatorID + pbSettings.OriginatorId = OriginatorID pbSettings.PassIdentityHeaders = src.PassIdentityHeaders.ValueBoolPointer() pbSettings.PrimaryColor = src.PrimaryColor.ValueStringPointer() pbSettings.ProxyLogLevel = src.ProxyLogLevel.ValueStringPointer() From 85436fb553a00499c1e497dec68e400198b964e4 Mon Sep 17 00:00:00 2001 From: Denis Mishin Date: Thu, 6 Mar 2025 19:28:06 -0500 Subject: [PATCH 2/2] fix docs --- docs/resources/route.md | 8 +++++++- internal/provider/enum_optional.go | 15 +++++++++++++++ internal/provider/route.go | 5 +++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/docs/resources/route.md b/docs/resources/route.md index 50a5d86..3bb4365 100644 --- a/docs/resources/route.md +++ b/docs/resources/route.md @@ -41,7 +41,13 @@ Route for Pomerium. - `jwt_issuer_format` (String) Format for JWT issuer strings. Use 'IssuerHostOnly' for hostname without scheme or trailing slash, or 'IssuerURI' for complete URI including scheme and trailing slash. - `kubernetes_service_account_token` (String) Kubernetes service account token. - `kubernetes_service_account_token_file` (String) Path to the Kubernetes service account token file. -- `load_balancing_policy` (String) Load balancing policy. +- `load_balancing_policy` (String) The following values are valid for the Load Balancing Policy field: + +- `round_robin` +- `maglev` +- `random` +- `ring_hash` +- `least_request` - `logo_url` (String) URL to the logo image. - `pass_identity_headers` (Boolean) If applied, passes X-Pomerium-Jwt-Assertion header and JWT Claims Headers to the upstream application. - `path` (String) Matches incoming requests with a path that is an exact match for the specified path. diff --git a/internal/provider/enum_optional.go b/internal/provider/enum_optional.go index 22532a8..c78672a 100644 --- a/internal/provider/enum_optional.go +++ b/internal/provider/enum_optional.go @@ -30,6 +30,21 @@ func GetValidEnumValuesCanonical[T protoreflect.Enum](prefix string) []string { return values } +// GetValidEnumValuesCanonicalMarkdown returns a markdown string of valid enum values for a given protobuf enum type +func GetValidEnumValuesCanonicalMarkdown[T protoreflect.Enum](name, prefix string) string { + vals := GetValidEnumValuesCanonical[T](prefix) + var sb strings.Builder + sb.WriteString("The following values are valid for the ") + sb.WriteString(name) + sb.WriteString(" field:\n\n") + for _, v := range vals { + sb.WriteString("- `") + sb.WriteString(v) + sb.WriteString("`\n") + } + return sb.String() +} + // EnumValueToPBWithDefault converts a string to a protobuf enum value. func OptionalEnumValueToPB[T interface { ~int32 diff --git a/internal/provider/route.go b/internal/provider/route.go index e214c5c..ea1c67b 100644 --- a/internal/provider/route.go +++ b/internal/provider/route.go @@ -211,8 +211,9 @@ func (r *RouteResource) Schema(_ context.Context, _ resource.SchemaRequest, resp }, }, "load_balancing_policy": schema.StringAttribute{ - Description: "Load balancing policy.", - Optional: true, + Description: "Load balancing policy.", + MarkdownDescription: GetValidEnumValuesCanonicalMarkdown[pb.LoadBalancingPolicy]("Load Balancing Policy", "LOAD_BALANCING_POLICY"), + Optional: true, Validators: []validator.String{ stringvalidator.OneOf(GetValidEnumValuesCanonical[pb.LoadBalancingPolicy]("LOAD_BALANCING_POLICY")...), },